领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

用 Python 和 Pygame 实现一个图形界面的俄罗斯方块小游戏

nixiaole 2025-01-02 18:14:16 知识剖析 17 ℃

俄罗斯方块(Tetris)是一款经典的益智类游戏,玩家需要将下落的方块堆积成完整的行,从而获得积分。今天,我们将使用 Python 和 Pygame 库来开发一个俄罗斯方块小游戏,并通过这篇文章详细介绍如何编写这个游戏。

1. 了解 Pygame 和游戏开发

Pygame 是一个简单易用的 Python 游戏开发库,它提供了开发 2D 游戏所需的工具。使用 Pygame 可以方便地处理图形、声音和事件响应,非常适合入门级的游戏开发。

在开始之前,确保你的系统上已经安装了 Pygame。如果没有,可以使用以下命令来安装:

pip install pygame

2. 游戏设计分析

俄罗斯方块的核心玩法简单,但其实现涉及多个方面的逻辑,包括:

  • 方块的生成、移动和旋转;
  • 网格的绘制和方块放置;
  • 检测是否形成完整的行并清除;
  • 游戏结束的判断;
  • 简单的用户交互(键盘控制)。

我们将从这些基础部分出发,逐步构建游戏。

3. 创建游戏窗口

首先,我们需要创建一个基本的游戏窗口。这是所有图形界面程序的核心。在 Pygame 中,可以通过 pygame.display.set_mode() 来设置窗口的尺寸,并使用 pygame.display.set_caption() 来定义窗口标题。

import pygame
import random

# 初始化Pygame
pygame.init()

# 定义窗口的宽高
SCREEN_WIDTH = 300
SCREEN_HEIGHT = 600
BLOCK_SIZE = 30

# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('俄罗斯方块')

上面的代码中,我们设置了一个 300x600 像素的游戏窗口,方块的大小为 30x30 像素。游戏中的每一个方块都将在这个网格中移动和堆积。

4. 定义方块形状

俄罗斯方块由七种形状组成,每种形状对应一个由 4 个小方块组成的几何结构。为了方便管理方块的形状和颜色,我们可以定义一个 SHAPES 列表来存储这些形状,并使用不同的颜色进行区分。

# 定义颜色
CYAN = (0, 255, 255)
YELLOW = (255, 255, 0)
PURPLE = (128, 0, 128)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
ORANGE = (255, 165, 0)
BLUE = (0, 0, 255)

# 俄罗斯方块的形状
SHAPES = [
    [[1, 1, 1, 1]],  # I形
    [[1, 1], [1, 1]],  # O形
    [[0, 1, 0], [1, 1, 1]],  # T形
    [[1, 1, 0], [0, 1, 1]],  # Z形
    [[0, 1, 1], [1, 1, 0]],  # S形
    [[1, 1, 1], [1, 0, 0]],  # L形
    [[1, 1, 1], [0, 0, 1]],  # 反L形
]

# 对应颜色
SHAPE_COLORS = [CYAN, YELLOW, PURPLE, RED, GREEN, ORANGE, BLUE]

每种形状是一个二维列表,其中的 1 表示该位置有方块,0 表示该位置为空。不同的形状会以不同颜色显示,增加视觉效果。

5. 设计方块类

我们将使用一个类 Tetrimino 来表示每一个俄罗斯方块。这个类需要包含方块的形状、颜色、位置以及旋转的逻辑。

# 定义方块类
class Tetrimino:
    def __init__(self, shape):
        self.shape = shape
        self.color = random.choice(SHAPE_COLORS)  # 随机选择一种颜色
        self.x = 5  # 方块水平位置
        self.y = 0  # 方块垂直位置
        self.rotation = 0  # 当前旋转角度

    def rotate(self):
        # 旋转方块
        self.rotation = (self.rotation + 1) % len(self.shape)

在这个类中,我们定义了方块的 x 和 y 来表示其在网格中的位置,rotation 用来管理方块的旋转。旋转时,方块的形状会从 self.shape 列表中按顺序取出。

6. 创建游戏网格

接下来,我们需要生成游戏的网格。网格用于存放已经落下的方块以及新的方块位置。可以使用一个二维列表来表示网格。

# 创建游戏网格
def create_grid(locked_positions={}):
    grid = [[(0, 0, 0) for _ in range(10)] for _ in range(20)]  # 20行10列的网格
    
    # 将锁定的方块填入网格
    for (x, y), color in locked_positions.items():
        grid[y][x] = color
    
    return grid

网格的每个元素都是一个 RGB 颜色值,表示当前该位置的颜色。如果某个位置为空,则为黑色 (0, 0, 0)。

7. 方块的移动和检测

为了让方块能够在网格中自由移动,我们需要编写检测逻辑,判断当前方块是否可以移动到目标位置。如果目标位置被其他方块占据或越过边界,则不能移动。

# 检查方块是否可以移动
def valid_space(shape, grid):
    accepted_positions = [[(j, i) for j in range(10) if grid[i][j] == (0, 0, 0)] for i in range(20)]
    accepted_positions = [j for sub in accepted_positions for j in sub]

    formatted = convert_shape_format(shape)

    for pos in formatted:
        if pos not in accepted_positions:
            if pos[1] > -1:
                return False
    return True

8. 让方块下落

我们可以通过主循环控制方块的下落速度,并监听玩家的键盘输入,控制方块的左右移动和旋转。

# 主循环
def main():
    locked_positions = {}
    grid = create_grid(locked_positions)
    current_piece = Tetrimino(random.choice(SHAPES))
    next_piece = Tetrimino(random.choice(SHAPES))
    clock = pygame.time.Clock()
    fall_time = 0

    run = True
    while run:
        grid = create_grid(locked_positions)
        fall_speed = 0.27
        fall_time += clock.get_rawtime()
        clock.tick()

        # 方块自动下落
        if fall_time / 1000 >= fall_speed:
            fall_time = 0
            current_piece.y += 1
            if not valid_space(current_piece, grid):
                current_piece.y -= 1
                locked_positions.update({(x, y): current_piece.color for x, y in convert_shape_format(current_piece)})
                current_piece = next_piece
                next_piece = Tetrimino(random.choice(SHAPES))

        # 监听键盘输入
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    current_piece.x -= 1
                    if not valid_space(current_piece, grid):
                        current_piece.x += 1
                elif event.key == pygame.K_RIGHT:
                    current_piece.x += 1
                    if not valid_space(current_piece, grid):
                        current_piece.x -= 1
                elif event.key == pygame.K_DOWN:
                    current_piece.y += 1
                    if not valid_space(current_piece, grid):
                        current_piece.y -= 1
                elif event.key == pygame.K_UP:
                    current_piece.rotate()
                    if not valid_space(current_piece, grid):
                        current_piece.rotate()

        draw_window(screen, grid)
        pygame.display.update()

    pygame.quit()

9. 总结

在这篇文章中,我们使用 Python 和 Pygame 实现了一个基础的俄罗斯方块游戏。这个项目涵盖了方块的生成、移动、旋转、网格的绘制以及行消除等核心功能。通过这样的小游戏开发,不仅能够加深对游戏逻辑的理解,还能提升 Python 编程技能。

这个游戏可以继续扩展,比如加入得分系统、不同难度的下落速度、声音效果等。你可以根据自己的需求和喜好,进一步优化游戏体验。

最近发表
标签列表