用PYTHON实现俄罗斯方块游戏案例

以下是基于 Python 和 Pygame 的俄罗斯方块游戏实现代码,包含基本功能如方块旋转、移动、消行和计分。

游戏初始化

复制代码
import pygame
import random

# 初始化
pygame.init()

# 屏幕设置
SCREEN_WIDTH = 300
SCREEN_HEIGHT = 600
BLOCK_SIZE = 30
GRID_WIDTH = SCREEN_WIDTH // BLOCK_SIZE
GRID_HEIGHT = SCREEN_HEIGHT // BLOCK_SIZE

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (128, 128, 128)
COLORS = [
    (0, 255, 255),  # I
    (0, 0, 255),    # J
    (255, 165, 0),  # L
    (255, 255, 0),  # O
    (0, 255, 0),    # S
    (128, 0, 128),  # T
    (255, 0, 0)     # Z
]

# 方块形状
SHAPES = [
    [[1, 1, 1, 1]],  # I
    [[1, 0, 0], [1, 1, 1]],  # J
    [[0, 0, 1], [1, 1, 1]],  # L
    [[1, 1], [1, 1]],  # O
    [[0, 1, 1], [1, 1, 0]],  # S
    [[0, 1, 0], [1, 1, 1]],  # T
    [[1, 1, 0], [0, 1, 1]]   # Z
]

游戏主类

复制代码
class Tetris:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption('俄罗斯方块')
        self.clock = pygame.time.Clock()
        self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
        self.current_piece = self.new_piece()
        self.game_over = False
        self.score = 0
        
    def new_piece(self):
        shape = random.choice(SHAPES)
        color = COLORS[SHAPES.index(shape)]
        return {
            'shape': shape,
            'color': color,
            'x': GRID_WIDTH // 2 - len(shape[0]) // 2,
            'y': 0
        }
    
    def valid_move(self, piece, x, y, rotation=None):
        shape = piece['shape']
        if rotation is not None:
            shape = self.rotate_shape(shape, rotation)
        for i, row in enumerate(shape):
            for j, cell in enumerate(row):
                if cell:
                    new_x = piece['x'] + j + x
                    new_y = piece['y'] + i + y
                    if (new_x < 0 or new_x >= GRID_WIDTH or 
                        new_y >= GRID_HEIGHT or 
                        (new_y >= 0 and self.grid[new_y][new_x])):
                        return False
        return True
    
    def rotate_shape(self, shape, rotation):
        if rotation == 'left':
            return [list(row) for row in zip(*shape)][::-1]
        elif rotation == 'right':
            return [list(row)[::-1] for row in zip(*shape)]
        return shape
    
    def lock_piece(self):
        for i, row in enumerate(self.current_piece['shape']):
            for j, cell in enumerate(row):
                if cell:
                    self.grid[self.current_piece['y'] + i][self.current_piece['x'] + j] = self.current_piece['color']
        self.clear_lines()
        self.current_piece = self.new_piece()
        if not self.valid_move(self.current_piece, 0, 0):
            self.game_over = True
    
    def clear_lines(self):
        lines_cleared = 0
        for i in range(GRID_HEIGHT):
            if all(self.grid[i]):
                lines_cleared += 1
                for j in range(i, 0, -1):
                    self.grid[j] = self.grid[j-1][:]
                self.grid[0] = [0] * GRID_WIDTH
        self.score += lines_cleared ** 2 * 100
    
    def draw(self):
        self.screen.fill(BLACK)
        
        # 绘制网格
        for i in range(GRID_HEIGHT):
            for j in range(GRID_WIDTH):
                if self.grid[i][j]:
                    pygame.draw.rect(self.screen, self.grid[i][j], 
                                    (j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
                    pygame.draw.rect(self.screen, WHITE, 
                                    (j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)
        
        # 绘制当前方块
        for i, row in enumerate(self.current_piece['shape']):
            for j, cell in enumerate(row):
                if cell:
                    pygame.draw.rect(self.screen, self.current_piece['color'], 
                                    ((self.current_piece['x'] + j) * BLOCK_SIZE, 
                                     (self.current_piece['y'] + i) * BLOCK_SIZE, 
                                     BLOCK_SIZE, BLOCK_SIZE))
                    pygame.draw.rect(self.screen, WHITE, 
                                    ((self.current_piece['x'] + j) * BLOCK_SIZE, 
                                     (self.current_piece['y'] + i) * BLOCK_SIZE, 
                                     BLOCK_SIZE, BLOCK_SIZE), 1)
        
        # 绘制分数
        font = pygame.font.SysFont(None, 30)
        score_text = font.render(f'Score: {self.score}', True, WHITE)
        self.screen.blit(score_text, (10, 10))
        
        pygame.display.update()
    
    def run(self):
        while not self.game_over:
            self.clock.tick(10)
            
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.game_over = True
                
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        if self.valid_move(self.current_piece, -1, 0):
                            self.current_piece['x'] -= 1
                    elif event.key == pygame.K_RIGHT:
                        if self.valid_move(self.current_piece, 1, 0):
                            self.current_piece['x'] += 1
                    elif event.key == pygame.K_DOWN:
                        if self.valid_move(self.current_piece, 0, 1):
                            self.current_piece['y'] += 1
                    elif event.key == pygame.K_UP:
                        if self.valid_move(self.current_piece, 0, 0, 'right'):
                            self.current_piece['shape'] = self.rotate_shape(self.current_piece['shape'], 'right')
                    elif event.key == pygame.K_z:
                        if self.valid_move(self.current_piece, 0, 0, 'left'):
                            self.current_piece['shape'] = self.rotate_shape(self.current_piece['shape'], 'left')
                    elif event.key == pygame.K_SPACE:
                        while self.valid_move(self.current_piece, 0, 1):
                            self.current_piece['y'] += 1
                        self.lock_piece()
            
            if self.valid_move(self.current_piece, 0, 1):
                self.current_piece['y'] += 1
            else:
                self.lock_piece()
            
            self.draw()
        
        pygame.quit()

启动游戏

复制代码
if __name__ == '__main__':
    game = Tetris()
    game.run()

操作说明

  • 左右箭头键:左右移动方块
  • 上箭头键:顺时针旋转方块
  • Z键:逆时针旋转方块
  • 下箭头键:加速下落
  • 空格键:直接落到底部

这个实现包含了俄罗斯方块的基本功能,可以根据需要进一步扩展功能如等级系统、预览下一个方块等。

相关推荐
许泽宇的技术分享3 小时前
当AI学会“说人话“:Azure语音合成技术的魔法世界
后端·python·flask
光泽雨3 小时前
python学习基础
开发语言·数据库·python
裤裤兔3 小时前
python爬取pdf文件并保存至本地
chrome·爬虫·python·pdf·网络爬虫
Solyn_HAN3 小时前
非编码 RNA(ceRNA/lncRNA/circRNA)分析完整流程:从数据下载到功能验证(含代码模板)
python·bash·生物信息学·r
CesareCheung3 小时前
JMeter 进行 WebSocket 接口压测
python·websocket·jmeter
beijingliushao4 小时前
95-Python爬虫-正则表达式
爬虫·python·正则表达式
百***06014 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
吃个糖糖4 小时前
pytorch 卷积操作
人工智能·pytorch·python
麦麦麦造4 小时前
比 pip 快 100 倍!更现代的 python 包管理工具,替代 pip、venv、poetry!
后端·python