1. 前言
迷宫游戏是最经典的 2D 游戏类型之一:在一个由墙壁和通道构成的地图里,玩家需要绕过障碍、寻找通路,最终抵达出口。它不但简单易实现,又兼具可玩性,还能在此基础上添加怪物、道具、机关等元素。本篇文章将展示如何在 Pygame 环境下,从零开始开发一个简易版的“迷宫游戏”。
2. 开发环境
- Python 3.x
- Pygame 库:若尚未安装,可使用
pip install pygame
- 桌面操作系统:Windows、macOS 或大多数 Linux。
在确保 import pygame
没有报错后,即可开始项目编写。
3. 设计思路
-
迷宫地图
- 使用一个二维列表(二维数组)来表示迷宫。
- 不同数字代表不同的地形或功能:
0
表示可通行的地面;1
表示墙壁,玩家无法进入;2
表示出口,玩家走到此处表示胜利。
- 也可以定义更多类型(比如
3
表示钥匙或道具),在本示例中暂不扩展。
-
地图渲染
- 将迷宫的行列绘制成网格:每个格子用一定大小(如 40×40 像素)的矩形来表示;
- 不同类型的格子绘制不同的颜色或贴图。
-
玩家
- 记录玩家在迷宫网格中的坐标(例如
(row, col)
); - 通过方向键(上下左右)控制移动,每次移动到相邻格子;
- 如果下一个格子是墙壁,则无法移动;如果是通道则可进入;如果是出口,则触发胜利。
- 记录玩家在迷宫网格中的坐标(例如
-
胜利判定
- 当玩家坐标到达一个带有
2
的格子,表示找到迷宫出口; - 游戏停止或弹出“通关”提示。
- 当玩家坐标到达一个带有
-
扩展
- 在迷宫中添加钥匙、门、怪物、道具等机制;
- 实现自动生成迷宫算法、AI 寻路、计时器、排行榜等增强功能。
4. 完整示例代码
将以下示例保存为 maze_game.py
并运行。你可以在里面更改地图的大小、布局、颜色等,实现更多个性化。
import pygame
import sys# 初始化 Pygame
pygame.init()# -----------------------------
# 全局配置
# -----------------------------
TILE_SIZE = 40 # 每个方格的像素大小
FPS = 30# 颜色定义 (R, G, B)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (128, 128, 128)
GREEN = (0, 200, 0)
BLUE = (0, 0, 255)
BROWN = (139, 69, 19)# 迷宫地图:0-通道,1-墙壁,2-出口
# 你可自由调整此二维列表,打造不同迷宫关卡
MAZE_MAP = [[1,1,1,1,1,1,1,1,1,1],[1,0,0,0,1,0,0,0,0,1],[1,0,1,0,0,0,1,1,0,1],[1,0,1,0,1,0,1,0,0,1],[1,0,0,0,1,0,0,0,1,1],[1,1,1,0,1,1,1,0,1,1],[1,0,1,0,0,0,0,0,0,1],[1,0,1,1,1,1,1,1,0,1],[1,0,0,0,0,0,2,0,0,1],[1,1,1,1,1,1,1,1,1,1]
]ROWS = len(MAZE_MAP)
COLS = len(MAZE_MAP[0])# 创建窗口
SCREEN_WIDTH = COLS * TILE_SIZE
SCREEN_HEIGHT = ROWS * TILE_SIZE
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("迷宫游戏 - Pygame 示例")clock = pygame.time.Clock()
font = pygame.font.SysFont("arial", 32)# -----------------------------
# 玩家类
# -----------------------------
class Player:def __init__(self, start_row, start_col):self.row = start_rowself.col = start_coldef move(self, dr, dc):"""尝试移动玩家:dr, dc分别表示行和列方向上的位移(-1, 0, +1)若下一格是墙壁,则无法移动"""new_row = self.row + drnew_col = self.col + dcif 0 <= new_row < ROWS and 0 <= new_col < COLS:if MAZE_MAP[new_row][new_col] != 1: # 不是墙壁就能走self.row = new_rowself.col = new_col@propertydef x(self):return self.col * TILE_SIZE@propertydef y(self):return self.row * TILE_SIZE# -----------------------------
# 主游戏函数
# -----------------------------
def main():# 初始化玩家位置:假设从 (1,1) 出发 (也可根据地图自定义)player = Player(1, 1)running = Truegame_won = False # 是否已通关while running:clock.tick(FPS)for event in pygame.event.get():if event.type == pygame.QUIT:running = False# 键盘输入 (上下左右)keys = pygame.key.get_pressed()if keys[pygame.K_UP]:player.move(-1, 0)elif keys[pygame.K_DOWN]:player.move(1, 0)elif keys[pygame.K_LEFT]:player.move(0, -1)elif keys[pygame.K_RIGHT]:player.move(0, 1)# 检测是否到达出口if MAZE_MAP[player.row][player.col] == 2:game_won = Truerunning = False# 绘制场景screen.fill(BLACK)# 绘制迷宫for r in range(ROWS):for c in range(COLS):tile_type = MAZE_MAP[r][c]x = c * TILE_SIZEy = r * TILE_SIZEif tile_type == 1:# 墙壁pygame.draw.rect(screen, BROWN, (x, y, TILE_SIZE, TILE_SIZE))elif tile_type == 2:# 出口pygame.draw.rect(screen, BLUE, (x, y, TILE_SIZE, TILE_SIZE))else:# 通道pygame.draw.rect(screen, GRAY, (x, y, TILE_SIZE, TILE_SIZE))# 绘制玩家(用绿色方块表示)pygame.draw.rect(screen, GREEN, (player.x, player.y, TILE_SIZE, TILE_SIZE))pygame.display.flip()# 游戏结束,显示结果game_over(game_won)def game_over(won):screen.fill(BLACK)if won:msg = "恭喜通关!"else:msg = "游戏已退出"label = font.render(msg, True, WHITE)rect = label.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))screen.blit(label, rect)pygame.display.flip()pygame.time.wait(2000)pygame.quit()sys.exit()if __name__ == "__main__":main()
主要逻辑解析
-
迷宫地图(MAZE_MAP)
- 使用一个二维列表来存储迷宫。示例中尺寸为 10×10(行列),但你可以随意扩展或修改布局。
0
表示地面可通行,1
表示墙壁不可通行,2
表示出口。
-
Player(玩家)
- 内部存储玩家在迷宫中的
(row, col)
网格坐标; move(dr, dc)
用来尝试移动到相邻格子,若是墙壁则拒绝移动。- 通过属性
x
、y
将网格坐标转为像素坐标,用于在屏幕上绘制。
- 内部存储玩家在迷宫中的
-
游戏循环
- 处理键盘方向输入,调用
player.move(dr, dc)
; - 每帧绘制整个迷宫和玩家;
- 若玩家到达
2
(出口),标记为game_won
并跳出循环。
- 处理键盘方向输入,调用
-
结束界面
- 在主循环结束后,根据
won
参数在屏幕中央显示文字,延时两秒再退出。
- 在主循环结束后,根据
5. 运行效果
6. 总结
本篇示例通过一个二维数组简单地呈现了“迷宫”的概念,让玩家在 Pygame 中上下左右移动,并找到出口来取得胜利。
迷宫游戏的难度与趣味可以通过地图规模与多种机制进一步提升:加上自动生成、怪物巡逻、钥匙门逻辑等,都能让该项目成为一个富有挑战性又无限可扩展的小作品。希望本文能帮助你掌握网格地图及碰撞检测的思路,并在游戏开发的道路上越走越远!