使用Pygame制作“走迷宫”游戏

news2025/2/3 22:38:42

1. 前言

迷宫游戏是最经典的 2D 游戏类型之一:在一个由墙壁和通道构成的地图里,玩家需要绕过障碍、寻找通路,最终抵达出口。它不但简单易实现,又兼具可玩性,还能在此基础上添加怪物、道具、机关等元素。本篇文章将展示如何在 Pygame 环境下,从零开始开发一个简易版的“迷宫游戏”。


2. 开发环境

  1. Python 3.x
  2. Pygame 库:若尚未安装,可使用 pip install pygame
  3. 桌面操作系统:Windows、macOS 或大多数 Linux。

在确保 import pygame 没有报错后,即可开始项目编写。


3. 设计思路

  1. 迷宫地图

    • 使用一个二维列表(二维数组)来表示迷宫。
    • 不同数字代表不同的地形或功能:
      • 0 表示可通行的地面;
      • 1 表示墙壁,玩家无法进入;
      • 2 表示出口,玩家走到此处表示胜利。
    • 也可以定义更多类型(比如 3 表示钥匙或道具),在本示例中暂不扩展。
  2. 地图渲染

    • 将迷宫的行列绘制成网格:每个格子用一定大小(如 40×40 像素)的矩形来表示;
    • 不同类型的格子绘制不同的颜色或贴图。
  3. 玩家

    • 记录玩家在迷宫网格中的坐标(例如 (row, col));
    • 通过方向键(上下左右)控制移动,每次移动到相邻格子;
    • 如果下一个格子是墙壁,则无法移动;如果是通道则可进入;如果是出口,则触发胜利。
  4. 胜利判定

    • 当玩家坐标到达一个带有 2 的格子,表示找到迷宫出口;
    • 游戏停止或弹出“通关”提示。
  5. 扩展

    • 在迷宫中添加钥匙、门、怪物、道具等机制;
    • 实现自动生成迷宫算法、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_row
        self.col = start_col

    def move(self, dr, dc):
        """
        尝试移动玩家:dr, dc分别表示行和列方向上的位移(-1, 0, +1)
        若下一格是墙壁,则无法移动
        """
        new_row = self.row + dr
        new_col = self.col + dc
        if 0 <= new_row < ROWS and 0 <= new_col < COLS:
            if MAZE_MAP[new_row][new_col] != 1:  # 不是墙壁就能走
                self.row = new_row
                self.col = new_col

    @property
    def x(self):
        return self.col * TILE_SIZE

    @property
    def y(self):
        return self.row * TILE_SIZE

# -----------------------------
# 主游戏函数
# -----------------------------
def main():
    # 初始化玩家位置:假设从 (1,1) 出发 (也可根据地图自定义)
    player = Player(1, 1)

    running = True
    game_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 = True
            running = False

        # 绘制场景
        screen.fill(BLACK)

        # 绘制迷宫
        for r in range(ROWS):
            for c in range(COLS):
                tile_type = MAZE_MAP[r][c]
                x = c * TILE_SIZE
                y = r * TILE_SIZE
                if 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()

主要逻辑解析

  1. 迷宫地图(MAZE_MAP)

    • 使用一个二维列表来存储迷宫。示例中尺寸为 10×10(行列),但你可以随意扩展或修改布局。
    • 0 表示地面可通行,1 表示墙壁不可通行,2 表示出口。
  2. Player(玩家)

    • 内部存储玩家在迷宫中的 (row, col) 网格坐标;
    • move(dr, dc) 用来尝试移动到相邻格子,若是墙壁则拒绝移动。
    • 通过属性 xy 将网格坐标转为像素坐标,用于在屏幕上绘制。
  3. 游戏循环

    • 处理键盘方向输入,调用 player.move(dr, dc)
    • 每帧绘制整个迷宫和玩家;
    • 若玩家到达 2(出口),标记为 game_won 并跳出循环。
  4. 结束界面

    • 在主循环结束后,根据 won 参数在屏幕中央显示文字,延时两秒再退出。

5. 运行效果

image.png


6. 总结

