这份迷宫游戏的完整可运行代码(已确保无遗漏、可直接执行),以及对应的核心知识点总结,我整理完整代码,再进行详细知识点提炼。
一、完整可运行代码
这份代码在你原有基础上做了微小的健壮性优化,确保直接复制即可运行,无报错:
import pygameimport randomimport sys# 1. 配置(核心:增大迷宫尺寸,提升路线复杂度基础)MAZE_WIDTH = 81# 从21提升到81(奇数,保证通路完整性)MAZE_HEIGHT = 51# 从15提升到51(奇数,增加纵向分支)CELL_SIZE = 15# 适当缩小格子尺寸,避免窗口过大WINDOW_WIDTH = MAZE_WIDTH * CELL_SIZEWINDOW_HEIGHT = MAZE_HEIGHT * CELL_SIZE + 100# 底部留空间放按钮# 颜色(简洁风格,保留原有配置)COLORS = {"bg": (24, 24, 24),"wall": (50, 50, 50),"path": (255, 255, 255),"start": (0, 255, 0),"end": (255, 0, 0),"player": (0, 0, 255),"button": (100, 100, 100),"button_hover": (150, 150, 150),"button_text": (255, 255, 255)}# 初始化pygame.init()screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))pygame.display.set_caption("复杂路线迷宫(按钮控制)")clock = pygame.time.Clock()font = pygame.font.Font(None, 36)# 2. 生成复杂路线迷宫(优化DFS算法,增加分支和迂回路线)defcreate_maze(width, height):""" 优化DFS算法生成复杂路线迷宫: 1. 更大的迷宫尺寸提供更多分支空间 2. 随机打乱方向列表,增加路线随机性 3. 保留更多未访问分支,提升迂回复杂度 """ maze = [[1for _ in range(width)] for _ in range(height)] stack = [] start_x, start_y = 1, 1 maze[start_y][start_x] = 0 stack.append((start_x, start_y))# 基础四个移动方向(每次移动2格,挖通中间墙壁) base_directions = [(0, -2), (0, 2), (-2, 0), (2, 0)]while stack: current_x, current_y = stack[-1] unvisited = []# 关键优化1:每次循环随机打乱方向列表,增加路线不可预测性 shuffled_directions = random.sample(base_directions, len(base_directions))for dx, dy in shuffled_directions: new_x = current_x + dx new_y = current_y + dy# 边界判断:确保新坐标在迷宫范围内,且未被访问(仍为墙壁)if1 <= new_x < width - 1and1 <= new_y < height - 1and maze[new_y][new_x] == 1: unvisited.append((dx, dy))if unvisited:# 关键优化2:随机选择未访问方向,增加分支多样性(核心提升复杂度) dx, dy = random.choice(unvisited) new_x = current_x + dx new_y = current_y + dy# 挖通当前格子到新格子的中间墙壁,形成连续通路 maze[current_y + dy//2][current_x + dx//2] = 0 maze[new_y][new_x] = 0# 将新格子压入栈,继续深度探索,形成更多分支 stack.append((new_x, new_y))else:# 无未访问方向,回溯(弹出栈顶),探索其他分支 stack.pop()# 标记起点和终点(拉开距离,增加探索路径长度) maze[1][1] = 2# 起点(左上角) maze[height-2][width-2] = 3# 终点(右下角)return maze# 3. 绘制迷宫和玩家defdraw_maze(maze, player_pos): screen.fill(COLORS["bg"])for y in range(MAZE_HEIGHT):for x in range(MAZE_WIDTH): rect = pygame.Rect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE)if maze[y][x] == 1: pygame.draw.rect(screen, COLORS["wall"], rect)elif maze[y][x] == 0: pygame.draw.rect(screen, COLORS["path"], rect)elif maze[y][x] == 2: pygame.draw.rect(screen, COLORS["start"], rect)elif maze[y][x] == 3: pygame.draw.rect(screen, COLORS["end"], rect)# 绘制玩家 px, py = player_pos player_rect = pygame.Rect(px*CELL_SIZE, py*CELL_SIZE, CELL_SIZE, CELL_SIZE) pygame.draw.rect(screen, COLORS["player"], player_rect) pygame.draw.rect(screen, (0,0,0), player_rect, 2)# 4. 按钮类(保留原有功能,支持悬浮变色和点击)classButton:def__init__(self, x, y, w, h, text): self.rect = pygame.Rect(x, y, w, h) self.text = textdefdraw(self): color = COLORS["button_hover"] if self.rect.collidepoint(pygame.mouse.get_pos()) else COLORS["button"] pygame.draw.rect(screen, color, self.rect) pygame.draw.rect(screen, (0,0,0), self.rect, 2) text_surf = font.render(self.text, True, COLORS["button_text"]) text_rect = text_surf.get_rect(center=self.rect.center) screen.blit(text_surf, text_rect)defis_clicked(self, event):if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:return self.rect.collidepoint(event.pos)returnFalse# 5. 移动校验(保留原有功能,防止玩家穿墙和越界)defis_valid(maze, x, y):return0 <= x < MAZE_WIDTH and0 <= y < MAZE_HEIGHT and maze[y][x] != 1# 6. 主函数(保留按钮控制和键盘控制)defmain():# 生成复杂路线迷宫 maze = create_maze(MAZE_WIDTH, MAZE_HEIGHT) player_pos = (1, 1)# 创建按钮 btn_w, btn_h = 80, 50 btn_y = MAZE_HEIGHT * CELL_SIZE + 20 btn_up = Button(WINDOW_WIDTH//2 - btn_w//2, btn_y, btn_w, btn_h, "上") btn_down = Button(WINDOW_WIDTH//2 - btn_w//2, btn_y + 60, btn_w, btn_h, "下") btn_left = Button(WINDOW_WIDTH//2 - btn_w - 20, btn_y + 60, btn_w, btn_h, "左") btn_right = Button(WINDOW_WIDTH//2 + 20, btn_y + 60, btn_w, btn_h, "右") buttons = [btn_up, btn_down, btn_left, btn_right] running = Truewhile running: clock.tick(60) # 限制帧率为60FPS,防止画面闪烁for event in pygame.event.get():if event.type == pygame.QUIT: running = False# 按钮点击控制玩家移动if btn_up.is_clicked(event): x, y = player_posif is_valid(maze, x, y-1): player_pos = (x, y-1)if btn_down.is_clicked(event): x, y = player_posif is_valid(maze, x, y+1): player_pos = (x, y+1)if btn_left.is_clicked(event): x, y = player_posif is_valid(maze, x-1, y): player_pos = (x-1, y)if btn_right.is_clicked(event): x, y = player_posif is_valid(maze, x+1, y): player_pos = (x+1, y)# 保留键盘方向键控制if event.type == pygame.KEYDOWN: x, y = player_posif event.key == pygame.K_UP and is_valid(maze, x, y-1): player_pos = (x, y-1)if event.key == pygame.K_DOWN and is_valid(maze, x, y+1): player_pos = (x, y+1)if event.key == pygame.K_LEFT and is_valid(maze, x-1, y): player_pos = (x-1, y)if event.key == pygame.K_RIGHT and is_valid(maze, x+1, y): player_pos = (x+1, y)# 绘制迷宫、玩家和按钮 draw_maze(maze, player_pos)for btn in buttons: btn.draw()# 更新整个屏幕显示 pygame.display.flip()# 退出游戏,释放资源 pygame.quit() sys.exit()if __name__ == "__main__": main()
二、前置运行条件
运行前需要安装pygame库,终端执行以下命令:
pip install pygame
三、核心知识点总结
1. 迷宫生成核心:优化版DFS(深度优先搜索)算法
- 核心思想:“探索-回溯”,利用栈(
stack)存储当前探索路径,先深度挖掘一条路径直到无路可走,再回溯寻找其他未探索分支,最终生成连通的迷宫。
- 迷宫尺寸采用奇数(81、51):保证起点/终点在通路中,且每次移动2格时,中间有可挖通的墙壁,避免通路断裂。
- 随机打乱方向列表(
random.sample):打破固定方向探索的规律性,增加路线不可预测性。 - 随机选择未访问方向:生成更多分支和迂回路线,提升迷宫复杂度,而非单一的“一条路走到黑”。
- 核心操作:每次移动2格,同时将当前格子与新格子中间的墙壁置为0(挖通),形成连续通路。
2. Pygame核心基础用法
- 游戏初始化与窗口创建:
pygame.init() 初始化所有模块,pygame.display.set_mode() 创建游戏窗口,pygame.display.set_caption() 设置窗口标题。 - 游戏主循环:
while running 是游戏的核心循环,负责处理事件、更新逻辑、绘制画面,缺一不可。 - 事件处理:
pygame.event.get() 获取所有事件,处理窗口关闭(pygame.QUIT)、鼠标点击(pygame.MOUSEBUTTONDOWN)、键盘按键(pygame.KEYDOWN)。 - 图形绘制:
pygame.draw.rect() 绘制矩形(迷宫格子、按钮、玩家),screen.blit() 绘制文字表面(按钮上的文字),screen.fill() 清空屏幕(防止画面残留)。 - 帧率控制:
clock.tick(60) 限制帧率为60FPS,避免CPU占用过高,同时保证画面流畅不闪烁。 - 画面更新:
pygame.display.flip() 刷新整个屏幕,将绘制的内容展示给用户。
3. 面向对象基础(Button类)
- 类的定义与实例化:
class Button 定义按钮类,封装按钮的属性(rect 矩形区域、text 按钮文字)和方法(draw 绘制、is_clicked 判断是否被点击)。 - 封装的优势:将按钮的相关逻辑集中在类中,无需重复编写代码,便于后续添加更多按钮(如“重新生成迷宫”),提升代码可维护性。
- 核心功能实现:利用
rect.collidepoint() 判断鼠标是否在按钮区域内,实现按钮悬浮变色和点击判定。
4. 游戏逻辑辅助
- 移动合法性校验(
is_valid函数):防止玩家穿墙(maze[y][x] != 1)和越界(坐标在迷宫宽高范围内),是游戏逻辑的“安全屏障”。 - 坐标映射:将迷宫的格子坐标(x, y)通过
x*CELL_SIZE、y*CELL_SIZE 映射为屏幕像素坐标,实现迷宫在窗口中的正常显示。 - 多控制方式支持:同时支持鼠标按钮点击和键盘方向键控制,提升游戏的易用性。
5. 其他关键细节
- 列表推导式创建迷宫:
[[1 for _ in range(width)] for _ in range(height)] 快速创建二维数组(迷宫),初始值全为1(墙壁)。 - 游戏退出:
pygame.quit() 释放pygame资源,sys.exit() 退出Python程序,保证程序正常终止。