使用Pygame制作“贪吃蛇”游戏

贪吃蛇 是一款经典的休闲小游戏:玩家通过操控一条会不断变长的“蛇”在屏幕中移动,去吃随机出现的食物,同时要避免撞到墙壁或自己身体的其他部分。由于其逻辑相对简单,但可玩性和扩展性都不错,非常适合作为新手练习游戏编程的项目。在本篇博客中,我们将使用 Python 语言 + Pygame 库来从零实现一款贪吃蛇。


1. 开发环境准备

  1. Python 3.x
  2. Pygame 库:如果尚未安装,请在命令行执行:
    pip install pygame
    
  3. 图形界面环境:在常见的桌面系统(Windows、macOS、Linux)上都可以正常运行 Pygame 程序。

2. 游戏实现思路

要实现一个简易的贪吃蛇,主要需要以下几个要点:

  1. 游戏界面

    • 一般的做法是将屏幕拆分成网格(如 20×20 的方格),蛇和食物都在这些方格坐标上移动。
    • 每一个方格的大小可定义为 20×20 或更适合你需求的像素。
    • 蛇的运动每次走一格,方向由玩家通过箭头键或 WASD 控制。
  2. 蛇的表示

    • 通常用一个列表来储存蛇身每个“方块”的坐标(从头到尾依次存放)。
    • 当蛇移动时,需要在头部插入一个新的坐标(根据方向计算),同时移除最后一个坐标(蛇尾)来保持“长度”不变;只有当蛇吃到食物时,才不移除尾部,从而实现“变长”。
  3. 食物的产生

    • 在网格上随机产生一个坐标点,作为食物。
    • 当蛇头和食物坐标重合时,表示蛇吃到了食物,此时增加蛇的长度并在其他空格处随机生成新的食物。
  4. 边界与身体碰撞检测

    • 边界检测:如果蛇头超出屏幕范围,则表示撞墙,游戏结束。
    • 身体碰撞检测:如果蛇头的坐标跟身体某个方块相同,表示咬到自己,游戏结束。
  5. 游戏循环

    • 使用 Pygame 的事件与时钟,循环更新游戏状态:接收玩家按键,移动蛇头,检测碰撞,更新得分等。

3. 完整示例代码

将以下代码保存为 snake_game.py 并运行,即可体验一个最基本版本的贪吃蛇。你可以根据自己的需求对其中的参数或逻辑进行修改和完善。

