以下是基于 Python + Pygame 实现的完整俄罗斯方块游戏代码,包含核心功能(方块生成、移动、旋转、消除、计分),注释详细可直接运行:
第一步:安装依赖
先安装 Pygame 库:
pip install pygame
第二步:完整代码
import pygame
import random
初始化Pygame
pygame.init()
游戏常量
SCREEN_WIDTH = 300 # 屏幕宽度
SCREEN_HEIGHT = 600 # 屏幕高度
BLOCK_SIZE = 30 # 方块大小(像素)
GRID_WIDTH = SCREEN_WIDTH // BLOCK_SIZE # 网格列数(10列)
GRID_HEIGHT = SCREEN_HEIGHT // BLOCK_SIZE # 网格行数(20行)
颜色定义(RGB)
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型)
]
俄罗斯方块7种形状(0=空,1=方块)
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()
FPS = 10
字体设置(计分板)
font = pygame.font.Font(None, 36)
class Tetromino:
"""方块类:管理单个下落的俄罗斯方块"""
def init(self):
self.shape = random.choice(SHAPES) # 随机选择形状
self.color = random.choice(COLORS) # 随机选择颜色
self.x = GRID_WIDTH // 2 - len(self.shape[0]) // 2 # 初始X位置(居中)
self.y = 0 # 初始Y位置(顶部)
def rotate(self):
"""旋转方块(矩阵转置+逆序)"""
转置矩阵
rotated = list(zip(*self.shape[::-1]))
转换为列表格式
self.shape = [list(row) for row in rotated]
def draw(self):
"""绘制方块到屏幕"""
for y, row in enumerate(self.shape):
for x, cell in enumerate(row):
if cell:
计算方块在屏幕上的实际坐标
screen_x = (self.x + x) * BLOCK_SIZE
screen_y = (self.y + y) * BLOCK_SIZE
绘制方块(带边框)
pygame.draw.rect(screen, self.color, (screen_x, screen_y, BLOCK_SIZE - 1, BLOCK_SIZE - 1))
http://my.tv.sohu.com/us/325502589/707536412.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjQxMi5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536349.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjM0OS5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536345.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjM0NS5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536409.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjQwOS5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536338.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjMzOC5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536220.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjIyMC5zaHRtbA==.html
http://my.tv.sohu.com/us/200323727/707536099.shtml
https://tv.sohu.com/v/dXMvMjAwMzIzNzI3LzcwNzUzNjA5OS5zaHRtbA==.html
http://my.tv.sohu.com/us/305726550/707536326.shtml
https://tv.sohu.com/v/dXMvMzA1NzI2NTUwLzcwNzUzNjMyNi5zaHRtbA==.html
http://my.tv.sohu.com/us/278601206/707536327.shtml
https://tv.sohu.com/v/dXMvMjc4NjAxMjA2LzcwNzUzNjMyNy5zaHRtbA==.html
http://my.tv.sohu.com/us/266746298/707536112.shtml
https://tv.sohu.com/v/dXMvMjY2NzQ2Mjk4LzcwNzUzNjExMi5zaHRtbA==.html
http://my.tv.sohu.com/us/297125191/707536111.shtml
https://tv.sohu.com/v/dXMvMjk3MTI1MTkxLzcwNzUzNjExMS5zaHRtbA==.html
http://my.tv.sohu.com/us/200323727/707536322.shtml
https://tv.sohu.com/v/dXMvMjAwMzIzNzI3LzcwNzUzNjMyMi5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536094.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjA5NC5zaHRtbA==.html
http://my.tv.sohu.com/us/305726550/707536213.shtml
https://tv.sohu.com/v/dXMvMzA1NzI2NTUwLzcwNzUzNjIxMy5zaHRtbA==.html
http://my.tv.sohu.com/us/278601206/707536317.shtml
https://tv.sohu.com/v/dXMvMjc4NjAxMjA2LzcwNzUzNjMxNy5zaHRtbA==.html
http://my.tv.sohu.com/us/297125191/707536092.shtml
https://tv.sohu.com/v/dXMvMjk3MTI1MTkxLzcwNzUzNjA5Mi5zaHRtbA==.html
http://my.tv.sohu.com/us/266746298/707536110.shtml
https://tv.sohu.com/v/dXMvMjY2NzQ2Mjk4LzcwNzUzNjExMC5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536090.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjA5MC5zaHRtbA==.html
http://my.tv.sohu.com/us/200323727/707536210.shtml
https://tv.sohu.com/v/dXMvMjAwMzIzNzI3LzcwNzUzNjIxMC5zaHRtbA==.html
http://my.tv.sohu.com/us/297125191/707536207.shtml
https://tv.sohu.com/v/dXMvMjk3MTI1MTkxLzcwNzUzNjIwNy5zaHRtbA==.html
http://my.tv.sohu.com/us/305726550/707536109.shtml
https://tv.sohu.com/v/dXMvMzA1NzI2NTUwLzcwNzUzNjEwOS5zaHRtbA==.html
http://my.tv.sohu.com/us/266746298/707536208.shtml
https://tv.sohu.com/v/dXMvMjY2NzQ2Mjk4LzcwNzUzNjIwOC5zaHRtbA==.html
http://my.tv.sohu.com/us/278601206/707536315.shtml
https://tv.sohu.com/v/dXMvMjc4NjAxMjA2LzcwNzUzNjMxNS5zaHRtbA==.html
http://my.tv.sohu.com/us/200323727/707536205.shtml
https://tv.sohu.com/v/dXMvMjAwMzIzNzI3LzcwNzUzNjIwNS5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536312.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjMxMi5zaHRtbA==.html
http://my.tv.sohu.com/us/305726550/707536311.shtml
https://tv.sohu.com/v/dXMvMzA1NzI2NTUwLzcwNzUzNjMxMS5zaHRtbA==.html
http://my.tv.sohu.com/us/266746298/707536079.shtml
https://tv.sohu.com/v/dXMvMjY2NzQ2Mjk4LzcwNzUzNjA3OS5zaHRtbA==.html
http://my.tv.sohu.com/us/278601206/707536309.shtml
https://tv.sohu.com/v/dXMvMjc4NjAxMjA2LzcwNzUzNjMwOS5zaHRtbA==.html
http://my.tv.sohu.com/us/297125191/707536104.shtml
https://tv.sohu.com/v/dXMvMjk3MTI1MTkxLzcwNzUzNjEwNC5zaHRtbA==.html
http://my.tv.sohu.com/us/325502589/707536303.shtml
https://tv.sohu.com/v/dXMvMzI1NTAyNTg5LzcwNzUzNjMwMy5zaHRtbA==.html
http://my.tv.sohu.com/us/305726550/707536302.shtml
https://tv.sohu.com/v/dXMvMzA1NzI2NTUwLzcwNzUzNjMwMi5zaHRtbA==.html
http://my.tv.sohu.com/us/200323727/707536102.shtml
https://tv.sohu.com/v/dXMvMjAwMzIzNzI3LzcwNzUzNjEwMi5zaHRtbA==.html
http://my.tv.sohu.com/us/278601206/707535800.shtml
https://tv.sohu.com/v/dXMvMjc4NjAxMjA2LzcwNzUzNTgwMC5zaHRtbA==.html
http://my.tv.sohu.com/us/266746298/707535799.shtml
https://tv.sohu.com/v/dXMvMjY2NzQ2Mjk4LzcwNzUzNTc5OS5zaHRtbA==.html
http://my.tv.sohu.com/us/297125191/707536204.shtml
https://tv.sohu.com/v/dXMvMjk3MTI1MTkxLzcwNzUzNjIwNC5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535946.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTk0Ni5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535943.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTk0My5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707536002.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNjAwMi5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535699.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTY5OS5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535834.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTgzNC5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535745.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTc0NS5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535940.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTk0MC5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535738.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTczOC5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535933.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTkzMy5zaHRtbA==.html
http://my.tv.sohu.com/us/240036200/707535737.shtml
https://tv.sohu.com/v/dXMvMjQwMDM2MjAwLzcwNzUzNTczNy5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535688.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTY4OC5zaHRtbA==.html
http://my.tv.sohu.com/us/297257850/707535682.shtml
https://tv.sohu.com/v/dXMvMjk3MjU3ODUwLzcwNzUzNTY4Mi5zaHRtbA==.html
http://my.tv.sohu.com/us/240036200/707535679.shtml
https://tv.sohu.com/v/dXMvMjQwMDM2MjAwLzcwNzUzNTY3OS5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535923.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTkyMy5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535825.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTgyNS5zaHRtbA==.html
http://my.tv.sohu.com/us/275702383/707535684.shtml
https://tv.sohu.com/v/dXMvMjc1NzAyMzgzLzcwNzUzNTY4NC5zaHRtbA==.html
http://my.tv.sohu.com/us/297759672/707535732.shtml
https://tv.sohu.com/v/dXMvMjk3NzU5NjcyLzcwNzUzNTczMi5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535821.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTgyMS5zaHRtbA==.html
http://my.tv.sohu.com/us/275702383/707535925.shtml
https://tv.sohu.com/v/dXMvMjc1NzAyMzgzLzcwNzUzNTkyNS5zaHRtbA==.html
http://my.tv.sohu.com/us/297759672/707535924.shtml
https://tv.sohu.com/v/dXMvMjk3NzU5NjcyLzcwNzUzNTkyNC5zaHRtbA==.html
http://my.tv.sohu.com/us/297257850/707535677.shtml
https://tv.sohu.com/v/dXMvMjk3MjU3ODUwLzcwNzUzNTY3Ny5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535676.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTY3Ni5zaHRtbA==.html
http://my.tv.sohu.com/us/275702383/707535922.shtml
https://tv.sohu.com/v/dXMvMjc1NzAyMzgzLzcwNzUzNTkyMi5zaHRtbA==.html
http://my.tv.sohu.com/us/297759672/707535730.shtml
https://tv.sohu.com/v/dXMvMjk3NzU5NjcyLzcwNzUzNTczMC5zaHRtbA==.html
http://my.tv.sohu.com/us/240036200/707535921.shtml
https://tv.sohu.com/v/dXMvMjQwMDM2MjAwLzcwNzUzNTkyMS5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535675.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTY3NS5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535729.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTcyOS5zaHRtbA==.html
http://my.tv.sohu.com/us/297257850/707535672.shtml
https://tv.sohu.com/v/dXMvMjk3MjU3ODUwLzcwNzUzNTY3Mi5zaHRtbA==.html
http://my.tv.sohu.com/us/275702383/707535728.shtml
https://tv.sohu.com/v/dXMvMjc1NzAyMzgzLzcwNzUzNTcyOC5zaHRtbA==.html
http://my.tv.sohu.com/us/240036200/707535726.shtml
https://tv.sohu.com/v/dXMvMjQwMDM2MjAwLzcwNzUzNTcyNi5zaHRtbA==.html
http://my.tv.sohu.com/us/294005880/707535917.shtml
https://tv.sohu.com/v/dXMvMjk0MDA1ODgwLzcwNzUzNTkxNy5zaHRtbA==.html
http://my.tv.sohu.com/us/297759672/707535727.shtml
https://tv.sohu.com/v/dXMvMjk3NzU5NjcyLzcwNzUzNTcyNy5zaHRtbA==.html
http://my.tv.sohu.com/us/273023296/707535918.shtml
https://tv.sohu.com/v/dXMvMjczMDIzMjk2LzcwNzUzNTkxOC5zaHRtbA==.html
http://my.tv.sohu.com/us/297257850/707535670.shtml
https://tv.sohu.com/v/dXMvMjk3MjU3ODUwLzcwNzUzNTY3MC5zaHRtbA==.html
class Game:
"""游戏主类:管理网格、碰撞检测、计分"""
def init(self):
self.grid = [[BLACK for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)] # 游戏网格(初始全黑)
self.current_tetromino = Tetromino() # 当前下落的方块
self.score = 0 # 分数
self.game_over = False # 游戏结束标志
def draw_grid(self):
"""绘制游戏网格(已落地的方块)"""
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
pygame.draw.rect(screen, self.grid[y][x], (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE - 1, BLOCK_SIZE - 1))
def check_collision(self, tetromino, dx=0, dy=0, rotated=False):
"""检测碰撞:dx=X偏移,dy=Y偏移,rotated=是否旋转后的形状"""
shape = tetromino.shape
if rotated:
临时计算旋转后的形状
shape = [list(row) for row in zip(*shape[::-1])]
for y, row in enumerate(shape):
for x, cell in enumerate(row):
if cell:
计算偏移后的坐标
new_x = tetromino.x + x + dx
new_y = tetromino.y + y + dy
碰撞条件:超出左右边界、超出下边界、碰到已落地的方块
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] != BLACK)):
return True
return False
def lock_tetromino(self):
"""将落地的方块锁定到网格中"""
for y, row in enumerate(self.current_tetromino.shape):
for x, cell in enumerate(row):
if cell:
grid_y = self.current_te