生成迷宫(maze)的算法有很多种,论坛上有很多这方面的资料可以参考。  这里使用回溯法(backtracking),主要参考Build a 2-player maze game with Python Part 4 - Coding TidBits

用的是迭代函数(recursive function): 不断寻找周边没有走过的网格(cell), 并随机打通任一边的”墙(wall)".  如果设定SHOW_DRAW = True的话, 可以图像显示整个回溯法过程。 迷宫生成结束后, 图像显示, 并加上一个红球代表玩家, 红球可以走过整个迷宫, 玩法方面, 可以计算红球通过整个迷宫的时间。迷宫的复杂程度可以通过设定其行和列数, 如MAZE_COLS=15, MAZE_ROWS=13

全部代码如下:

import random
import pygame
import numpy as np

#Ref;http://www.danduda.com/blog/2018/11/18/Build-a-2-player-maze-game-with-Python-Part-4/
UP,DOWN=-1,1
LEFT,RIGHT=-2,2

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

MAZE_COLS=15
MAZE_ROWS=13
WALL_SIZE = int(120/max(MAZE_COLS,MAZE_ROWS))  # Pixel size/Wall thickness
WT=WALL_SIZE #used in pygame.time.wait(WT)
CELL_SIZE=4*WALL_SIZE #a cell has only 2 walls: DOWN, RIGHT
MAZE_WIDTH =CELL_SIZE * MAZE_COLS +WALL_SIZE  
MAZE_HEIGHT = CELL_SIZE *MAZE_ROWS+ WALL_SIZE

