基于 Pygame 的 Python 贪吃蛇游戏开发实战教程
使用 Python 的 Pygame 库开发经典的贪吃蛇游戏。内容涵盖环境搭建、核心逻辑实现、碰撞检测机制及游戏循环控制。通过分步代码解析,帮助开发者理解事件处理、坐标管理及渲染流程,并提供完整的可运行代码示例与常见错误排查指南。

使用 Python 的 Pygame 库开发经典的贪吃蛇游戏。内容涵盖环境搭建、核心逻辑实现、碰撞检测机制及游戏循环控制。通过分步代码解析,帮助开发者理解事件处理、坐标管理及渲染流程,并提供完整的可运行代码示例与常见错误排查指南。

贪吃蛇游戏是计算机历史上最经典的街机游戏之一。玩家的主要目标是在控制蛇移动的过程中,尽可能多地吃到水果,同时避免撞墙或撞到自己的身体。对于学习 Python 或 Pygame 库的新手来说,构建一个贪吃蛇游戏是一个极佳的入门项目。它涵盖了图形渲染、事件处理、逻辑判断等核心编程概念。
本文将使用 Pygame 库来创建这个贪吃蛇游戏。Pygame 是一个开源的跨平台 Python 模块集合,专为制作视频游戏而设计。它内置了图形和声音库,语法简洁,非常适合初学者快速上手。
要开始开发,首先需要确保已安装 Python 3.x 版本。接着,在终端或命令提示符中运行以下命令安装 Pygame:
pip install pygame
如果网络较慢,可以使用国内镜像源加速:
pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple
为了保持代码整洁,建议将项目文件组织如下:
snake_game.py:主程序入口assets/:存放音效、图片等资源(可选)config.py:存放游戏配置参数(如窗口大小、速度)首先,我们需要导入 pygame 用于图形界面,time 用于控制时间延迟,以及 random 用于生成随机坐标。
import pygame
import time
import random
# 游戏速度设置
snake_speed = 15
# 窗口尺寸定义
window_x = 720
window_y = 480
# 颜色定义 (RGB 格式)
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)
调用 pygame.init() 初始化所有 Pygame 模块。随后创建游戏窗口并设置标题,同时初始化时钟对象以控制帧率。
# 初始化 pygame
pygame.init()
# 初始化游戏窗口
game_window = pygame.display.set_mode((window_x, window_y))
pygame.display.set_caption('Python Snake Game')
# FPS 控制器,用于限制每秒帧数
fps = pygame.time.Clock()
初始化蛇的位置、身体块列表以及水果的随机位置。默认方向设置为向右。
# 蛇的默认起始位置
snake_position = [100, 50]
# 蛇的身体块列表(初始长度为 4)
snake_body = [[100, 50], [90, 50], [80, 50], [70, 50]]
# 水果位置(随机生成,步长为 10)
fruit_position = [random.randrange(1, (window_x // 10)) * 10,
random.randrange(1, (window_y // 10)) * 10]
fruit_spawn = True
# 默认方向
direction = 'RIGHT'
change_to = direction
创建一个函数来渲染当前分数。使用 pygame.font.SysFont 创建字体对象,并通过 render 生成文本表面,最后使用 blit 绘制到屏幕上。
score = 0
def show_score(choice, color, font, size):
score_font = pygame.font.SysFont(font, size)
score_surface = score_font.render('Score : ' + str(score), True, color)
score_rect = score_surface.get_rect()
# 将分数显示在左上角
score_rect.midtop = (window_x / 2, 15)
game_window.blit(score_surface, score_rect)
当发生碰撞时调用此函数。它会显示最终得分,暂停 2 秒后退出程序。
def game_over():
my_font = pygame.font.SysFont('times new roman', 50)
game_over_surface = my_font.render('Your Score is : ' + str(score), True, red)
game_over_rect = game_over_surface.get_rect()
game_over_rect.midtop = (window_x / 2, window_y / 4)
game_window.blit(game_over_surface, game_over_rect)
pygame.display.flip()
time.sleep(2)
pygame.quit()
quit()
这是游戏的核心部分,包含事件监听、逻辑更新、碰撞检测和画面刷新。
while True:
# 1. 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
change_to = 'UP'
if event.key == pygame.K_DOWN:
change_to = 'DOWN'
if event.key == pygame.K_LEFT:
change_to = 'LEFT'
if event.key == pygame.K_RIGHT:
change_to = 'RIGHT'
# 2. 防止反向移动(例如正在向右时不能直接向左)
if change_to == 'UP' and direction != 'DOWN':
direction = 'UP'
if change_to == 'DOWN' and direction != 'UP':
direction = 'DOWN'
if change_to == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
if change_to == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
# 3. 移动蛇头
if direction == 'UP':
snake_position[1] -= 10
if direction == 'DOWN':
snake_position[1] += 10
if direction == 'LEFT':
snake_position[0] -= 10
if direction == 'RIGHT':
snake_position[0] += 10
# 4. 蛇身生长机制
snake_body.insert(0, list(snake_position))
# 检测是否吃到水果
if snake_position[0] == fruit_position[0] and snake_position[1] == fruit_position[1]:
score += 10
fruit_spawn = False
else:
snake_body.pop() # 没吃到则移除尾部,保持长度不变
# 重新生成水果
if not fruit_spawn:
fruit_position = [random.randrange(1, (window_x // 10)) * 10,
random.randrange(1, (window_y // 10)) * 10]
fruit_spawn = True
# 5. 绘制背景
game_window.fill(black)
# 6. 绘制蛇身
for pos in snake_body:
pygame.draw.rect(game_window, green, pygame.Rect(pos[0], pos[1], 10, 10))
# 7. 绘制水果
pygame.draw.rect(game_window, white, pygame.Rect(
fruit_position[0], fruit_position[1], 10, 10))
# 8. 碰撞检测:撞墙
if snake_position[0] < 0 or snake_position[0] > window_x - 10:
game_over()
if snake_position[1] < 0 or snake_position[1] > window_y - 10:
game_over()
# 9. 碰撞检测:撞自己
for block in snake_body[1:]:
if snake_position[0] == block[0] and snake_position[1] == block[1]:
game_over()
# 10. 显示分数
show_score(1, white, 'times new roman', 20)
# 11. 刷新屏幕
pygame.display.update()
# 12. 控制帧率
fps.tick(snake_speed)
可以通过随着分数增加来提高 snake_speed 的值,使游戏后期更具挑战性。
if score % 50 == 0:
snake_speed += 2
利用文件系统记录玩家的最高分,下次启动时读取。
import os
def save_high_score(score):
filename = 'high_score.txt'
try:
with open(filename, 'r') as f:
current_high = int(f.read())
except FileNotFoundError:
current_high = 0
if score > current_high:
with open(filename, 'w') as f:
f.write(str(score))
在吃到水果或游戏结束时播放简短的 .wav 或 .mp3 文件。
eat_sound = pygame.mixer.Sound('eat.wav')
eat_sound.play()
export DISPLAY=:0 或使用虚拟 framebuffer。fps.tick() 的参数是否过大,适当降低速度值。通过本教程,我们完成了从环境搭建到核心逻辑实现的完整贪吃蛇游戏开发。掌握了 Pygame 的基本流程:初始化 -> 事件循环 -> 逻辑更新 -> 渲染 -> 帧率控制。这为后续开发更复杂的游戏奠定了坚实基础。开发者可以在此基础上继续扩展功能,如增加道具系统、多人模式或关卡设计。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online