前两篇文章,我们使用Prim算法生成了文章,这一次,我们要用Pygame将迷宫的完整生成过程可视化
首先导入模块,这里我们要用到pygame,随机库,sys,time用于减缓速度,threading用于生成迷宫的另一个线程
- import pygame
- from pygame.locals import *
- import random as rd
- import sys
- import time
- import threading
我们用类和对象的形式实现,定义Game类,初始化函数中设置窗口,a和b表示迷宫大小,lineWidth是迷宫墙壁画在窗口中的粗细,创建一个线程,指向createMaze(createMaze的代码下方会补充),然后启动线程
- class Game:
- def __init__(self):
- pygame.init()
- self.W,self.H=900,900
- self.screen=pygame.display.set_mode((self.W,self.H))
-
- self.a,self.b=28,39
- self.lineWidth=5
- thread=threading.Thread(target=self.createMaze,args=(self.a,self.b))
- thread.start()
创建listen函数,用于监听事件
- def listen(self):
- for event in pygame.event.get():
- if event.type==QUIT:
- sys.exit()
接下来是创建迷宫的代码,在上一篇遍历墙生成迷宫的时候,我们已经将代码完整写出来了,只要修改一小部分内容即可,要修改的地方如下:
在函数参数中添加self
def createMaze(self,a,b):
然后,把函数中的maze全部改为self.maze,直接存入类变量中
这里不再展示代码,需要算法代码的可以查看我的上一篇文章:
Python Prim 算法 生成迷宫_Leleprogrammer的博客-CSDN博客Python Prim算法 通过遍历墙来生成迷宫,快来看看吧!https://blog.csdn.net/leleprogrammer/article/details/125472436?spm=1001.2014.3001.5501或者是在文末的最终代码中复制,要学习算法原理的,查看上一篇文章即可
接下来,draw函数,用于绘制迷宫,这里代码不会太难,就不做太多讲解
- def draw(self):
- self.screen.fill((255,255,255))
- for (n,face),is_wall in self.maze.items():
- if is_wall:
- y=n//self.a
- x=n%self.a
- absX=x*self.width
- absY=y*self.height
- if face=="u":
- pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX+self.width,absY),self.lineWidth)
- if face=="d":
- pygame.draw.line(self.screen,(0,0,0),(absX,absY+self.height),(absX+self.width,absY+self.height),self.lineWidth)
- if face=="l":
- pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX,absY+self.height),self.lineWidth)
- if face=="r":
- pygame.draw.line(self.screen,(0,0,0),(absX+self.width,absY),(absX+self.width,absY+self.height),self.lineWidth)
然后是run函数,主循环
- def run(self):
- while True:
- self.listen()
- self.draw()
- self.refreshWindow()
- pygame.display.update()
用于显示文字的函数,这里没有用到,可以不加上,这里加上去是为了后续利用此框架编写游戏,这里还是把这个显示文字的函数给大家
- @staticmethod
- def print_text(name,size,text,color):
- font=pygame.font.SysFont(name,size)
- image=font.render(text,True,color)
- return image
最后,添加这段启动的代码
- if __name__ == '__main__':
- game=Game()
- game.run()
这样就好啦!
最终代码(可供参考)
- import pygame
- from pygame.locals import *
- import random as rd
- import sys
- import time
- import threading
-
- class Game:
- def __init__(self):
- pygame.init()
- self.W,self.H=900,900
- self.screen=pygame.display.set_mode((self.W,self.H))
- pygame.display.set_caption("Find the Way")
-
- self.a,self.b=28,39
- self.lineWidth=5
- thread=threading.Thread(target=self.createMaze,args=(self.a,self.b))
- thread.start()
-
- def listen(self):
- for event in pygame.event.get():
- if event.type==QUIT:
- sys.exit()
-
- def createMaze(self,a,b):
- self.maze={}
- for n in range(a*b):
- for face in ["u","d","l","r"]:
- self.maze[(n,face)]=1
- history=[]
- walls=[]
- block=rd.choice(list(self.maze.keys()))[0]
- history.append(block)
- for face in ["u","d","l","r"]:
- walls.append((block,face))
- while len(walls)!=0:
- time.sleep(0.001)
- wall=rd.choice(walls)
- twoBlocks=[wall[0]]
- faces=[wall[1]]
- if wall[1]=="u":
- if wall[0]-a<0:
- twoBlocks.append(None)
- else:
- twoBlocks.append(wall[0]-a)
- faces.append("d")
- elif wall[1]=="r":
- if (wall[0]+1)%a!=0:
- twoBlocks.append(wall[0]+1)
- faces.append("l")
- else:
- twoBlocks.append(None)
- elif wall[1]=="l":
- if wall[0]%a!=0:
- twoBlocks.append(wall[0]-1)
- faces.append("r")
- else:
- twoBlocks.append(None)
- elif wall[1]=="d":
- if wall[0]+a>len(self.maze)/4-1:
- twoBlocks.append(None)
- else:
- twoBlocks.append(wall[0]+a)
- faces.append("u")
- ins=[]
- infaces=[]
- for i,oneBlock in enumerate(twoBlocks):
- if oneBlock in history:
- ins.append(oneBlock)
- infaces.append(faces[i])
- if len(ins)==1:
- mirrorFace=None
- if infaces[0]=="u":
- mirrorFace="d"
- elif infaces[0]=="d":
- mirrorFace="u"
- elif infaces[0]=="r":
- mirrorFace="l"
- elif infaces[0]=="l":
- mirrorFace="r"
- if not (None in twoBlocks):
- self.maze[(ins[0],infaces[0])]=0
- other=None
- if ins[0]==twoBlocks[0]:
- other=twoBlocks[1]
- else:
- other=twoBlocks[0]
- self.maze[(other,mirrorFace)]=0
- walls.remove(wall)
- history.append(other)
- for face in ["u","l","r","d"]:
- if self.maze.get((other,face))==1 and not ((other,face) in walls):
- walls.append((other,face))
- else:
- walls.remove(wall)
- continue
- elif len(ins)==2:
- walls.remove(wall)
-
- def draw(self):
- self.screen.fill((255,255,255))
- for (n,face),is_wall in self.maze.items():
- if is_wall:
- y=n//self.a
- x=n%self.a
- absX=x*self.width
- absY=y*self.height
- if face=="u":
- pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX+self.width,absY),self.lineWidth)
- if face=="d":
- pygame.draw.line(self.screen,(0,0,0),(absX,absY+self.height),(absX+self.width,absY+self.height),self.lineWidth)
- if face=="l":
- pygame.draw.line(self.screen,(0,0,0),(absX,absY),(absX,absY+self.height),self.lineWidth)
- if face=="r":
- pygame.draw.line(self.screen,(0,0,0),(absX+self.width,absY),(absX+self.width,absY+self.height),self.lineWidth)
-
- def run(self):
- while True:
- self.listen()
- self.draw()
- self.refreshWindow()
- pygame.display.update()
-
- if __name__ == '__main__':
- game=Game()
- game.run()
本次的教学到这里也就结束啦!喜欢我的文章的,别忘了多多点赞关注支持哦!谢谢~