本篇示例通过一个二维数组简单地呈现了“迷宫”的概念,让玩家在 Pygame 中上下左右移动,并找到出口来取得胜利。
迷宫游戏的难度与趣味可以通过地图规模多种机制进一步提升:加上自动生成、怪物巡逻、钥匙门逻辑等,都能让该项目成为一个富有挑战性又无限可扩展的小作品。希望本文能帮助你掌握网格地图及碰撞检测的思路,并在游戏开发的道路上越走越远!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2291478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8.攻防世界Web_php_wrong_nginx_config

进入题目页面如下 尝试弱口令密码登录 一直显示网站建设中&#xff0c;尝试无果&#xff0c;查看源码也没有什么特别漏洞存在 用Kali中的dirsearch扫描根目录试试 命令&#xff1a; dirsearch -u http://61.147.171.105:53736/ -e* 登录文件便是刚才登录的界面打开robots.txt…

基于Langchain-Chatchat + ChatGLM 本地部署知识库

一、相关环境 参考链接: Github:https://github.com/chatchat-space/Langchain-Chatchat Langchain-chatchat版本&#xff1a;v0.3.1 安装环境&#xff1a;Ubuntu&#xff1a;22.04&#xff0c;CUDA&#xff1a;12.1 二、搭建过程 2.1 环境配置 2.1.1 创建chatchat虚拟环…

grpc 和 http 的区别---二进制vsJSON编码

gRPC 和 HTTP 是两种广泛使用的通信协议&#xff0c;各自适用于不同的场景。以下是它们的详细对比与优势分析&#xff1a; 一、核心特性对比 特性gRPCHTTP协议基础基于 HTTP/2基于 HTTP/1.1 或 HTTP/2数据格式默认使用 Protobuf&#xff08;二进制&#xff09;通常使用 JSON/…

Cypher入门

文章目录 Cypher入门创建数据查询数据matchoptional matchwhere分页with 更新数据删除数据实例&#xff1a;好友推荐 Cypher入门 Cypher是Neo4j的查询语言。 创建数据 在Neo4j中使用create命令创建节点、关系、属性数据。 create (n {name:$value}) return n //创建节点&am…

深度学习深度解析:从基础到前沿

引言 深度学习作为人工智能的一个重要分支&#xff0c;通过模拟人脑的神经网络结构来进行数据分析和模式识别。它在图像识别、自然语言处理、语音识别等领域取得了显著成果。本文将深入探讨深度学习的基础知识、主要模型架构以及当前的研究热点和发展趋势。 基础概念与数学原理…

如何使用SliverGrid组件

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了SliverList组件相关的内容&#xff0c;本章回中将介绍SliverGrid组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的SliverGrid组件是一种网格类组件&#xff0c;主要用来…

K8S集群架构及主机准备

本次集群部署主机分布K8S集群主机配置主机静态IP设置主机名解析ipvs管理工具安装及模块加载主机系统升级主机间免密登录配置主机基础配置完后最好做个快照备份 2台负载均衡器 Haproxy高可用keepalived3台k8s master节点5台工作节点(至少2及以上)本次集群部署主机分布 K8S集群主…

012-51单片机CLD1602显示万年历+闹钟+农历+整点报时

1. 硬件设计 硬件是我自己设计的一个通用的51单片机开发平台&#xff0c;可以根据需要自行焊接模块&#xff0c;这是用立创EDA画的一个双层PCB板&#xff0c;所以模块都是插针式&#xff0c;不是表贴的。电路原理图在文末的链接里&#xff0c;PCB图暂时不选择开源。 B站上传的…

数据分析系列--[11] RapidMiner,K-Means聚类分析(含数据集)

一、数据集 二、导入数据 三、K-Means聚类 数据说明:提供一组数据,含体重、胆固醇、性别。 分析目标:找到这组数据中需要治疗的群体供后续使用。 一、数据集 点击下载数据集 二、导入数据 三、K-Means聚类 Ending, congratulations, youre done.

深度学习查漏补缺:1.梯度消失、梯度爆炸和残差块

一、梯度消失 梯度消失的根本原因在于 激活函数的性质和链式法则的计算&#xff1a; 激活函数的导数很小&#xff1a; 常见的激活函数&#xff08;例如 Sigmoid 和 Tanh&#xff09;在输入较大或较小时&#xff0c;输出趋于饱和&#xff08;Sigmoid 的输出趋于 0 或 1&#xf…

