Pygame - 俄罗斯方块游戏开发教程

发布于:2025-02-11 ⋅ 阅读:(39) ⋅ 点赞:(0)

本教程将带你一步步制作一个简单的俄罗斯方块游戏,使用Python和pygame库。我们将逐步了解如何创建游戏窗口、实现方块控制、碰撞检测、行消除、计分等功能,最后完成一个基本的俄罗斯方块游戏。


1. 准备工作

首先,你需要确保已安装pygame库。你可以通过以下命令安装:

pip install pygame

2. 初始化游戏

我们开始编写游戏的基础结构,包括初始化pygame,创建游戏窗口,定义常用的颜色和形状。

import pygame
import random

# 初始化pygame
pygame.init()

# 颜色定义
COLORS = [
    (0, 0, 0),        # 黑色 - 背景
    (120, 195, 239),  # 浅蓝色
    (147, 226, 149),  # 浅绿色
    (249, 150, 139),  # 浅红色
    (248, 198, 139),  # 浅橙色
    (136, 139, 242),  # 浅紫色
    (245, 150, 242),  # 浅粉色
    (158, 158, 158)   # 浅灰色
]

# 方块形状定义
SHAPES = [
    [[1, 5, 9, 13], [4, 5, 6, 7]],  # I
    [[4, 5, 9, 10], [2, 6, 5, 9]],  # Z
    [[6, 7, 9, 10], [1, 5, 6, 10]], # S
    [[1, 2, 5, 9], [0, 4, 5, 6], [1, 5, 9, 8], [4, 5, 6, 10]], # J
    [[1, 2, 6, 10], [5, 6, 7, 9], [2, 6, 10, 11], [3, 5, 6, 7]], # L
    [[1, 4, 5, 6], [1, 4, 5, 9], [4, 5, 6, 9], [1, 5, 6, 9]], # T
    [[1, 2, 5, 6]], # O
]

# 游戏配置
FIELD_WIDTH = 10
FIELD_HEIGHT = 20
TILE_SIZE = 30
GAME_RES = FIELD_WIDTH * TILE_SIZE, FIELD_HEIGHT * TILE_SIZE
FPS = 60

# 创建游戏窗口
screen = pygame.display.set_mode(GAME_RES)
pygame.display.set_caption('俄罗斯方块')
clock = pygame.time.Clock()

# 游戏网格
field = [[0 for i in range(FIELD_WIDTH)] for j in range(FIELD_HEIGHT)]

3. 创建方块类

Tetromino类用于生成和控制游戏中的方块。每个方块有位置、类型、颜色和旋转状态。

# 方块类
class Tetromino:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.type = random.randint(0, len(SHAPES) - 1)
        self.color = random.randint(1, len(COLORS) - 1)
        self.rotation = 0

    def image(self):
        return SHAPES[self.type][self.rotation]

    def rotate(self):
        self.rotation = (self.rotation + 1) % len(SHAPES[self.type])

4. 创建方块生成和碰撞检测

我们需要实现生成新方块和检测方块是否与其他方块或墙壁发生碰撞。

# 创建方块
def create_figure():
    return Tetromino(3, 0)

# 检查碰撞
def intersects():
    for i in range(4):
        for j in range(4):
            if i * 4 + j in figure.image():
                if (i + figure.y > FIELD_HEIGHT - 1 or
                    j + figure.x > FIELD_WIDTH - 1 or
                    j + figure.x < 0 or
                    field[i + figure.y][j + figure.x] > 0):
                    return True
    return False

5. 行消除

每当一行被填满时,需要将其从游戏场景中删除,并且所有上面的行下移。

# 消除完整的行
def break_lines():
    lines = 0
    for i in range(1, FIELD_HEIGHT):
        zeros = 0
        for j in range(FIELD_WIDTH):
            if field[i][j] == 0:
                zeros += 1
        if zeros == 0:
            lines += 1
            for i1 in range(i, 1, -1):
                for j in range(FIELD_WIDTH):
                    field[i1][j] = field[i1-1][j]
    return lines

6. 主游戏循环

我们将实现游戏的主循环,其中包括方块的下落、用户输入的处理(控制方块的移动和旋转)、以及绘制游戏界面。

# 主游戏循环
figure = create_figure()
counter = 0
pressing_down = False
game_over = False
score = 0

while not game_over:
    counter += 1
    if counter > 100000:
        counter = 0

    # 每30帧下落一次
    if counter % (FPS // 2) == 0 or pressing_down:
        if figure.y < FIELD_HEIGHT - 1:
            figure.y += 1
            if intersects():
                figure.y -= 1
                # 固定方块
                for i in range(4):
                    for j in range(4):
                        if i * 4 + j in figure.image():
                            field[figure.y + i][figure.x + j] = figure.color
                # 创建新方块
                figure = create_figure()
                if intersects():
                    game_over = True

    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                figure.rotate()
                if intersects():
                    figure.rotate()
                    figure.rotate()
                    figure.rotate()
            if event.key == pygame.K_LEFT:
                figure.x -= 1
                if intersects():
                    figure.x += 1
            if event.key == pygame.K_RIGHT:
                figure.x += 1
                if intersects():
                    figure.x -= 1
            if event.key == pygame.K_DOWN:
                pressing_down = True
        if event.type == pygame.KEYUP and event.key == pygame.K_DOWN:
            pressing_down = False

    # 绘制背景
    screen.fill(COLORS[0])

    # 绘制已固定的方块
    for i in range(FIELD_HEIGHT):
        for j in range(FIELD_WIDTH):
            if field[i][j] > 0:
                pygame.draw.rect(screen, COLORS[field[i][j]], 
                               [j * TILE_SIZE, i * TILE_SIZE, TILE_SIZE - 1, TILE_SIZE - 1])

    # 绘制当前方块
    for i in range(4):
        for j in range(4):
            if i * 4 + j in figure.image():
                pygame.draw.rect(screen, COLORS[figure.color], 
                               [(figure.x + j) * TILE_SIZE, 
                                (figure.y + i) * TILE_SIZE, 
                                TILE_SIZE - 1, TILE_SIZE - 1])

    # 检查并消除完整的行
    score += break_lines()

    # 更新显示
    pygame.display.flip()
    clock.tick(FPS)

# 游戏结束
font = pygame.font.Font(None, 48)
text = font.render(f'游戏结束! 得分: {score}', True, (255, 255, 255))
screen.blit(text, (GAME_RES[0] // 4, GAME_RES[1] // 2))
pygame.display.flip()

# 等待几秒后退出
pygame.time.wait(3000)
pygame.quit()

7. 完成游戏

至此,你已经完成了一个基本的俄罗斯方块游戏。你可以运行代码并体验游戏。游戏包括:

  • 方块下落与旋转
  • 方块与墙壁或其他方块的碰撞检测
  • 完整行的消除
  • 计分功能
  • 游戏结束时显示分数

小结

这个教程展示了如何使用pygame库来实现一个简单的俄罗斯方块游戏。你可以在此基础上进行扩展和优化,例如添加更丰富的图形效果、音效和菜单界面等。


网站公告

今日签到

点亮在社区的每一天
去签到