迷宫的逻辑很简单,就是用上下左右键控制方块运动,然后定义一下墙壁,指明方块不能穿过墙壁即可。
当然,还是老规矩,在具体实现之前,先设置一些常量
import pygame
import sys
# 定义颜色
GRAY = (205, 205, 205)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
SIZE = 40
接下来设置一个按键字典,用于控制方块运动
KEY_DCT = {
pygame.K_LEFT : [-1, 0],
pygame.K_RIGHT : [1, 0],
pygame.K_UP : [0, -1],
pygame.K_DOWN : [0, 1]
}
以左键为例,当左键按左时,方块的纵坐标不变,而横坐标减去1,顾对应 ( − 1 , 0 ) (-1,0) (−1,0)。
考虑到更好的自定义迷宫的支持,采用字符列表作为迷宫的映射,以#, I, O分别表示墙壁、玩家位置以及出口位置。从而上面的迷宫可表示如下
maze = [
"############",
"#I # #",
"# ## ### #",
"# # #",
"# # #### #",
"# ## #",
"# ### # # #",
"# ## # #",
"# # # # #",
"## # ## #",
"# # #O# ###",
"############"
]
maze = [list(m) for m in maze]
之所以采用嵌套的字符列表,乃因字符串不支持类似s[1]=2这种操作。
接下来要做的,就是定义一个绘图函数,可以将迷宫和玩家统一绘制出来,实现如下。如果后续有升级的需求,在迷宫中放置一些不明物体,从而需要的字符种类更多,那么可以考虑将绘图逻辑封装成字典。
# 绘制迷宫地图
def init(strLst = maze):
# 第i行,第j列
for i,s in enumerate(strLst):
for j,ch in enumerate(s):
if ch not in "#IO":
continue
rect = (j*SIZE, i*SIZE, SIZE, SIZE)
if ch == "#":
pygame.draw.rect(win, GRAY, rect,5)
elif ch == "I":
player = [j, i]
pygame.draw.rect(win, RED, rect)
elif ch == "O":
pExit = [j, i]
pygame.draw.rect(win, GREEN, rect)
return player, pExit
在实现主循环之前,需要对pygame进行初始化,包括初始化窗口等
# 初始化pygame
pygame.init()
win = pygame.display.set_mode(
(len(maze[0]) * SIZE, len(maze) * SIZE))
pygame.display.set_caption("迷宫游戏")
running = True
其中,running为游戏结束的判定变量,其主循环内容如下
while running:
win.fill(WHITE)
player, pExit = init(maze)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key not in KEY_DCT:
continue
i, j = player
di, dj = KEY_DCT[event.key]
ni, nj = i+di, j+dj
if maze[nj][ni] != "#":
player = [ni, nj]
maze[j][i] = " "
maze[nj][ni] = "I"
# 判断玩家是否到达出口
if player == pExit:
print("恭喜你,成功通过迷宫!")
running = False
pygame.display.update()