跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python大前端算法

基于 Pygame 的 Python 贪吃蛇游戏开发实战教程

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

ByteFlow发布于 2025/2/6更新于 2026/9/1257 浏览
基于 Pygame 的 Python 贪吃蛇游戏开发实战教程

基于 Pygame 的 Python 贪吃蛇游戏开发实战教程

前言

贪吃蛇游戏是计算机历史上最经典的街机游戏之一。玩家的主要目标是在控制蛇移动的过程中,尽可能多地吃到水果,同时避免撞墙或撞到自己的身体。对于学习 Python 或 Pygame 库的新手来说,构建一个贪吃蛇游戏是一个极佳的入门项目。它涵盖了图形渲染、事件处理、逻辑判断等核心编程概念。

本文将使用 Pygame 库来创建这个贪吃蛇游戏。Pygame 是一个开源的跨平台 Python 模块集合,专为制作视频游戏而设计。它内置了图形和声音库,语法简洁,非常适合初学者快速上手。

环境搭建

1. 安装 Pygame

要开始开发,首先需要确保已安装 Python 3.x 版本。接着,在终端或命令提示符中运行以下命令安装 Pygame:

pip install pygame

如果网络较慢,可以使用国内镜像源加速:

pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 项目结构建议

为了保持代码整洁,建议将项目文件组织如下:

  • 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 引擎

调用 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)

进阶优化建议

1. 增加难度等级

可以通过随着分数增加来提高 snake_speed 的值,使游戏后期更具挑战性。

if score % 50 == 0:
    snake_speed += 2

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))

3. 添加音效

在吃到水果或游戏结束时播放简短的 .wav 或 .mp3 文件。

eat_sound = pygame.mixer.Sound('eat.wav')
eat_sound.play()

常见问题排查

  1. ModuleNotFoundError: No module named 'pygame'
    • 解决方法:确认 pip 安装路径与 python 解释器一致,尝试重新安装。
  2. Display initialization failed
    • 解决方法:在无图形界面的服务器环境运行时,需设置环境变量 export DISPLAY=:0 或使用虚拟 framebuffer。
  3. 蛇移动卡顿
    • 解决方法:检查 fps.tick() 的参数是否过大,适当降低速度值。

总结

通过本教程,我们完成了从环境搭建到核心逻辑实现的完整贪吃蛇游戏开发。掌握了 Pygame 的基本流程:初始化 -> 事件循环 -> 逻辑更新 -> 渲染 -> 帧率控制。这为后续开发更复杂的游戏奠定了坚实基础。开发者可以在此基础上继续扩展功能,如增加道具系统、多人模式或关卡设计。

目录

  1. 基于 Pygame 的 Python 贪吃蛇游戏开发实战教程
  2. 前言
  3. 环境搭建
  4. 1. 安装 Pygame
  5. 2. 项目结构建议
  6. 核心代码实现
  7. 第一步:导入必要的库与初始化
  8. 游戏速度设置
  9. 窗口尺寸定义
  10. 颜色定义 (RGB 格式)
  11. 第二步:初始化 Pygame 引擎
  12. 初始化 pygame
  13. 初始化游戏窗口
  14. FPS 控制器,用于限制每秒帧数
  15. 第三步:定义蛇与水果的初始状态
  16. 蛇的默认起始位置
  17. 蛇的身体块列表(初始长度为 4)
  18. 水果位置(随机生成,步长为 10)
  19. 默认方向
  20. 第四步:显示分数的功能函数
  21. 第五步:游戏结束处理函数
  22. 第六步:主游戏循环
  23. 进阶优化建议
  24. 1. 增加难度等级
  25. 2. 保存最高分
  26. 3. 添加音效
  27. 常见问题排查
  28. 总结

更多推荐文章

查看全部
  • Qwen-Image-Edit-2511 图像编辑模型特性及一致性提升解析
  • C++ 红黑树模拟实现
  • 前端函数防抖详解:原理、手写实现与实战应用
  • Xinference v1.17.1:在 Jupyter 中加载 Qwen、Llama3 及 Whisper 模型
  • UI UX Pro Max:打造懂设计的 AI 前端开发搭档
  • GitHub Copilot 提示词工程指南:从基础使用到高效协作
  • Flutter 实现 BIP340 Schnorr 签名适配鸿蒙 HarmonyOS
  • 前端弹窗遮罩层背景滚动穿透问题及三种解决方案
  • Java 后端面试八股文 30 天系统复习计划
  • 攻防世界 Web 安全挑战 easy_web SSTI 模板注入分析
  • 深入浅出 LangChain 与智能 Agent:构建下一代 AI 助手
  • OpenAI 指控 DeepSeek 非法蒸馏,字节发布 Seedance 2.0,Java 26 预览版来了
  • Spring Boot 调用 WebService 的两种实现方式:动态与静态调用
  • OpenPPT:基于 Web 的智能 PPT 在线编辑器
  • Liferay 主题开发核心知识点与自定义路径配置
  • Spring AOP 原理:代理模式与源码解析
  • C++ 模板编程入门:函数与类模板详解
  • 大模型智能助手项目实战与产品经验总结
  • Stack-Chan 机器人开发与使用指南
  • Python Tkinter Frame 核心解析与实战指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online