import pygame
import random
import sys# 初始化 Pygame
pygame.init()# ---------------------
#  全局配置
# ---------------------
BLOCK_SIZE = 20        # 蛇和食物的大小(方块尺寸)
GRID_WIDTH = 30        # 水平方向方块数
GRID_HEIGHT = 20       # 垂直方向方块数SCREEN_WIDTH = GRID_WIDTH * BLOCK_SIZE
SCREEN_HEIGHT = GRID_HEIGHT * BLOCK_SIZEFPS = 10               # 游戏刷新率(蛇移动速度)# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED   = (255, 0, 0)
GREEN = (0, 200, 0)
GRAY  = (50, 50, 50)# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("贪吃蛇 - Pygame")# 字体
font = pygame.font.SysFont("arial", 24)# ---------------------
#  功能函数
# ---------------------
def draw_text(text, color, x, y):"""在屏幕指定位置绘制文字"""surface = font.render(text, True, color)screen.blit(surface, (x, y))def draw_block(color, x, y):"""在(x, y)绘制一个BLOCK_SIZE大小的方块"""rect = pygame.Rect(x, y, BLOCK_SIZE, BLOCK_SIZE)pygame.draw.rect(screen, color, rect)# ---------------------
#  蛇类
# ---------------------
class Snake:def __init__(self):# 蛇初始位置(列表: 记录蛇身每个方块的坐标)# 例如[(x1, y1), (x2, y2), ...] 从头到尾self.body = [(GRID_WIDTH // 2, GRID_HEIGHT // 2)]self.direction = 'UP'     # 初始方向:上self.grow = False         # 标识是否需要增长身体def move(self):# 计算新头部位置head_x, head_y = self.body[0]if self.direction == 'UP':head_y -= 1elif self.direction == 'DOWN':head_y += 1elif self.direction == 'LEFT':head_x -= 1elif self.direction == 'RIGHT':head_x += 1new_head = (head_x, head_y)self.body.insert(0, new_head)  # 头部插入到列表最前# 如果不需要生长,则移除尾部if not self.grow:self.body.pop()else:self.grow = False  # 本次已经完成增长def change_direction(self, new_dir):"""根据玩家按键改变蛇的方向,但需要防止蛇直接掉头(如当前在往左跑,不可立即改成往右)"""opposite = {'UP': 'DOWN', 'DOWN': 'UP', 'LEFT': 'RIGHT', 'RIGHT': 'LEFT'}if new_dir != opposite[self.direction]:self.direction = new_dirdef check_collision(self):"""检测是否撞墙或撞自己:- 撞墙: 头部超出网格范围- 撞自己: 头部坐标出现在身体其他部分"""head_x, head_y = self.body[0]# 撞墙if head_x < 0 or head_x >= GRID_WIDTH or head_y < 0 or head_y >= GRID_HEIGHT:return True# 撞自己if self.body[0] in self.body[1:]:return Truereturn Falsedef draw(self):"""绘制蛇"""for block in self.body:x_coord = block[0] * BLOCK_SIZEy_coord = block[1] * BLOCK_SIZEdraw_block(GREEN, x_coord, y_coord)# ---------------------
#  食物类
# ---------------------
class Food:def __init__(self):self.position = self.random_pos()def random_pos(self):"""随机生成食物坐标(网格中)"""return (random.randint(0, GRID_WIDTH - 1),random.randint(0, GRID_HEIGHT - 1))def draw(self):"""绘制食物"""x_coord = self.position[0] * BLOCK_SIZEy_coord = self.position[1] * BLOCK_SIZEdraw_block(RED, x_coord, y_coord)# ---------------------
#  游戏主函数
# ---------------------
def main():clock = pygame.time.Clock()snake = Snake()food = Food()score = 0running = Truewhile running:clock.tick(FPS)  # 控制游戏帧率(蛇移动速度)# 1) 处理事件for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.KEYDOWN:if event.key == pygame.K_UP:snake.change_direction('UP')elif event.key == pygame.K_DOWN:snake.change_direction('DOWN')elif event.key == pygame.K_LEFT:snake.change_direction('LEFT')elif event.key == pygame.K_RIGHT:snake.change_direction('RIGHT')# 2) 更新游戏状态 (蛇移动, 检测碰撞, 食物处理)snake.move()# 如果蛇头与食物位置相同 => 吃到食物if snake.body[0] == food.position:score += 1snake.grow = Truefood.position = food.random_pos()# 检测蛇是否撞墙或撞自己if snake.check_collision():running = False# 3) 绘制游戏界面screen.fill(BLACK)    # 清屏(背景黑色)snake.draw()food.draw()draw_text(f"Score: {score}", WHITE, 10, 10)pygame.display.flip()# 如果跳出主循环,说明游戏结束game_over(screen, score)def game_over(surface, score):"""游戏结束界面,可在此添加重来或退出选项"""surface.fill(GRAY)draw_text("Game Over!", WHITE, SCREEN_WIDTH // 2 - 60, SCREEN_HEIGHT // 2 - 30)draw_text(f"Your Score: {score}", WHITE, SCREEN_WIDTH // 2 - 70, SCREEN_HEIGHT // 2 + 10)pygame.display.flip()# 等待若干秒后退出pygame.time.wait(3000)pygame.quit()sys.exit()if __name__ == "__main__":main()

核心逻辑解析

  1. Snake 类

    • 用一个列表 body 存储从头到尾的网格坐标。
    • move() 函数在前面插入新的头部坐标,如不需要增长则移除尾部。
    • check_collision() 判断是否超出网格边界或头部与身体其他部分重合。
  2. Food 类

    • 只需保存一个 position 表示食物在网格的坐标。
    • 当被吃到时,用 random_pos() 重新生成新的位置。
  3. 主循环

    • 通过 clock.tick(FPS) 控制蛇每秒移动多少次。
    • 监听方向键来改变蛇的方向。
    • 判断蛇头和食物是否重合,若重合则得分、食物重生、蛇变长。
    • 若蛇撞墙或撞自己,则游戏结束并跳转到 game_over 界面。

