当前位置: 首页 > news >正文

使用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 从零实现了一款简单的贪吃蛇游戏。该示例涵盖了网格移动、随机食物生成、碰撞检测、方向控制等基本概念,为你打下初步的游戏开发基础。

相关文章:

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

贪吃蛇 是一款经典的休闲小游戏&#xff1a;玩家通过操控一条会不断变长的“蛇”在屏幕中移动&#xff0c;去吃随机出现的食物&#xff0c;同时要避免撞到墙壁或自己身体的其他部分。由于其逻辑相对简单&#xff0c;但可玩性和扩展性都不错&#xff0c;非常适合作为新手练习游戏…...

本地部署DeepSeek开源多模态大模型Janus-Pro-7B实操

本地部署DeepSeek开源多模态大模型Janus-Pro-7B实操 Janus-Pro-7B介绍 Janus-Pro-7B 是由 DeepSeek 开发的多模态 AI 模型&#xff0c;它在理解和生成方面取得了显著的进步。这意味着它不仅可以处理文本&#xff0c;还可以处理图像等其他模态的信息。 模型主要特点:Permalink…...

Java开发vscode环境搭建

1 几个名词 JDK Java Development Kit JRE Java Runtion Environment JVM JDK 包括 Compiler,debugger,JRE等。JRE包括JVM和Runtime Library。 2 配置环境 2.1 安装JDK 类比 C/C的 g工具 官网&#xff1a;https://www.oracle.com/java/technologies/downloads/ 根据自己使…...

深入解析:一个简单的浮动布局 HTML 示例

深入解析&#xff1a;一个简单的浮动布局 HTML 示例 示例代码解析代码结构分析1. HTML 结构2. CSS 样式 核心功能解析1. 浮动布局&#xff08;Float&#xff09;2. 清除浮动&#xff08;Clear&#xff09;3. 其他样式 效果展示代码优化与扩展总结 在网页设计中&#xff0c;浮动…...

车载软件 --- 大一新生入门汽车零部件嵌入式开发

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…...

DDD - 领域驱动设计分层架构:构建可演化的微服务架构

文章目录 引言1. 什么是DDD分层架构&#xff1f;1.1 DDD分层架构的演变1.2 四层架构的起源与问题1.3 依赖倒置和五层架构 2. DDD分层架构的核心层次2.1 用户接口层&#xff08;User Interface Layer&#xff09;2.2 应用层&#xff08;Application Layer&#xff09;2.3 领域层…...

2025数学建模美赛|赛题翻译|E题

2025数学建模美赛&#xff0c;E题赛题翻译 更多美赛内容持续更新中......

DeepSeek-V3 与 DeepSeek R1 对比分析:技术与应用的全面解析

一、背景 在当今科技飞速发展的时代&#xff0c;深度学习技术如同一股强大的浪潮&#xff0c;席卷了自然语言处理&#xff08;NLP&#xff09;、计算机视觉&#xff08;CV&#xff09;以及多模态模型等众多领域。从智能语音助手到图像识别技术&#xff0c;从文本生成工具到多模…...

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记 文章目录 qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记1.例程运行效果2.例程缩略图3.项目文件列表4.main.qml5.main.cpp6.CMakeLists.txt 1.例程运行效果 运行该项目需要自己准备一个模型文件 2.例程缩略图…...

Linux内核中的页面错误处理机制与按需分页技术

在现代操作系统中,内存管理是核心功能之一,而页面错误(Page Fault)处理机制是内存管理的重要组成部分。当程序访问一个尚未映射到物理内存的虚拟地址时,CPU会触发页面错误异常,内核需要捕获并处理这种异常,以决定如何响应,例如加载缺失的页面、处理权限错误等。Linux内…...

PHP实现混合加密方式,提高加密的安全性(代码解密)

代码1&#xff1a; <?php // 需要加密的内容 $plaintext 授权服务器拒绝连接;// 1. AES加密部分 $aesKey openssl_random_pseudo_bytes(32); // 生成256位AES密钥 $iv openssl_random_pseudo_bytes(16); // 生成128位IV// AES加密&#xff08;CBC模式&#xff09…...

使用openwrt搭建ipsec隧道

背景&#xff1a;最近同事遇到了个ipsec问题&#xff0c;做的ipsec特性&#xff0c;ftp下载ipv6性能只有100kb, 正面定位该问题也蛮久了&#xff0c;项目没有用openwrt, 不过用了开源组件strongswan, 加密算法这些也是内核自带的&#xff0c;想着开源的不太可能有问题&#xff…...

大语言模型(LLM)模拟金融市场参与者行为

大语言模型(LLM)模拟金融市场参与者行为 研究背景 传统深度学习模型通过识别市场数据历史模式预测市场,但未捕捉个体决策过程。LLM 虽能学习人类对不同提示的反应,但在模拟金融市场参与者时面临挑战:个体投资者不总是理性决策,LLM 可能无法捕捉;LLM 数值和金融知识可靠…...

用一个例子详细说明python单例模式

单例模式是一种设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。这在需要控制资源&#xff08;如数据库连接、文件系统等&#xff09;的访问时非常有用。 下面是一个使用Python实现单例模式的例子&#xff1a; class Singleton:…...

第1章 量子暗网中的血色黎明

月球暗面的危机与阴谋 量子隧穿效应催生的幽蓝电弧&#xff0c;于环形山表面肆意跳跃&#xff0c;仿若无数奋力挣扎的机械蠕虫&#xff0c;将月球暗面的死寂打破&#xff0c;徒增几分诡异。艾丽伫立在被遗弃的“广寒宫”量子基站顶端&#xff0c;机械义眼之中&#xff0c;倒映着…...

LeetCode--84. 柱状图中最大的矩形【单调栈】

84. 柱状图中最大的矩形 正文 题目如下 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 这道题暴力很简单&#xff0c;但是时间复杂度是O(N^2)&#xf…...

网络工程师 (8)存储管理

一、页式存储基本原理 &#xff08;一&#xff09;内存划分 页式存储首先将内存物理空间划分成大小相等的存储块&#xff0c;这些块通常被称为“页帧”或“物理页”。每个页帧的大小是固定的&#xff0c;例如常见的页帧大小有4KB、8KB等&#xff0c;这个大小由操作系统决定。同…...

【Leetcode 每日一题】541. 反转字符串 II

问题背景 给定一个字符串 s s s 和一个整数 k k k&#xff0c;从字符串开头算起&#xff0c;每计数至 2 k 2k 2k 个字符&#xff0c;就反转这 2 k 2k 2k 字符中的前 k k k 个字符。 如果剩余字符少于 k k k 个&#xff0c;则将剩余字符全部反转。如果剩余字符小于 2 k…...

MSA Transformer

过去的蛋白质语言模型以单个序列为输入&#xff0c;MSA Transformer以多序列比对的形式将一组序列作为输入。该模型将行和列注意力交织在输入序列中&#xff0c;并在许多蛋白质家族中使用mask语言建模目标进行训练。模型的性能远超过了当时最先进的无监督学习方法&#xff0c;其…...

Vue.js组件开发-实现全屏焦点图片带图标导航按钮控制图片滑动切换

使用 Vue 实现全屏焦点图片带图标导航按钮控制图片滑动切换 步骤 创建 Vue 项目&#xff1a;可以使用 Vue CLI 快速创建一个新的 Vue 项目。设计组件结构&#xff1a;创建一个包含图片展示区域和导航按钮的组件。实现图片滑动切换逻辑&#xff1a;通过点击导航按钮切换图片。…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...