于动态规划的启幕之章,借 C++ 笔触绘就算法新篇

注意&#xff1a;代码由易到难 P1216 [IOI 1994] 数字三角形 Number Triangles 题目链接&#xff1a;[IOI 1994] 数字三角形 Number Triangles - 洛谷 题目描述 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每…

基于开源2 + 1链动模式AI智能名片S2B2C商城小程序的内容创作与传播效能探究

摘要&#xff1a;本文围绕开源2 1链动模式AI智能名片S2B2C商城小程序&#xff0c;深入探讨在其应用场景下内容创作与传播效果的关键要素——转发数与转化率。通过剖析如何创作引发用户共鸣、提升用户信任的内容&#xff0c;阐明深度思考内容本质对于实现有效传播的重要性&…

深度学习之“线性代数”

线性代数在深度学习中是解决多维数学对象计算问题的核心工具。这些数学对象包括标量、向量、矩阵和张量&#xff0c;借助它们可以高效地对数据进行操作和建模。以下将详细介绍这些数学对象及其在深度学习中的典型用途。 数学对象概述 标量 标量是最简单的数学对象&#xff0…

SpringBoot的配置(配置文件、加载顺序、配置原理)

文章目录 SpringBoot的配置(配置文件、加载顺序、配置原理)一、引言二、配置文件1、配置文件的类型1.1、配置文件的使用 2、多环境配置 三、加载顺序四、配置原理五、使用示例1、配置文件2、配置类3、控制器 六、总结 SpringBoot的配置(配置文件、加载顺序、配置原理) 一、引言…

CVE-2023-38831 漏洞复现:win10 压缩包挂马攻击剖析

目录 前言 漏洞介绍 漏洞原理 产生条件 影响范围 防御措施 复现步骤 环境准备 具体操作 前言 在网络安全这片没有硝烟的战场上&#xff0c;新型漏洞如同隐匿的暗箭&#xff0c;时刻威胁着我们的数字生活。其中&#xff0c;CVE - 2023 - 38831 这个关联 Win10 压缩包挂…

Clion开发STM32时使用stlink下载程序与Debug调试

一、下载程序 先创建一个文件夹&#xff1a; 命名&#xff1a;stlink.cfg 写入以下代码: # choose st-link/j-link/dap-link etc. #adapter driver cmsis-dap #transport select swdsource [find interface/stlink.cfg]transport select hla_swdsource [find target/stm32f4x.…

无人机图传模块 wfb-ng openipc-fpv,4G

openipc 的定位是为各种模块提供底层的驱动和linux最小系统&#xff0c;openipc 是采用buildroot系统编译而成&#xff0c;因此二次开发能力有点麻烦。为啥openipc 会用于无人机图传呢&#xff1f;因为openipc可以将现有的网络摄像头ip-camera模块直接利用起来&#xff0c;从而…

C语言 --- 分支

C语言 --- 分支 语句分支语句含义if...else语句单分支if语句语法形式 双分支 if-else 语句语法形式 悬空else含义问题描述 多分支 if-else 语句语法形式 switch...case语句含义语法形式 总结 &#x1f4bb;作者简介&#xff1a;曾与你一样迷茫&#xff0c;现以经验助你入门 C 语…

低代码系统-产品架构案例介绍、炎黄盈动-易鲸云(十二)

易鲸云作为炎黄盈动新推出的产品&#xff0c;在定位上为低零代码产品。 开发层 表单引擎 表单设计器&#xff0c;包括设计和渲染 流程引擎 流程设计&#xff0c;包括设计和渲染&#xff0c;需要说明的是&#xff1a;采用国际标准BPMN2.0&#xff0c;可以全球通用 视图引擎 视图…

自制虚拟机(C/C++)(三、做成标准GUI Windows软件,扩展指令集,直接支持img软盘)

开源地址:VMwork 要使终端不弹出&#xff0c; #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") 还要实现jmp near 0x01类似的 本次的main.cpp #include <graphics.h> #include <conio.h> #include <windows.h> #includ…