pip install pygame
import pygameimport random# 初始化pygame.init()# 颜色定义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 - 红色]# 游戏设置CELL_SIZE = 30GRID_WIDTH = 10GRID_HEIGHT = 20SCREEN_WIDTH = CELL_SIZE * (GRID_WIDTH + 6)SCREEN_HEIGHT = CELL_SIZE * GRID_HEIGHTGAME_AREA_LEFT = CELL_SIZE# 方块形状定义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]# 创建游戏窗口screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))pygame.display.set_caption("俄罗斯方块")clock = pygame.time.Clock()class Tetris:def __init__(self):self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]self.current_piece = self.new_piece()self.game_over = Falseself.paused = False # 暂停状态self.score = 0self.level = 1self.fall_speed = 0.5 # 秒self.fall_time = 0def new_piece(self):# 随机选择一个方块shape = random.choice(SHAPES)color = COLORS[SHAPES.index(shape)]# 初始位置 (顶部中间)x = GRID_WIDTH // 2 - len(shape[0]) // 2y = 0return {"shape": shape, "color": color, "x": x, "y": y}def valid_move(self, piece, x_offset=0, y_offset=0):for y, row in enumerate(piece["shape"]):for x, cell in enumerate(row):if cell:new_x = piece["x"] + x + x_offsetnew_y = piece["y"] + y + y_offsetif (new_x < 0 or new_x >= GRID_WIDTH ornew_y >= GRID_HEIGHT or(new_y >= 0 and self.grid[new_y][new_x])):return Falsereturn Truedef rotate_piece(self):# 转置矩阵然后反转每一行来实现旋转piece = self.current_piece.copy()shape = piece["shape"]rows = len(shape)cols = len(shape[0])# 旋转矩阵rotated = [[shape[rows-1-j][i] for j in range(rows)] for i in range(cols)]old_shape = piece["shape"]piece["shape"] = rotatedif not self.valid_move(piece):piece["shape"] = old_shapeself.current_piece = piecedef lock_piece(self):for y, row in enumerate(self.current_piece["shape"]):for x, cell in enumerate(row):if cell:self.grid[self.current_piece["y"] + y][self.current_piece["x"] + x] = self.current_piece["color"]# 检查是否有完整的行self.clear_lines()# 创建新方块self.current_piece = self.new_piece()# 检查游戏是否结束if not self.valid_move(self.current_piece):self.game_over = Truedef clear_lines(self):lines_cleared = 0for y in range(GRID_HEIGHT):if all(self.grid[y]):lines_cleared += 1# 移动上面的行下来for y2 in range(y, 0, -1):self.grid[y2] = self.grid[y2-1].copy()self.grid[0] = [0 for _ in range(GRID_WIDTH)]# 更新分数if lines_cleared == 1:self.score += 100 * self.levelelif lines_cleared == 2:self.score += 300 * self.levelelif lines_cleared == 3:self.score += 500 * self.levelelif lines_cleared == 4:self.score += 800 * self.level# 更新等级 (每清除10行升一级)self.level = 1 + self.score // 10000self.fall_speed = max(0.05, 0.5 - (self.level - 1) * 0.05)def update(self, delta_time):if self.game_over or self.paused:returnself.fall_time += delta_timeif self.fall_time >= self.fall_speed:self.fall_time = 0if self.valid_move(self.current_piece, 0, 1):self.current_piece["y"] += 1else:self.lock_piece()def draw(self):# 绘制游戏区域背景pygame.draw.rect(screen, GRAY, (GAME_AREA_LEFT, 0, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE))pygame.draw.rect(screen, BLACK, (GAME_AREA_LEFT, 0, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE), 2)# 绘制网格线for x in range(GRID_WIDTH + 1):pygame.draw.line(screen, GRAY,(GAME_AREA_LEFT + x * CELL_SIZE, 0),(GAME_AREA_LEFT + x * CELL_SIZE, GRID_HEIGHT * CELL_SIZE))for y in range(GRID_HEIGHT + 1):pygame.draw.line(screen, GRAY,(GAME_AREA_LEFT, y * CELL_SIZE),(GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE, y * CELL_SIZE))# 绘制已固定的方块for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):if self.grid[y][x]:pygame.draw.rect(screen, self.grid[y][x],(GAME_AREA_LEFT + x * CELL_SIZE + 1,y * CELL_SIZE + 1,CELL_SIZE - 2, CELL_SIZE - 2))# 绘制当前移动的方块if not self.game_over:for y, row in enumerate(self.current_piece["shape"]):for x, cell in enumerate(row):if cell:pygame.draw.rect(screen, self.current_piece["color"],(GAME_AREA_LEFT + (self.current_piece["x"] + x) * CELL_SIZE + 1,(self.current_piece["y"] + y) * CELL_SIZE + 1,CELL_SIZE - 2, CELL_SIZE - 2))# 绘制分数和等级font = pygame.font.SysFont(None, 36)score_text = font.render(f"分数: {self.score}", True, WHITE)level_text = font.render(f"等级: {self.level}", True, WHITE)screen.blit(score_text, (GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE + 20, 30))screen.blit(level_text, (GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE + 20, 70))# 绘制暂停提示if self.paused:font = pygame.font.SysFont(None, 48)pause_text = font.render("已暂停", True, WHITE)screen.blit(pause_text, (GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE // 2 - 60,GRID_HEIGHT * CELL_SIZE // 2 - 30))# 游戏结束提示if self.game_over:font = pygame.font.SysFont(None, 48)game_over_text = font.render("游戏结束!", True, (255, 0, 0))restart_text = font.render("按R键重新开始", True, WHITE)screen.blit(game_over_text, (GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE // 2 - 100,GRID_HEIGHT * CELL_SIZE // 2 - 60))screen.blit(restart_text, (GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE // 2 - 120,GRID_HEIGHT * CELL_SIZE // 2))# 创建游戏实例game = Tetris()# 游戏主循环running = Truewhile running:delta_time = clock.tick(60) / 1000.0 # 转换为秒# 处理事件for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_p: # 按P键暂停/继续if not game.game_over:game.paused = not game.pausedif event.key == pygame.K_r and game.game_over: # 按R键重新开始game = Tetris()if not game.game_over and not game.paused:if event.key == pygame.K_LEFT and game.valid_move(game.current_piece, -1, 0):game.current_piece["x"] -= 1elif event.key == pygame.K_RIGHT and game.valid_move(game.current_piece, 1, 0):game.current_piece["x"] += 1elif event.key == pygame.K_DOWN and game.valid_move(game.current_piece, 0, 1):game.current_piece["y"] += 1elif event.key == pygame.K_UP:game.rotate_piece()elif event.key == pygame.K_SPACE: # 硬降落while game.valid_move(game.current_piece, 0, 1):game.current_piece["y"] += 1game.lock_piece()# 更新游戏状态 - 只在未暂停且未结束时更新game.update(delta_time)# 绘制screen.fill(BLACK)game.draw()pygame.display.flip()pygame.quit()
游戏功能说明
1.基本游戏机制:
7种经典俄罗斯方块形状
方块自动下落
左右移动和旋转控制(左移方向键、右移方向键、向上方向键)
快速下落(空格键)
行消除和分数计算
随着分数增加难度提升
2.按钮功能
暂停功能:
按
P键可以暂停/继续游戏暂停时会显示"已暂停"提示
暂停时方块停止下落,不接受任何操作
重新开始功能:
游戏结束后按
R键可以重新开始游戏重新初始化所有游戏状态
游戏有三种状态:运行中、暂停、结束
每种状态下只接受特定的按键操作
3.操作说明
← → 键:左右移动方块
↑ 键:旋转方块
↓ 键:加速下落
空格键:直接落到底部
P 键:暂停/继续游戏
R 键:游戏结束后重新开始
4.计分系统:
消除1行: 100分 × 当前等级
消除2行: 300分 × 当前等级
消除3行: 500分 × 当前等级
消除4行: 800分 × 当前等级

