使用Pygame制作“贪吃蛇”游戏
贪吃蛇 是一款经典的休闲小游戏:玩家通过操控一条会不断变长的“蛇”在屏幕中移动,去吃随机出现的食物,同时要避免撞到墙壁或自己身体的其他部分。由于其逻辑相对简单,但可玩性和扩展性都不错,非常适合作为新手练习游戏编程的项目。在本篇博客中,我们将使用 Python 语言 + Pygame 库来从零实现一款贪吃蛇。
1. 开发环境准备
- Python 3.x
- Pygame 库:如果尚未安装,请在命令行执行:
pip install pygame - 图形界面环境:在常见的桌面系统(Windows、macOS、Linux)上都可以正常运行 Pygame 程序。
2. 游戏实现思路
要实现一个简易的贪吃蛇,主要需要以下几个要点:
-
游戏界面
- 一般的做法是将屏幕拆分成网格(如 20×20 的方格),蛇和食物都在这些方格坐标上移动。
- 每一个方格的大小可定义为 20×20 或更适合你需求的像素。
- 蛇的运动每次走一格,方向由玩家通过箭头键或 WASD 控制。
-
蛇的表示
- 通常用一个列表来储存蛇身每个“方块”的坐标(从头到尾依次存放)。
- 当蛇移动时,需要在头部插入一个新的坐标(根据方向计算),同时移除最后一个坐标(蛇尾)来保持“长度”不变;只有当蛇吃到食物时,才不移除尾部,从而实现“变长”。
-
食物的产生
- 在网格上随机产生一个坐标点,作为食物。
- 当蛇头和食物坐标重合时,表示蛇吃到了食物,此时增加蛇的长度并在其他空格处随机生成新的食物。
-
边界与身体碰撞检测
- 边界检测:如果蛇头超出屏幕范围,则表示撞墙,游戏结束。
- 身体碰撞检测:如果蛇头的坐标跟身体某个方块相同,表示咬到自己,游戏结束。
-
游戏循环
- 使用 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()
核心逻辑解析
-
Snake 类
- 用一个列表
body存储从头到尾的网格坐标。 move()函数在前面插入新的头部坐标,如不需要增长则移除尾部。check_collision()判断是否超出网格边界或头部与身体其他部分重合。
- 用一个列表
-
Food 类
- 只需保存一个
position表示食物在网格的坐标。 - 当被吃到时,用
random_pos()重新生成新的位置。
- 只需保存一个
-
主循环
- 通过
clock.tick(FPS)控制蛇每秒移动多少次。 - 监听方向键来改变蛇的方向。
- 判断蛇头和食物是否重合,若重合则得分、食物重生、蛇变长。
- 若蛇撞墙或撞自己,则游戏结束并跳转到
game_over界面。
- 通过
4. 实现效果


