[Python] 纯文本查看 复制代码
import pygame
import random
import sys
# 初始化 Pygame
pygame.init()
# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 700
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
SIDEBAR_WIDTH = 200
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 120, 255)
YELLOW = (255, 255, 0)
PURPLE = (180, 0, 255)
CYAN = (0, 255, 255)
ORANGE = (255, 165, 0)
GRAY = (40, 40, 40)
LIGHT_GRAY = (100, 100, 100)
DARK_GRAY = (30, 30, 30)
BACKGROUND = (15, 15, 30)
# 方块形状定义
SHAPES = [
[[1, 1, 1, 1]], # I
[[1, 1, 1], [0, 1, 0]], # T
[[1, 1, 1], [1, 0, 0]], # L
[[1, 1, 1], [0, 0, 1]], # J
[[1, 1], [1, 1]], # O
[[0, 1, 1], [1, 1, 0]], # S
[[1, 1, 0], [0, 1, 1]] # Z
]
# 方块颜色
SHAPE_COLORS = [CYAN, PURPLE, ORANGE, BLUE, YELLOW, GREEN, RED]
class Tetromino:
def __init__(self):
self.shape_idx = random.randint(0, len(SHAPES) - 1)
self.shape = SHAPES[self.shape_idx]
self.color = SHAPE_COLORS[self.shape_idx]
self.x = GRID_WIDTH // 2 - len(self.shape[0]) // 2
self.y = 0
def rotate(self):
# 旋转方块 (转置矩阵然后反转每一行)
rotated = [[self.shape[y][x] for y in range(len(self.shape)-1, -1, -1)]
for x in range(len(self.shape[0]))]
return rotated
def get_positions(self):
positions = []
for y, row in enumerate(self.shape):
for x, cell in enumerate(row):
if cell:
positions.append((self.x + x, self.y + y))
return positions
class TetrisGame:
def __init__(self):
self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")
self.clock = pygame.time.Clock()
self.font = pygame.font.SysFont(None, 36)
self.small_font = pygame.font.SysFont(None, 24)
self.reset_game()
def reset_game(self):
self.board = [[0 for _ in range(GRID_WIDTH)]
for _ in range(GRID_HEIGHT)]
self.current_piece = Tetromino()
self.next_piece = Tetromino()
self.game_over = False
self.score = 0
self.level = 1
self.lines_cleared = 0
self.fall_speed = 0.5 # 方块下落速度 (秒/格)
self.fall_timer = 0
self.paused = False
def draw_grid(self):
# 绘制游戏区域背景
grid_left = (SCREEN_WIDTH - SIDEBAR_WIDTH) // 2 - \
GRID_WIDTH * GRID_SIZE // 2
grid_top = SCREEN_HEIGHT // 2 - GRID_HEIGHT * GRID_SIZE // 2
pygame.draw.rect(self.screen, DARK_GRAY,
(grid_left - 2, grid_top - 2,
GRID_WIDTH * GRID_SIZE + 4,
GRID_HEIGHT * GRID_SIZE + 4))
# 绘制网格
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
pygame.draw.rect(self.screen, GRAY,
(grid_left + x * GRID_SIZE,
grid_top + y * GRID_SIZE,
GRID_SIZE, GRID_SIZE), 1)
# 绘制已固定的方块
if self.board[y][x]:
color_idx = self.board[y][x] - 1
pygame.draw.rect(self.screen, SHAPE_COLORS[color_idx],
(grid_left + x * GRID_SIZE + 1,
grid_top + y * GRID_SIZE + 1,
GRID_SIZE - 2, GRID_SIZE - 2))
# 绘制当前下落的方块
for x, y in self.current_piece.get_positions():
if y >= 0: # 只绘制在网格内的部分
pygame.draw.rect(self.screen, self.current_piece.color,
(grid_left + x * GRID_SIZE + 1,
grid_top + y * GRID_SIZE + 1,
GRID_SIZE - 2, GRID_SIZE - 2))
# 绘制网格边界
pygame.draw.rect(self.screen, WHITE,
(grid_left - 2, grid_top - 2,
GRID_WIDTH * GRID_SIZE + 4,
GRID_HEIGHT * GRID_SIZE + 4), 2)
def draw_sidebar(self):
sidebar_left = SCREEN_WIDTH - SIDEBAR_WIDTH
pygame.draw.rect(self.screen, DARK_GRAY,
(sidebar_left, 0, SIDEBAR_WIDTH, SCREEN_HEIGHT))
# 绘制分数
score_text = self.font.render(f"分数: {self.score}", True, WHITE)
self.screen.blit(score_text, (sidebar_left + 20, 50))
# 绘制等级
level_text = self.font.render(f"等级: {self.level}", True, WHITE)
self.screen.blit(level_text, (sidebar_left + 20, 100))
# 绘制消除行数
lines_text = self.font.render(f"行数: {self.lines_cleared}", True, WHITE)
self.screen.blit(lines_text, (sidebar_left + 20, 150))
# 绘制下一个方块预览
next_text = self.font.render("下一个:", True, WHITE)
self.screen.blit(next_text, (sidebar_left + 20, 220))
# 绘制下一个方块
preview_left = sidebar_left + 50
preview_top = 270
pygame.draw.rect(self.screen, GRAY,
(preview_left - 10, preview_top - 10,
120, 120), 2)
shape = self.next_piece.shape
color = self.next_piece.color
# 计算方块居中位置
start_x = preview_left + (4 - len(shape[0])) * GRID_SIZE // 2
start_y = preview_top + (4 - len(shape)) * GRID_SIZE // 2
for y, row in enumerate(shape):
for x, cell in enumerate(row):
if cell:
pygame.draw.rect(self.screen, color,
(start_x + x * GRID_SIZE,
start_y + y * GRID_SIZE,
GRID_SIZE - 2, GRID_SIZE - 2))
# 绘制控制说明
controls_y = 420
controls = [
"控制说明:",
"← → : 左右移动",
"↑ : 旋转",
"↓ : 加速下落",
"空格 : 直接落下",
"P : 暂停游戏",
"R : 重新开始"
]