新增功能:速度控制系统
一、核心功能说明
- 速度变量设置:
- 最小速度:50ms (最快下限)
- 最大速度:1000ms (最慢上限)
- 调整步长:50ms
- 动态调整机制:
- 按键控制:+ 或 = 键加快速度(减少下落时间);
- - 键减慢速度(增加下落时间)
- 上下限保护:避免速度过极端,保障游戏体验平衡
二、UI 显示增强
- 右侧新增 “速度” 显示区域
- 速度等级从 1 开始,数值越高 = 速度越快 →
- 同步调整其他 UI 元素位置,布局更协调
三、操作说明更新
- 游戏启动时自动显示新按键说明
- 包含速度调整的详细操作指引
四、技术实现(文件:tetris.py,红色的点代表修改的代码)
- 初始化:添加速度控制相关变量
# 在 __init__ 方法中添加的代码(第182-184行)
self.fall_time = 0 # 方块下落计时器
self.fall_speed = 500 # 方块下落速度(毫秒)
self.min_speed = 50 # 最小下落速度(毫秒,最快)
self.max_speed = 1000 # 最大下落速度(毫秒,最慢)
self.speed_step = 50 # 速度调整步长(毫秒)
- 事件处理:在run方法中增加+/-键的处理逻辑
# 在 run 方法的事件处理中添加的代码(第480-491行)
# 空格键:直接下降到底部
elif event.key == pygame.K_SPACE:
# 持续下移直到无法继续下移
while self.is_valid_position(self.current_piece, dy=1):
self.current_piece['y'] += 1
# +键或=键:加快游戏速度(减少下落时间)
elif event.key == pygame.K_PLUS or event.key == pygame.K_EQUALS:
# 减少下落速度值,但不能小于最小速度
if self.fall_speed > self.min_speed:
self.fall_speed = max(self.min_speed, self.fall_speed - self.speed_step)
# -键:减慢游戏速度(增加下落时间)
elif event.key == pygame.K_MINUS:
# 增加下落速度值,但不能大于最大速度
if self.fall_speed < self.max_speed:
self.fall_speed = min(self.max_speed, self.fall_speed + self.speed_step)
- UI 绘制:在draw_ui方法中添加速度显示模块
# 在 draw_ui 方法中添加的代码(第400-409行)
# 将行数文本绘制到屏幕上
self.screen.blit(lines_text, (ui_x, 150))
# ==================== 绘制游戏速度信息 ====================
# 计算速度等级(速度越快等级越高)
speed_level = (self.max_speed - self.fall_speed) // self.speed_step + 1
# 尝试使用中文字体渲染速度,失败则使用英文
try:
speed_text = self.font_chinese.render(f"速度: {speed_level}", True, WHITE)
except:
speed_text = self.font.render(f"Speed: {speed_level}", True, WHITE)
# 将速度文本绘制到屏幕上
self.screen.blit(speed_text, (ui_x, 200))
- 布局调整:重新排列 UI 元素位置
# 调整下一个方块预览的位置(第418行和第431行)
self.screen.blit(next_text, (ui_x, 250)) # 从200改为250
draw_y = 290 + y * 20 # 从240改为290
功能亮点
玩家可根据自身喜好和技能水平实时调整速度,让游戏体验更个性化、更灵活!
5. 操作说明更新
# 在程序入口点添加的操作说明(第555-556行)
print("空格 : 直接下降到底部") # 空格键让方块直接下降到底部
print("+ = : 加快游戏速度") # +或=键加快游戏速度
print("- : 减慢游戏速度") # -键减慢游戏速度
print("") # 空行分隔
以下为完整代码
# 导入pygame游戏开发库,用于图形界面和游戏循环
import pygame
# 导入random库,用于随机生成方块
import random
# 导入sys库,用于程序退出
import sys
# 初始化pygame库,必须在使用pygame功能前调用
pygame.init()
# ==================== 游戏常量定义 ====================
WIDTH = 800 # 游戏窗口的宽度(像素)
HEIGHT = 700 # 游戏窗口的高度(像素,修复底部显示不全的问题)
BLOCK_SIZE = 30 # 每个方块的大小(像素)
GRID_WIDTH = 10 # 游戏区域的宽度(以方块为单位)
GRID_HEIGHT = 20 # 游戏区域的高度(以方块为单位)
GRID_X_OFFSET = 50 # 游戏区域距离窗口左边的偏移量(像素)
GRID_Y_OFFSET = 50 # 游戏区域距离窗口顶部的偏移量(像素)
# ==================== 颜色定义(RGB值) ====================
BLACK = (0, 0, 0) # 黑色,用于背景
WHITE = (255, 255, 255) # 白色,用于文字和网格线
RED = (255, 0, 0) # 红色,用于Z形方块
GREEN = (0, 255, 0) # 绿色,用于S形方块
BLUE = (0, 0, 255) # 蓝色,用于J形方块
YELLOW = (255, 255, 0) # 黄色,用于O形方块
ORANGE = (255, 165, 0) # 橙色,用于L形方块
PURPLE = (128, 0, 128) # 紫色,用于T形方块
CYAN = (0, 255, 255) # 青色,用于I形方块
GRAY = (128, 128, 128) # 灰色,用于网格线
# ==================== 俄罗斯方块的7种形状定义 ====================
# 每个形状用二维数组表示,'#'表示有方块,'.'表示空
# 每个形状可以有多个旋转状态(0度、90度、180度、270度)
TETRIS_SHAPES = [
# I形状(直线方块)- 有2个旋转状态
[['.....', # 第一个状态:垂直
'..#..', # 中间一列有4个方块
'..#..',
'..#..',
'..#..'],
['.....', # 第二个状态:水平
'.....', # 中间一行有4个方块
'####.',
'.....',
'.....']],
# O形状(正方形方块)- 只有1个旋转状态(旋转后形状不变)
[['.....',
'.....', # 2x2的正方形
'.##..',
'.##..',
'.....']],
# T形状(T字形方块)- 有4个旋转状态
[['.....', # 状态1:T字正立
'.....',
'.#...', # 上面一个方块
'###..', # 下面一行三个方块
'.....'],
['.....', # 状态2:T字向右
'.....',
'.#...', # 左边一个方块
'.##..', # 中间两个方块
'.#...'], # 右边一个方块
['.....', # 状态3:T字倒立
'.....',
'.....',
'###..', # 上面一行三个方块
'.#...'], # 下面一个方块
['.....', # 状态4:T字向左
'.....',
'.#...', # 右边一个方块
'##...', # 中间两个方块
'.#...']], # 左边一个方块
# S形状(S字形方块)- 有2个旋转状态
[['.....', # 状态1:水平S形
'.....',
'.##..', # 右上两个方块
'##...', # 左下两个方块
'.....'],
['.....', # 状态2:垂直S形
'.....',
'.#...', # 上方一个方块
'.##..', # 中间两个方块
'..#..']], # 下方一个方块
# Z形状(Z字形方块)- 有2个旋转状态
[['.....', # 状态1:水平Z形
'.....',
'##...', # 左上两个方块
'.##..', # 右下两个方块
'.....'],
['.....', # 状态2:垂直Z形
'.....',
'..#..', # 上方一个方块
'.##..', # 中间两个方块
'.#...']], # 下方一个方块
# J形状(J字形方块)- 有4个旋转状态
[['.....', # 状态1:J字正立
'.....',
'.#...', # 上方一个方块
'.#...', # 中间一个方块
'##...'], # 下方两个方块(左转弯)
['.....', # 状态2:J字向右
'.....',
'.....',
'#....', # 左边一个方块
'###..'], # 右边三个方块
['.....', # 状态3:J字倒立
'.....',
'.##..', # 上方两个方块(右转弯)
'.#...', # 中间一个方块
'.#...'], # 下方一个方块
['.....', # 状态4:J字向左
'.....',
'.....',
'###..', # 左边三个方块
'..#..']], # 右边一个方块
# L形状(L字形方块)- 有4个旋转状态
[['.....', # 状态1:L字正立
'.....',
'..#..', # 上方一个方块
'..#..', # 中间一个方块
'.##..'], # 下方两个方块(右转弯)
['.....', # 状态2:L字向右
'.....',
'.....',
'###..', # 左边三个方块
'#....'], # 右边一个方块
['.....', # 状态3:L字倒立
'.....',
'##...', # 上方两个方块(左转弯)
'.#...', # 中间一个方块
'.#...'], # 下方一个方块
['.....', # 状态4:L字向左
'.....',
'.....',
'..#..', # 右边一个方块
'###..']] # 左边三个方块
]
# ==================== 形状颜色映射 ====================
# 每种形状对应的颜色,按照TETRIS_SHAPES的顺序排列
# 0:I形状-青色, 1:O形状-黄色, 2:T形状-紫色, 3:S形状-绿色, 4:Z形状-红色, 5:J形状-蓝色, 6:L形状-橙色
SHAPE_COLORS = [CYAN, YELLOW, PURPLE, GREEN, RED, BLUE, ORANGE]
# ==================== 俄罗斯方块游戏主类 ====================
class Tetris:
"""俄罗斯方块游戏主类"""
def __init__(self):
"""初始化俄罗斯方块游戏"""
# ==================== 游戏窗口初始化 ====================
# 创建游戏窗口,设置窗口大小为WIDTH x HEIGHT像素
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
# 设置窗口标题
pygame.display.set_caption("俄罗斯方块 - Python学习版")
# 创建时钟对象,用于控制游戏帧率
self.clock = pygame.time.Clock()
# ==================== 游戏状态变量初始化 ====================
# 创建游戏网格,初始化为全0(空白)
# 网格大小为GRID_HEIGHT行 x GRID_WIDTH列
self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
self.score = 0 # 当前得分
self.level = 1 # 当前等级
self.lines_cleared = 0 # 已消除的行数
self.fall_time = 0 # 方块下落计时器
self.fall_speed = 500 # 方块下落速度(毫秒)
self.min_speed = 50 # 最小下落速度(毫秒,最快)
self.max_speed = 1000 # 最大下落速度(毫秒,最慢)
self.speed_step = 50 # 速度调整步长(毫秒)
# ==================== 当前和下一个方块初始化 ====================
# 获取第一个随机方块作为当前方块
self.current_piece = self.get_new_piece()
# 预生成下一个方块,用于预览显示
self.next_piece = self.get_new_piece()
# ==================== 字体设置初始化 ====================
# 创建默认字体对象,用于显示英文文字(48像素大小)
self.font = pygame.font.Font(None, 48)
# 尝试加载中文字体,如果失败则使用默认字体作为备用
try:
# 使用系统宋体字体显示中文文字(36像素大小)
self.font_chinese = pygame.font.SysFont('simsun', 36)
except:
# 如果中文字体加载失败,使用默认字体
self.font_chinese = self.font
def get_new_piece(self):
"""生成新的俄罗斯方块"""
# 随机选择一个形状索引(0-6,对应7种不同的俄罗斯方块形状)
shape_index = random.randint(0, len(TETRIS_SHAPES) - 1)
# 返回一个包含方块所有信息的字典
return {
'shape': TETRIS_SHAPES[shape_index], # 方块的形状数据(包含所有旋转状态)
'rotation': 0, # 当前旋转状态(从0开始)
'x': GRID_WIDTH // 2 - 2, # 初始X坐标(水平居中)
'y': 0, # 初始Y坐标(从顶部开始)
'color': SHAPE_COLORS[shape_index] # 方块的颜色
}
def is_valid_position(self, piece, dx=0, dy=0, rotation=None):
"""检查方块位置是否有效"""
# 如果没有指定旋转状态,使用当前旋转状态
if rotation is None:
rotation = piece['rotation']
# 获取指定旋转状态下的方块形状
shape = piece['shape'][rotation]
# 遍历方块形状的每一行
for y, row in enumerate(shape):
# 遍历每一行的每一列
for x, cell in enumerate(row):
# 如果当前位置有方块(用'#'表示)
if cell == '#':
# 计算方块在游戏网格中的实际坐标
new_x = piece['x'] + x + dx # 当前X + 形状内偏移 + 移动偏移
new_y = piece['y'] + y + dy # 当前Y + 形状内偏移 + 移动偏移
# 检查是否超出游戏区域边界
if (new_x < 0 or new_x >= GRID_WIDTH or
new_y >= GRID_HEIGHT):
return False # 超出边界,位置无效
# 检查是否与已放置的方块重叠
# new_y >= 0 确保不检查游戏区域上方的位置
if new_y >= 0 and self.grid[new_y][new_x] != 0:
return False # 发生重叠,位置无效
return True # 所有检查通过,位置有效
def place_piece(self, piece):
"""将方块放置到游戏区域"""
# 获取当前旋转状态下的方块形状
shape = piece['shape'][piece['rotation']]
# 遍历方块形状的每一行
for y, row in enumerate(shape):
# 遍历每一行的每一列
for x, cell in enumerate(row):
# 如果当前位置有方块(用'#'表示)
if cell == '#':
# 计算在游戏网格中的坐标
grid_x = piece['x'] + x # 方块X坐标 + 形状内X偏移
grid_y = piece['y'] + y # 方块Y坐标 + 形状内Y偏移
# 只有当Y坐标在游戏区域内时才放置方块
if grid_y >= 0:
# 将方块的颜色放置到游戏网格中
self.grid[grid_y][grid_x] = piece['color']
def clear_lines(self):
"""清除完整的行"""
# 存储需要清除的行号
lines_to_clear = []
# ==================== 查找完整行 ====================
# 从上到下检查每一行
for y in range(GRID_HEIGHT):
# 检查当前行是否完全填满(所有位置都不为0)
if all(self.grid[y][x] != 0 for x in range(GRID_WIDTH)):
lines_to_clear.append(y) # 添加到待清除列表
# ==================== 清除完整行 ====================
# 删除所有完整的行
for y in lines_to_clear:
del self.grid[y] # 删除完整行
# 在顶部插入新的空行(全为0)
self.grid.insert(0, [0 for _ in range(GRID_WIDTH)])
# ==================== 更新游戏状态 ====================
lines_cleared = len(lines_to_clear) # 本次清除的行数
if lines_cleared > 0:
# 更新总清除行数
self.lines_cleared += lines_cleared
# 分数计算:1行100分,2行300分,3行500分,4行800分
score_values = [0, 100, 300, 500, 800]
# 根据清除行数和当前等级计算得分
self.score += score_values[min(lines_cleared, 4)] * self.level
# 每清除10行提升一个等级
self.level = self.lines_cleared // 10 + 1
# 等级越高,下降速度越快(最快50毫秒)
self.fall_speed = max(50, 500 - (self.level - 1) * 50)
def rotate_piece(self, piece):
"""旋转方块"""
# 计算下一个旋转状态(循环:0->1->2->3->0...)
new_rotation = (piece['rotation'] + 1) % len(piece['shape'])
# 检查新的旋转状态是否有效(不会碰撞或超出边界)
if self.is_valid_position(piece, rotation=new_rotation):
# 如果有效,更新方块的旋转状态
piece['rotation'] = new_rotation
def draw_grid(self):
"""绘制游戏网格"""
# ==================== 绘制垂直网格线 ====================
# 绘制GRID_WIDTH+1条垂直线(包括左右边界)
for x in range(GRID_WIDTH + 1):
# 计算当前垂直线的X坐标
line_x = GRID_X_OFFSET + x * BLOCK_SIZE
# 绘制从顶部到底部的垂直线
pygame.draw.line(self.screen, GRAY,
(line_x, GRID_Y_OFFSET), # 起点:顶部
(line_x, GRID_Y_OFFSET + GRID_HEIGHT * BLOCK_SIZE)) # 终点:底部
# ==================== 绘制水平网格线 ====================
# 绘制GRID_HEIGHT+1条水平线(包括上下边界)
for y in range(GRID_HEIGHT + 1):
# 计算当前水平线的Y坐标
line_y = GRID_Y_OFFSET + y * BLOCK_SIZE
# 绘制从左侧到右侧的水平线
pygame.draw.line(self.screen, GRAY,
(GRID_X_OFFSET, line_y), # 起点:左侧
(GRID_X_OFFSET + GRID_WIDTH * BLOCK_SIZE, line_y)) # 终点:右侧
def draw_piece(self, piece):
"""绘制当前下落的方块"""
# 获取当前旋转状态下的方块形状
shape = piece['shape'][piece['rotation']]
# 遍历方块形状的每一行
for y, row in enumerate(shape):
# 遍历每一行的每一列
for x, cell in enumerate(row):
# 如果当前位置有方块(用'#'表示)
if cell == '#':
# 计算方块在屏幕上的绘制坐标
draw_x = GRID_X_OFFSET + (piece['x'] + x) * BLOCK_SIZE
draw_y = GRID_Y_OFFSET + (piece['y'] + y) * BLOCK_SIZE
# 绘制方块(留1像素边距以显示网格线)
pygame.draw.rect(self.screen, piece['color'],
(draw_x + 1, draw_y + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2))
def draw_placed_blocks(self):
"""绘制已放置在游戏区域中的方块"""
# 遍历游戏网格的每一行
for y in range(GRID_HEIGHT):
# 遍历每一行的每一列
for x in range(GRID_WIDTH):
# 如果当前位置有方块(不为0表示有颜色)
if self.grid[y][x] != 0:
# 计算方块在屏幕上的绘制坐标
draw_x = GRID_X_OFFSET + x * BLOCK_SIZE
draw_y = GRID_Y_OFFSET + y * BLOCK_SIZE
# 绘制方块(留1像素边距以显示网格线)
pygame.draw.rect(self.screen, self.grid[y][x],
(draw_x + 1, draw_y + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2))
def draw_ui(self):
"""绘制用户界面(分数、等级、行数、下一个方块预览)"""
# ==================== 计算UI区域位置 ====================
# 计算UI区域的起始X坐标(游戏区域右侧30像素处)
ui_x = GRID_X_OFFSET + GRID_WIDTH * BLOCK_SIZE + 30
# ==================== 绘制分数信息 ====================
# 尝试使用中文字体渲染分数,失败则使用英文
try:
score_text = self.font_chinese.render(f"分数: {self.score}", True, WHITE)
except:
score_text = self.font.render(f"Score: {self.score}", True, WHITE)
# 将分数文本绘制到屏幕上
self.screen.blit(score_text, (ui_x, 50))
# ==================== 绘制等级信息 ====================
# 尝试使用中文字体渲染等级,失败则使用英文
try:
level_text = self.font_chinese.render(f"等级: {self.level}", True, WHITE)
except:
level_text = self.font.render(f"Level: {self.level}", True, WHITE)
# 将等级文本绘制到屏幕上
self.screen.blit(level_text, (ui_x, 100))
# ==================== 绘制已清除行数信息 ====================
# 尝试使用中文字体渲染行数,失败则使用英文
try:
lines_text = self.font_chinese.render(f"行数: {self.lines_cleared}", True, WHITE)
except:
lines_text = self.font.render(f"Lines: {self.lines_cleared}", True, WHITE)
# 将行数文本绘制到屏幕上
self.screen.blit(lines_text, (ui_x, 150))
# ==================== 绘制游戏速度信息 ====================
# 计算速度等级(速度越快等级越高)
speed_level = (self.max_speed - self.fall_speed) // self.speed_step + 1
# 尝试使用中文字体渲染速度,失败则使用英文
try:
speed_text = self.font_chinese.render(f"速度: {speed_level}", True, WHITE)
except:
speed_text = self.font.render(f"Speed: {speed_level}", True, WHITE)
# 将速度文本绘制到屏幕上
self.screen.blit(speed_text, (ui_x, 200))
# ==================== 绘制下一个方块预览标题 ====================
# 尝试使用中文字体渲染"下一个"标题,失败则使用英文
try:
next_text = self.font_chinese.render("下一个:", True, WHITE)
except:
next_text = self.font.render("Next:", True, WHITE)
# 将标题文本绘制到屏幕上
self.screen.blit(next_text, (ui_x, 250))
# ==================== 绘制下一个方块预览图形 ====================
# 获取下一个方块的第一个旋转状态(默认状态)
shape = self.next_piece['shape'][0]
# 遍历方块形状的每一行
for y, row in enumerate(shape):
# 遍历每一行的每一列
for x, cell in enumerate(row):
# 如果当前位置有方块(用'#'表示)
if cell == '#':
# 计算预览方块的绘制坐标(相对于UI区域)
draw_x = ui_x + 20 + x * 20 # UI区域X + 20像素偏移 + 列索引*20像素
draw_y = 290 + y * 20 # 固定Y位置290 + 行索引*20像素
# 绘制预览方块(18x18像素,留2像素间距)
pygame.draw.rect(self.screen, self.next_piece['color'],
(draw_x, draw_y, 18, 18))
def is_game_over(self):
"""检查游戏是否结束"""
# 游戏结束条件:新生成的方块无法放置在初始位置
# 如果当前方块在初始位置就无效,说明游戏区域已满
return not self.is_valid_position(self.current_piece)
def run(self):
"""游戏主循环 - 处理事件、更新游戏状态、绘制画面"""
# 游戏运行标志
running = True
# ==================== 主游戏循环 ====================
while running:
# 控制游戏帧率为60FPS,并获取上一帧的时间间隔(毫秒)
dt = self.clock.tick(60)
# 累加方块下落时间
self.fall_time += dt
# ==================== 事件处理 ====================
# 处理所有pygame事件(键盘输入、窗口关闭等)
for event in pygame.event.get():
# 处理窗口关闭事件
if event.type == pygame.QUIT:
running = False # 退出游戏循环
# 处理键盘按下事件
elif event.type == pygame.KEYDOWN:
# 左箭头键:向左移动方块
if event.key == pygame.K_LEFT:
# 检查左移是否有效(不会碰撞或超出边界)
if self.is_valid_position(self.current_piece, dx=-1):
self.current_piece['x'] -= 1 # 向左移动一格
# 右箭头键:向右移动方块
elif event.key == pygame.K_RIGHT:
# 检查右移是否有效(不会碰撞或超出边界)
if self.is_valid_position(self.current_piece, dx=1):
self.current_piece['x'] += 1 # 向右移动一格
# 下箭头键:加速下降方块
elif event.key == pygame.K_DOWN:
# 检查下移是否有效(不会碰撞或到达底部)
if self.is_valid_position(self.current_piece, dy=1):
self.current_piece['y'] += 1 # 向下移动一格
# 上箭头键:旋转方块
elif event.key == pygame.K_UP:
# 尝试旋转当前方块
self.rotate_piece(self.current_piece)
# 空格键:直接下降到底部
elif event.key == pygame.K_SPACE:
# 持续下移直到无法继续下移
while self.is_valid_position(self.current_piece, dy=1):
self.current_piece['y'] += 1
# +键或=键:加快游戏速度(减少下落时间)
elif event.key == pygame.K_PLUS or event.key == pygame.K_EQUALS:
# 减少下落速度值,但不能小于最小速度
if self.fall_speed > self.min_speed:
self.fall_speed = max(self.min_speed, self.fall_speed - self.speed_step)
# -键:减慢游戏速度(增加下落时间)
elif event.key == pygame.K_MINUS:
# 增加下落速度值,但不能大于最大速度
if self.fall_speed < self.max_speed:
self.fall_speed = min(self.max_speed, self.fall_speed + self.speed_step)
# ==================== 自动下降逻辑 ====================
# 检查是否到了自动下降的时间
if self.fall_time >= self.fall_speed:
# 尝试让当前方块下降一格
if self.is_valid_position(self.current_piece, dy=1):
self.current_piece['y'] += 1 # 继续下降
else:
# 方块无法继续下降,进行放置和清理操作
self.place_piece(self.current_piece) # 将方块放置到游戏区域
self.clear_lines() # 检查并清除完整的行
self.current_piece = self.next_piece # 当前方块变为下一个方块
self.next_piece = self.get_new_piece() # 生成新的下一个方块
# 检查游戏是否结束
if self.is_game_over():
print(f"游戏结束!最终分数: {self.score}")
running = False # 退出游戏循环
# 重置下降计时器
self.fall_time = 0
# ==================== 绘制游戏画面 ====================
# 清空屏幕(填充黑色背景)
self.screen.fill(BLACK)
# 绘制游戏网格线
self.draw_grid()
# 绘制已放置的方块
self.draw_placed_blocks()
# 绘制当前下落的方块
self.draw_piece(self.current_piece)
# 绘制用户界面(分数、等级等信息)
self.draw_ui()
# 更新显示(将绘制的内容显示到屏幕上)
pygame.display.flip()
# ==================== 游戏结束清理 ====================
# 退出pygame
pygame.quit()
# 退出程序
sys.exit()
# ==================== 程序入口点 ====================
if __name__ == "__main__":
# 显示游戏欢迎信息和操作说明
print("欢迎来到俄罗斯方块游戏!")
print("操作说明:")
print("← → : 左右移动") # 左右箭头键控制方块左右移动
print("↓ : 加速下降") # 下箭头键加速方块下降
print("↑ : 旋转方块") # 上箭头键旋转方块
print("空格 : 直接下降到底部") # 空格键让方块直接下降到底部
print("+ = : 加快游戏速度") # +或=键加快游戏速度
print("- : 减慢游戏速度") # -键减慢游戏速度
print("") # 空行分隔
# 创建游戏实例并开始运行
game = Tetris()
game.run()