4. 实现效果

在这里插入图片描述

在这里插入图片描述


5. 总结

通过这篇文章,我们用 Python + Pygame 从零实现了一款简单的贪吃蛇游戏。该示例涵盖了网格移动、随机食物生成、碰撞检测、方向控制等基本概念,为你打下初步的游戏开发基础。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【prompt实战】AI +OCR技术结合ChatGPT能力项目实践(BOL提单识别提取专家)

本文原创作者:姚瑞南 AI-agent 大模型运营专家,先后任职于美团、猎聘等中大厂AI训练专家和智能运营专家岗;多年人工智能行业智能产品运营及大模型落地经验,拥有AI外呼方向国家专利与PMP项目管理证书。(转载需经授权) 目录 1. 需求背景 2. 目标 3. BOL通用处理逻辑…

dl学习笔记(8):fashion-mnist

过完年懒羊羊也要复工了&#xff0c;这一节的内容不多&#xff0c;我们接着上次的fashion-mnist数据集。 首先第一步就是导入数据集&#xff0c;由于这个数据集很有名&#xff0c;是深度学习的常见入门数据集&#xff0c;所以可以在库里面导入。由于是图像数据集所以&#xff…

【Rust自学】20.2. 最后的项目:多线程Web服务器

说句题外话&#xff0c;这篇文章非常要求Rust的各方面知识&#xff0c;最好看一下我的【Rust自学】专栏的所有内容。这篇文章也是整个专栏最长&#xff08;4762字&#xff09;的文章&#xff0c;需要多次阅读消化&#xff0c;最好点个收藏&#xff0c;免得刷不到了。 喜欢的话…

Android学习21 -- launcher

1 前言 之前在工作中&#xff0c;第一次听到launcher有点蒙圈&#xff0c;不知道是啥&#xff0c;当时还赶鸭子上架去和客户PK launcher的事。后来才知道其实就是安卓的桌面。本来还以为很复杂&#xff0c;毕竟之前接触过windows的桌面&#xff0c;那叫一个复杂。。。 后面查了…

[创业之路-276]:从燃油汽车到智能汽车:工业革命下的价值变迁

目录 前言&#xff1a; 从燃油汽车到智能汽车&#xff1a;工业革命下的价值变迁 前言&#xff1a; 燃油汽车&#xff0c;第一次、第二次工业革命&#xff0c;机械化、电气化时代的产物&#xff0c;以机械和电气自动化为核心价值。 智能汽车&#xff0c;第三次、第四次工业革…

Spring Boot - 数据库集成07 - 数据库连接池

数据库连接池 文章目录 数据库连接池一&#xff1a;知识准备1&#xff1a;什么是数据库连接池&#xff1f;2&#xff1a;数据库连接池基本原理 二&#xff1a;HikariCP连接池1&#xff1a;简单使用2&#xff1a;进一步理解2.1&#xff1a;是SpringBoot2.x默认连接池2.2&#xf…

Python-基于PyQt5,Pillow,pathilb,imageio,moviepy,sys的GIF(动图)制作工具

前言&#xff1a;在抖音&#xff0c;快手等社交平台上&#xff0c;我们常常见到各种各样的GIF动画。在各大评论区里面&#xff0c;GIF图片以其短小精悍、生动有趣的特点&#xff0c;被广泛用于分享各种有趣的场景、搞笑的瞬间、精彩的动作等&#xff0c;能够快速吸引我们的注意…

使用线性回归模型逼近目标模型 | PyTorch 深度学习实战

前一篇文章&#xff0c;计算图 Compute Graph 和自动求导 Autograd | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 使用线性回归模型逼近目标模型 什么是回归什么是线性回归使用 PyTorch 实现线性回归模型代码执行结…

【蓝桥杯嵌入式】2_LED