TOPLEFT_X,TOPLEFT_Y = (SCREEN_WIDTH // 2 - MAZE_WIDTH // 2, SCREEN_HEIGHT // 2 - MAZE_HEIGHT // 2)
x_offset = TOPLEFT_X + WALL_SIZE
y_offset = TOPLEFT_Y + WALL_SIZE

WALL_COLOR = (18, 94, 32)
MAZE_COLOR = (255, 255, 255)
UNVISITED_COLOR = (0, 0, 0)
PLAYER_COLOR = (255, 0, 0)

SHOW_DRAW = True

class Cell():
    def __init__(self,r,c):
        self.r=r
        self.c=c
        self.visited=False    #True-just visited, not open any wall
        self.walls={UP:False,DOWN:False,LEFT:False,RIGHT:False}
 
class Maze():
    def __init__(self,row=MAZE_ROWS,col=MAZE_COLS):
        self.row=row
        self.col=col
        self.maze= [[Cell(r,c) for c in range(col)] for r in range(row)]
        self.make()       
        self.player= Player(PLAYER_COLOR, (WALL_SIZE * 3) // 2 )                                     
        self.player_sprite = pygame.sprite.RenderPlain(self.player)                    
    def make(self,r0=0,c0=0):    
        direction = {UP: (-1, 0),DOWN: (1, 0),LEFT:(0, -1),RIGHT:(0, 1)}
        current_cell=self.maze[r0][c0]        
        current_cell.visited=True 
        visited_stack=[current_cell]        
        while visited_stack:
            current_cell=visited_stack[-1]  
            un_visited=[]   #unvisited neighbours
            for d, (dr, dc) in direction.items():
                r, c = current_cell.r + dr, current_cell.c + dc
                if (0 <= r < self.row) and (0 <= c < self.col):
                    cell = self.maze[r][c]
                    if not cell.visited:   
                        un_visited.append((d,cell))                     
            if un_visited:                              
                dc,nc=random.choice(un_visited)
                current_cell.walls[dc]=True  #this direction is open
                nc.visited=True
                nc.walls[-dc]=True  
                visited_stack.append(nc)           
            elif len(visited_stack):
                visited_stack.pop()
                
            if SHOW_DRAW:
                self.draw_maze()
                pygame.display.update()
                pygame.time.wait(WT)
                pygame.event.pump()       
              
        #self.maze[0][0].walls[LEFT]=True
        #self.maze[self.row-1][self.col-1].walls[RIGHT] = True 
     
    def draw_maze(self):        
        screen.fill('black')
        pygame.draw.rect(screen, WALL_COLOR, (TOPLEFT_X, TOPLEFT_Y, MAZE_WIDTH, MAZE_HEIGHT))                                        
        for c in range(MAZE_COLS):      #colums 5 x-c
            for r in range(MAZE_ROWS):  # rows 3 y-r
                cell=self.maze[r][c]    
                x=c*CELL_SIZE+ x_offset
                y=r*CELL_SIZE + y_offset
                if cell.visited:                    
                     pygame.draw.rect(screen, MAZE_COLOR, (x, y,3*WALL_SIZE, 3*WALL_SIZE))                                           
                else:                             
                     pygame.draw.rect(screen, UNVISITED_COLOR,(x, y,3*WALL_SIZE, 3*WALL_SIZE)) 
                if cell.walls[DOWN]:
                     pygame.draw.rect(screen, MAZE_COLOR, (x, y+3*WALL_SIZE ,3*WALL_SIZE, WALL_SIZE))                         
                if cell.walls[RIGHT]:
                     pygame.draw.rect(screen, MAZE_COLOR, (x+3*WALL_SIZE, y, WALL_SIZE, 3*WALL_SIZE))
                                 
                                
            
    def can_move(self, direction):
        c=self.player.c
        r=self.player.r
        return self.maze[r][c].walls[direction]        
    def move_up(self):
        if self.can_move(UP):
            self.player.r-=1
    def move_right(self):
        if self.can_move(RIGHT):
            self.player.c+=1
    def move_down(self):
        if self.can_move(DOWN):
            self.player.r+=1
    def move_left(self):
        if self.can_move(LEFT): 
            self.player.c-=1    
 
    def checkEvents(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()   
            keys = pygame.key.get_pressed()
            if keys[pygame.K_LEFT]:
                self.move_left()
            if keys[pygame.K_RIGHT]:
                self.move_right()
            if keys[pygame.K_UP]:
                self.move_up()
            if keys[pygame.K_DOWN]:
                self.move_down()                
    def update(self):
        self.draw_maze()     
        #self.draw_grid()
        self.player.update()
        self.player_sprite.draw(screen)

class Player(pygame.sprite.Sprite):
    def __init__(self, color, radius, r=0, c=0):
        # Call the parent class (Sprite) constructor
        super().__init__()
        self.r = r
        self.c = c
        self.image = pygame.Surface([radius * 2, radius * 2])
        self.image.fill(MAZE_COLOR)
        self.image.set_colorkey(MAZE_COLOR)
        pygame.draw.circle(self.image, color, (radius, radius), radius)                  
        self.rect = self.image.get_rect()
        self.update() 
    def update(self):
        self.rect.x = x_offset+self.c*CELL_SIZE
        self.rect.y = y_offset+self.r*CELL_SIZE
            
pygame.init()
screen=pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
A=Maze()
while 1:
    screen.fill((0,0,0))
    A.checkEvents()
    A.update()
    pygame.display.update()

python pygame 游戏实战:Maze 迷宫生成,显示和游戏(附全部代码)相关推荐

  1. SinGAN一张照片即可生成同样的照片(附简化版代码)

    1.摘要 本文主要讲解:SinGAN-一张照片即可生成一模一样的照片(附简化版代码) 主要思路: 先由一个Z_N输入到G_N的生成器得到生成图像(这一步是单纯由噪声生成,其他生成器的输入都是由随机噪声 ...

  2. Python教学 | Python 中的分支结构(判断语句)【附本文代码和数据】

    查看原文:[数据seminar]Python教学 | Python 中的分支结构(判断语句)[附本文代码和数据] Part1引言 上期文章我们学习了组合数据类型字典以及元组,这标志着 Python 基 ...

  3. Python:制作一个模拟扔硬币的程序(附完整代码)

    Python:制作一个模拟扔硬币的程序(附完整代码) 在这个项目中,我们将编写一个Python程序来模拟扔硬币的方式.我们会使用Python内置的随机模块,实现随机出现正面或反面的效果. 首先,我们需 ...

  4. Maze_AI: 一款基于 Python + Pygame + AI 算法的迷宫小游戏

    (一)课题内容 实现走迷宫. 主要功能为界面显示.上下左右键的响应以及当前步数统计. 通过该课题全面熟悉数组.字符串等的使用,掌握程序设计的基本方法及友好界面的设计. (二)课题要求 1. 基本要求 ...

  5. PYTHON pygame库实战——实现双人弹球小游戏

    PYTHON pygame实战--运用pygame库实现双人弹球小游戏 使用python pygame库实现一个双人弹球小游戏,两人分别控制一个左右移动的挡板用来拦截小球,小球会在两板间不停弹跳,拦截 ...

  6. Python不能做游戏?游戏实战之-----《ink spill》(附游戏完整源码)

    嗨喽-小伙伴们,大家早上好,中午好,晚上好呀, 通过前两章对Pygame的学习,我们了解了它的基本使用,附上链接: 1. Python不能做游戏?一小时做出一个游戏! 2. Python不能做游戏?P ...

  7. 跟着BOY学习开发cocos2d-x 游戏 实战篇(4)之 游戏主界面 -----怪物系统---赌徒来袭

    兄弟们相比等这一章 等的时间比较长了吧!呵呵这几天公司的事情比较忙每天都只有晚上回来写会.所以进度慢了,不过兄弟们放心 我会坚持把这个游戏写完的写成一个可以买的游戏!哈哈 吹下牛了 其实在开发游戏的过 ...

  8. Python回归预测建模实战-随机梯度下降法预测房价(附源码和实现效果)

    机器学习在预测方面的应用,根据预测值变量的类型可以分为分类问题(预测值是离散型)和回归问题(预测值是连续型),前面我们介绍了机器学习建模处理了分类问题(具体见之前的文章),接下来我们以波斯顿房价数据集 ...

  9. 【UE4 RTS游戏】07-控件蓝图显示当前游戏时间

    效果 步骤 新建一个文件夹,命名为"Interfaces",在该文件夹内新建一个蓝图接口,命名为"I_HUD" 打开"Interfaces" ...

  10. 跟着BOY学习开发cocos2d-x 游戏 实战篇(6)之 游戏主界面 -----绚丽的魔法特效

    在开始这一章之前我先说一个问题 ,最近群里的朋友问我,环境怎么配置我想说请看我的第一章的简介,一定要仔细看,还有那些只为把项目运行起来根本就不看代码的直接问问题 .一定要好好的看下代码,你可以按照自己 ...

最新文章

  1. 申万一级行业日指数_申万一级行业指数一周表现
  2. %d 跟%i 的区别以及scanf和sscanf的用法
  3. 02-图像的几何变换
  4. python取出字典中最大值_python找出字典中value最大值的几种方法
  5. python补集运算_Python 的集合(set)运算
  6. Java写一个简单的扫雷游戏
  7. Java 1.1.3 修改字符串、不可变字符串
  8. ubuntu crontab 不执行的解决方法
  9. 第05课 Linux命令初探(一)
  10. 分布式存储系统学习笔记(三)—分布式键值系统(2)—淘宝Tair
  11. Android基础学习一(整理,从零开始)
  12. 匿名管道 与 命名管道
  13. STM32 标准外设库(STM32F107)
  14. 小红花代表什么_《送你一朵小红花》:细品后才知道,结尾处的平行世界代表着什么...
  15. [重庆思庄每日技术分享]-数据库创建组件时报错ORA-30554: XDB.XDB$ACL_XIDX is disabled
  16. java解决windows下文件没有Everyone以及完全控制的权限问题
  17. java代码桥梁收费站_高速公路收费站演讲稿(精简版).doc
  18. U盘图标显示成文件夹图标
  19. socket本地通信
  20. 顾问风采 | LF AI Data 基金会完成换届,堵俊平担任董事会主席、星爵担任会员总代表...

热门文章

  1. MongoDB概念集合
  2. 网页截图服务器,命令行下的2款网页截图工具推荐
  3. pdf关键字高亮 java_Java 查找、高亮PDF文本
  4. mysql 数据库内存不足_MySQL数据库内存不足怎么办 MySQL数据库使用教程
  5. Redhat 9.0之xtt+xft2,可显示粗斜体美化总结(第二版)
  6. Qualcomm工具
  7. 主页被修改成httpwww.yy4000.cn等类似首页,无法更改,怎么办?
  8. 记录一次keil调试过程:自动识别GPS厂家芯片
  9. miracl实现sm2
  10. SYN包与SYN攻击原理