5. 总结
通过这篇文章,我们用 Python + Pygame 从零实现了一款简单的贪吃蛇游戏。该示例涵盖了网格移动、随机食物生成、碰撞检测、方向控制等基本概念,为你打下初步的游戏开发基础。
相关文章:
使用Pygame制作“贪吃蛇”游戏
贪吃蛇 是一款经典的休闲小游戏:玩家通过操控一条会不断变长的“蛇”在屏幕中移动,去吃随机出现的食物,同时要避免撞到墙壁或自己身体的其他部分。由于其逻辑相对简单,但可玩性和扩展性都不错,非常适合作为新手练习游戏…...
云计算技术深度解析与实战案例
云计算技术深度解析与实战案例 引言 随着信息技术的飞速发展,云计算作为一种革命性的技术模式,已经渗透到各行各业,成为推动数字化转型的关键力量。本文旨在深入探讨云计算的技术特点、应用场景,并通过一个具体的代码使用案例&a…...
deb安装失败后,无法再安装别的包的解决方案
把package_name换成出安装问题的包 移除该包的安装标记 sudo dpkg --remove --force-remove-reinstreq package_name清理残留文件和配置 sudo apt-get purge package_name...
海外问卷调查如何影响企业的经营?在品牌建设中有何指导意义?
市场调查的定义:通过科学的方法,有目的地、系统地搜集整理一些市场信息,其目的在于了解当下市场现状和发展前景,为企业生产和品牌打造提供一些科学的指导意见,这是任何大企业、中小企业、初创企业都必须重视的一个重要…...
脚本运行禁止:npm 无法加载文件,因为在此系统上禁止运行脚本
问题与处理策略 1、问题描述 npm install -D tailwindcss执行上述指令,报如下错误 npm : 无法加载文件 D:\nodejs\npm.ps1,因为在此系统上禁止运行脚本。 有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_…...
unity学习23:场景scene相关,场景信息,场景跳转
目录 1 默认场景和Assets里的场景 1.1 scene的作用 1.2 scene作为project的入口 1.3 默认场景 2 场景scene相关 2.1 创建scene 2.2 切换场景 2.3 build中的场景,在构建中包含的场景 (否则会认为是失效的Scene) 2.4 Scenes in Bui…...
CPU 100% 出现系统中断 怎么解决
CPU 100% 出现系统中断 怎么解决 电脑开机时会掉帧,切换到桌面时就会卡顿,然后打开任务管理器就会看到系统中断的cpu占用率达到100%,过一段时间再打开还是会有显示100%的占用率,这个问题怎么解决? 文章目录 CPU 100% …...
数据分析系列--⑥RapidMiner构建决策树(泰坦尼克号案例含数据)
一、资源下载 二、数据处理 1.导入数据 2.数据预处理 三、构建模型 1.构建决策树 2.划分训练集和测试集 3.应用模型 4.结果分析 一、资源下载 点击下载数据集 二、数据处理 1.导入数据 2.数据预处理 三、构建模型 1.构建决策树 虽然决策树已经构建,但对于大多数初学者或…...
【MyDB】4-VersionManager 之 4-VM的实现
【MyDB】4-VersionManager 之 4-VM的实现 VM 的实现VM(VersionManager)的基本定义与实现优化具体功能实现begin()开启事务commit()提交事务abort 中止事务read 读取uid对应的数据记录所在的entryinsert方法,插入数据delete方法 VM 的实现 本章代码位于:t…...
2024-2025自动驾驶技术演进与产业破局的深度实践——一名自动驾驶算法工程师的年度技术总结与行业洞察
一、引言:站在自动驾驶的"技术奇点" 2024年是自动驾驶行业从"技术验证"迈向"商业化落地"的关键转折点。从特斯拉FSD V12的端到端技术突破,到中国L3法规的破冰,从大模型重构感知架构,到城市NOA的&qu…...
计算机网络 笔记 传输层
概述: 主要功能: TCP: 特点***: 数据格式: 连接管理***: 建立连接(三次握手) 释放连接(四次挥手) 应用场景 UDP: 特点: 数…...
(leetcode 213 打家劫舍ii)
代码随想录: 将一个线性数组换成两个线性数组(去掉头,去掉尾) 分别求两个线性数组的最大值 最后求这两个数组的最大值 代码随想录视频 #include<iostream> #include<vector> #include<algorithm> //nums:2,…...
《TCP 网络编程实战:开发流程、缓冲区原理、三次握手与四次挥手》
一、 TCP 网络应用程序开发流程 学习目标 能够知道TCP客户端程序的开发流程1. TCP 网络应用程序开发流程的介绍 TCP 网络应用程序开发分为: TCP 客户端程序开发TCP 服务端程序开发说明: 客户端程序是指运行在用户设备上的程序 服务端程序是指运行在服务器设备上的程序,专门…...
62.异步编程+Prism
为什么不需要在构造函数中初始化了? private ICommand _fetchUserInfoCommand; public ICommand FetchUserInfoCommand > _fetchUserInfoCommand ?? new DelegateCommand(ExecuteFetchUserInfoAsync); public MainWindowViewModel() {// 无需…...
基于亿坊PHP框架构建物联网解决方案的优势分析!
在物联网 (IoT) 领域,选到合适的框架对于整个项目的开展也尤为重要。通常情况下,基于PHP的一些主流框架被用户常选择,今天就带大家了解下基于亿坊PHP框架构建物联网解决方案的优势有哪些? 1、开发效率高 在物联网项目中…...
把本地搭建的hexo博客部署到自己的服务器上
配置远程服务器的git 安装git 安装依赖工具包 yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel安装编译工具 yum install -y gcc perl-ExtUtils-MakeMaker package下载git,也可以去官网下载了传到服务器上 wget https://www.ke…...
《DeepSeek 实用集成:大模型能力接入各类软件》
DeepSeek 实用集成 awesome-deepseek-integration/README_cn.md at main deepseek-ai/awesome-deepseek-integration 将 DeepSeek 大模型能力轻松接入各类软件。访问 DeepSeek 开放平台来获取您的 API key。 English/简体中文 应用程序 Chatbox一个支持多种流行LLM模型的桌…...
接口使用实例(1)
大家好,今天我们来看看接口的一些实例,关于如何定义和实现接口,相信通过这些例子,我们能有一些清晰的认知。 先定义一个学生类: 再给定一个学生数组,对这个对象数组中的元素进行排序(按分数排&…...
Git 版本控制:基础介绍与常用操作
目录 Git 的基本概念 Git 安装与配置 Git 常用命令与操作 1. 初始化本地仓库 2. 版本控制工作流程 3. 分支管理 4. 解决冲突 5. 回退和撤销 6. 查看提交日志 前言 在软件开发过程中,开发者常常需要在现有程序的基础上进行修改和扩展。但如果不加以管理&am…...
leetcode——合并K个有序链表(java)
给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例 1: 输入:lists [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下&#…...
跨境数据传输问题常见解决方式
在全球化经济的浪潮下,跨境数据传输已然成为企业日常运营的关键环节。随着数字贸易的蓬勃发展和跨国业务的持续扩张,企业在跨境数据处理方面遭遇了诸多棘手难题。那么,面对这些常见问题,企业该如何应对?镭速跨境数据传…...
python-leetcode-删除链表的倒数第 N 个结点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def removeNthFromEnd(self…...
EasyExcel写入和读取多个sheet
最近在工作中,作者频频接触到Excel处理,因此也对EasyExcel进行了一定的研究和学习,也曾困扰过如何处理多个sheet,因此此处分享给大家,希望能有所帮助 目录 1.依赖 2. Excel类 3.处理Excel读取和写入多个sheet 4. 执…...
lanqiaoOJ 2097:青蛙过河 ← 二分+前缀和+贪心
【题目来源】 https://www.lanqiao.cn/problems/2097/learning/ https://www.luogu.com.cn/problem/P8775 【题目描述】 小青蛙住在一条河边,它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。 备注:此图由百度 AI 创作生成 河里的石头排…...
woocommerce独立站与wordpress独立站的最大区别是什么
WooCommerce独立站与WordPress独立站的最大区别在于它们的功能定位和使用场景。 WordPress是一个开源的内容管理系统(CMS),最初是作为博客平台发展起来的,但现在已经演变为一个功能丰富的网站构建工具。它主要用于创建动态网站,提供广泛的定…...
MybatisX插件快速创建项目
一、安装插件 二、创建一个数据表测试 三、IDEA连接Mysql数据库 四、选择MybatiX构造器 五、配置参数 六、项目结构...
【Leetcode 每日一题 - 补卡】219. 存在重复元素 II
问题背景 给你一个整数数组 n u m s nums nums 和一个整数 k k k,判断数组中是否存在两个 不同的索引 i i i 和 j j j,满足 n u m s [ i ] n u m s [ j ] nums[i] nums[j] nums[i]nums[j] 且 ∣ i − j ∣ < k |i - j| < k ∣i−j∣<…...
llama3学习
首先是预训练部分,数据注意版权和风险问题。数据去重和数据清理,PII人的身份信息(人名、地址等)。如果数据有大量PII数据则这个数据丢掉。 网页的数据,提取,代码和数学的提取的特别的方法,OCR…...
H3CNE-31-BFD
Bidirectional Forwarding Dection,双向转发检查 作用:毫秒级故障检查,通常结合三层协议(静态路由、vrrp、ospf、BGP等),实现链路故障快速检查。 BFD配置示例 没有中间的SW,接口downÿ…...
VMware安装win10记录
(1)下载vmware,这个pro现在也免费的,下载地址:https://support.broadcom.com/group/ecx/productfiles?subFamilyVMware%20Workstation%20Pro&displayGroupVMware%20Workstation%20Pro%2017.0%20for%20Windows&release17.6.2&os&…...
