俄罗斯方块作为一款经典的益智游戏,自问世以来便广受欢迎。本文将详细介绍如何使用Python的Pygame库开发一个功能完整的俄罗斯方块游戏。通过这个项目,你将学习到游戏开发的基本原理和Pygame的使用方法。
在开始编码之前,让我们先了解一下游戏的基本设计:
由20×30的网格组成,每个方块占据一个单元格
7种不同形状的方块(I、O、T、J、L、S、Z),每种有独特的颜色
方块从顶部中央生成并自动下落,玩家可以控制移动和旋转
消除完整行获得分数,随着分数增加游戏难度提高
下面是完整的游戏实现代码,我将逐步解释各个部分的功能:
pip install pygame命令安装。
import pygame
import random
from pygame import *
# 初始化
pygame.init()
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
ORANGE = (255, 165, 0)
YELLOW = (255, 255, 0)
GREEN = (0, 255, 0)
PURPLE = (128, 0, 128)
RED = (255, 0, 0)
# 游戏设置
CELL_SIZE = 30
GRID_WIDTH = 20
GRID_HEIGHT = 30
SCREEN_WIDTH = CELL_SIZE * (GRID_WIDTH + 6)
SCREEN_HEIGHT = CELL_SIZE * GRID_HEIGHT
GAME_AREA_LEFT = CELL_SIZE
# 方块形状
SHAPES = [
[[1, 1, 1, 1]], # I
[[1, 1], [1, 1]], # O
[[1, 1, 1], [0, 1, 0]], # T
[[1, 1, 1], [1, 0, 0]], # J
[[1, 1, 1], [0, 0, 1]], # L
[[0, 1, 1], [1, 1, 0]], # S
[[1, 1, 0], [0, 1, 1]] # Z
]
# 方块颜色
COLORS = [CYAN, YELLOW, PURPLE, BLUE, ORANGE, GREEN, RED]
这段代码主要完成了游戏的初始化工作,包括导入必要的库、定义颜色常量、设置游戏参数以及方块的形状和颜色。
接下来是游戏的核心类Tetris,它包含了游戏的所有逻辑和功能:
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
self.font = pygame.font.SysFont('simhei', 25)
def new_piece(self):
# 随机选择方块和颜色
shape = random.choice(SHAPES)
color = COLORS[SHAPES.index(shape)]
# 初始位置在顶部中间
x = GRID_WIDTH // 2 - len(shape[0]) // 2
y = 0
return {'shape': shape, 'x': x, 'y': y, 'color': color}
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_offset
new_y = piece['y'] + y + y_offset
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
__init__方法初始化游戏窗口、网格、当前方块等基本属性。new_piece方法随机生成一个新的方块,并将其放置在网格顶部中央。valid_move方法用于检查方块在移动或旋转后是否合法,确保不会超出边界或与已锁定的方块重叠。
def rotate_piece(self):
# 转置矩阵然后反转每一行实现旋转
rotated = list(zip(*self.current_piece['shape'][::-1]))
rotated = [list(row) for row in rotated]
old_shape = self.current_piece['shape']
self.current_piece['shape'] = rotated
if not self.valid_move(self.current_piece):
self.current_piece['shape'] = old_shape
def 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 = True
def clear_lines(self):
lines_cleared = 0
for 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][:]
self.grid[0] = [0 for _ in range(GRID_WIDTH)]
# 更新分数
if lines_cleared:
self.score += lines_cleared * 10 # 改为每行10分
rotate_piece方法实现方块的旋转功能,通过矩阵转置和反转来实现。lock_piece方法将当前方块锁定在网格中,并检查是否有完整的行需要消除。clear_lines方法遍历所有行,找到并消除完整的行,同时更新分数。
def draw_controls(self):
# 绘制控制说明
controls = [
"控制说明:",
"← → : 左右移动",
"↑ : 旋转",
"↓ : 加速下落",
"F : 水平翻转",
"V : 垂直翻转",
"空格 : 直接落到底部"
]
for i, text in enumerate(controls):
control_text = self.font.render(text, True, WHITE)
self.screen.blit(control_text,
(GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE + 10,
80 + i * 30))
def draw(self):
self.screen.fill(BLACK)
# 绘制游戏区域边框
pygame.draw.rect(self.screen, WHITE,
(GAME_AREA_LEFT - 2, 0,
CELL_SIZE * GRID_WIDTH + 4,
CELL_SIZE * GRID_HEIGHT + 4), 2)
# 绘制网格
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
if self.grid[y][x]:
pygame.draw.rect(self.screen, self.grid[y][x],
(GAME_AREA_LEFT + x * CELL_SIZE,
y * CELL_SIZE,
CELL_SIZE, CELL_SIZE))
pygame.draw.rect(self.screen, WHITE,
(GAME_AREA_LEFT + x * CELL_SIZE,
y * CELL_SIZE,
CELL_SIZE, CELL_SIZE), 1)
# 绘制当前方块
for y, row in enumerate(self.current_piece['shape']):
for x, cell in enumerate(row):
if cell:
pygame.draw.rect(self.screen, self.current_piece['color'],
(GAME_AREA_LEFT + (self.current_piece['x'] + x) * CELL_SIZE,
(self.current_piece['y'] + y) * CELL_SIZE,
CELL_SIZE, CELL_SIZE))
pygame.draw.rect(self.screen, WHITE,
(GAME_AREA_LEFT + (self.current_piece['x'] + x) * CELL_SIZE,
(self.current_piece['y'] + y) * CELL_SIZE,
CELL_SIZE, CELL_SIZE), 1)
# 绘制分数
score_text = self.font.render(f'score: {self.score}', True, WHITE)
self.screen.blit(score_text, (GAME_AREA_LEFT + GRID_WIDTH * CELL_SIZE + 10, 30))
# 游戏结束提示
if self.game_over:
game_over_text = self.font.render('GAME OVER!', True, RED)
self.screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 70, SCREEN_HEIGHT // 2 - 15))
# 绘制控制说明
self.draw_controls()
pygame.display.update()
draw_controls方法显示游戏控制说明,告诉玩家如何操作。draw方法负责渲染整个游戏界面,包括游戏区域边框、已锁定的方块、当前正在下落的方块、分数和游戏结束提示等。
def run(self):
fall_time = 0
fall_speed = 0.5 # 秒
while not self.game_over:
fall_time += self.clock.get_rawtime() / 1000
self.clock.tick()
# 方块自动下落
if fall_time >= fall_speed:
fall_time = 0
if self.valid_move(self.current_piece, 0, 1):
self.current_piece['y'] += 1
else:
self.lock_piece()
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:
self.rotate_piece()
elif event.key == pygame.K_f: # 水平翻转
self.flip_piece(horizontal=True)
elif event.key == pygame.K_v: # 垂直翻转
self.flip_piece(horizontal=False)
elif event.key == pygame.K_SPACE: # 硬降落
while self.valid_move(self.current_piece, 0, 1):
self.current_piece['y'] += 1
self.lock_piece()
self.draw()
pygame.quit()
if __name__ == "__main__":
game = Tetris()
game.run()
run方法是游戏的主循环,控制游戏的运行流程。它处理方块的自动下落、用户输入事件(如按键操作),并更新游戏状态和渲染画面,直到游戏结束。
这个俄罗斯方块游戏已经具备了基本功能,但还有很多可以扩展和优化的地方:
添加下一个方块预览功能,让玩家提前知道接下来会出现什么方块
实现游戏级别系统,随着分数增加提高方块下落速度
添加音效和背景音乐,增强游戏体验
设计更美观的界面和动画效果
实现游戏暂停和继续功能
添加高分榜功能,记录玩家的最高分数
通过这个项目,你学习了如何使用Pygame开发一个完整的游戏,包括游戏循环、图形渲染、用户输入处理等核心概念。希望这篇文章对你理解游戏开发有所帮助!