1、电路图 74HC573是八位锁存器&#xff0c;当控制端LE脚为高电平时&#xff0c;芯片“导通”&#xff0c;LE为低电平时芯片“截止”即将输出状态“锁存”&#xff0c;led此时不会改变状态&#xff0c;所以可通过led对应的八个引脚的电平来控制led的状态&#xff0c;原理图分析…

尝试在Office里调用免费大语言模型的阶段性进展

我个人觉得通过api而不是直接浏览器客户端聊天调用大语言模型是使用人工智能大模型的一个相对进阶的阶段。 于是就尝试了一下。我用的是老师木 袁进辉博士新创的硅基流动云上的免费的大模型。——虽然自己获赠了不少免费token&#xff0c;但测试阶段用不上。 具体步骤如下&am…

LabVIEW自定义测量参数怎么设置?

以下通过一个温度采集案例&#xff0c;说明在 LabVIEW 中设置自定义测量参数的具体方法&#xff1a; 案例背景 ​ 假设使用 NI USB-6009 数据采集卡 和 热电偶传感器 监测温度&#xff0c;需自定义以下参数&#xff1a; 采样率&#xff1a;1 kHz 输入量程&#xff1a;0~10 V&a…

理解 C 与 C++ 中的 const 常量与数组大小的关系

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;数组大小的常量要求&#x1f4af;C 语言中的数组大小要求&#x1f4af;C 中的数组大小要求&#x1f4af;为什么 C 中 const 变量可以作为数组大小&#x1f4af;进一步的…

【Elasticsearch】文本分类聚合Categorize Text Aggregation

响应参数讲解: key &#xff08;字符串&#xff09;由 categorization_analyzer 提取的标记组成&#xff0c;这些标记是类别中所有输入字段值的共同部分。 doc_count &#xff08;整数&#xff09;与类别匹配的文档数量。 max_matching_length &#xff08;整数&#xff09;从…

基于SpringBoot的信息技术知识赛系统的设计与实现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

Windows Docker笔记-安装docker

安装环境 操作系统&#xff1a;Windows 11 家庭中文版 docker版本&#xff1a;Docker Desktop version: 4.36.0 (175267) 注意&#xff1a; Docker Desktop 支持以下Windows操作系统&#xff1a; 支持的版本&#xff1a;Windows 10&#xff08;家庭版、专业版、企业版、教育…

《Kettle保姆级教学-界面介绍》

目录 一、Kettle介绍二、界面介绍1.界面构成2、菜单栏详细介绍2.1 【文件F】2.2 【编辑】2.3 【视图】2.4 【执行】2.5 【工具】2.6 【帮助】 3、转换界面介绍4、作业界面介绍5、执行结果 一、Kettle介绍 Kettle 是一个开源的 ETL&#xff08;Extract, Transform, Load&#x…

新型智慧城市建设方案-1

智慧城市建设的背景与需求 随着信息技术的飞速发展&#xff0c;新型智慧城市建设成为推动城市现代化、提升城市管理效率的重要途径。智慧城市通过整合信息资源&#xff0c;优化城市规划、建设和管理&#xff0c;旨在打造更高效、便捷、宜居的城市环境。 智慧城市建设的主要内容…

【Java计算机毕业设计】基于Springboot的物业信息管理系统【源代码+数据库+LW文档+开题报告+答辩稿+部署教程+代码讲解】

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

ollama部署deepseek实操记录

1. 安装 ollama 1.1 下载并安装 官网 https://ollama.com/ Linux安装命令 https://ollama.com/download/linux curl -fsSL https://ollama.com/install.sh | sh安装成功截图 3. 开放外网访问 1、首先停止ollama服务&#xff1a;systemctl stop ollama 2、修改ollama的servic…

Agentic Automation:基于Agent的企业认知架构重构与数字化转型跃迁---我的AI经典战例

文章目录 Agent代理Agent组成 我在企业实战AI Agent企业痛点我构建的AI Agent App 项目开源 & 安装包下载 大家好&#xff0c;我是工程师令狐&#xff0c;今天想给大家讲解一下AI智能体&#xff0c;以及企业与AI智能体的结合&#xff0c;文章中我会列举自己在企业中Agent实…