【游戏开发入门】用python实现贪吃蛇
一、前言
贪吃蛇是 Python 最经典的练手项目,非常适合新手理解:游戏主循环、坐标逻辑、碰撞检测、状态机、帧率控制。
市面上大多数贪吃蛇代码存在很多 Bug:
-
食物会刷新在蛇身上
-
蛇可以180度掉头瞬间自杀
-
游戏速度固定,可玩性差
-
递归重启容易栈溢出
-
蛇头蛇身颜色一致,观感差
本篇给大家带来修复全部 Bug、带动态加速、双色蛇身、安全重启、无bug食物生成的高质量升级版贪吃蛇。
代码完全可直接运行,结构规范,适合学习 & 写进项目简历。
二、完整可运行源码
import pygame
import random
import sys
# Initialize pygame
pygame.init()
# Game config
WIDTH, HEIGHT = 600, 400
BLOCK_SIZE = 20
INITIAL_SPEED = 10 # 初始速度(帧率)
MAX_SPEED = 20 # 最大速度(避免过快)
SPEED_INCREMENT = 1 # 每吃5个食物加速一次
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
DARK_GREEN = (0, 180, 0) # 蛇身分段颜色
BLUE = (0, 0, 255)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Snake Game")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 35)
def show_text(msg, color, x, y):
"""在屏幕指定位置显示文字"""
text = font.render(msg, True, color)
screen.blit(text, (x, y))
def spawn_food(snake_body):
"""生成不落在蛇身上的食物坐标"""
while True:
x = round(random.randrange(0, WIDTH - BLOCK_SIZE) / BLOCK_SIZE) * BLOCK_SIZE
y = round(random.randrange(0, HEIGHT - BLOCK_SIZE) / BLOCK_SIZE) * BLOCK_SIZE
# 检查是否与蛇身重叠
if [x, y] not in snake_body:
return x, y
def game_loop():
"""主游戏循环(每次重启都会全新开始)"""
# 蛇的初始状态
x, y = WIDTH // 2, HEIGHT // 2
dx, dy = 0, 0
snake_body = []
snake_len = 1
# 生成第一个食物
food_x, food_y = spawn_food(snake_body)
# 游戏状态标记
game_over = False
game_close = False
# 速度与加速控制
speed = INITIAL_SPEED
eat_count = 0 # 用于统计吃了几次食物,决定加速
while not game_over:
# ----- 游戏结束界面(暂停循环) -----
while game_close:
screen.fill(BLACK)
show_text("Game Over! Press C to Restart, Q to Quit", RED, 40, HEIGHT//2 - 30)
show_text(f"Final Score: {snake_len - 1}", WHITE, WIDTH//2 - 60, HEIGHT//2 + 10)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
game_over = True
game_close = False
if event.key == pygame.K_c:
return # 退出当前局,外层循环重启
if event.type == pygame.QUIT:
game_over = True
game_close = False
# ----- 事件处理(键盘输入) -----
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
# 防止蛇180度掉头自杀
if event.key == pygame.K_LEFT and dx == 0:
dx = -BLOCK_SIZE
dy = 0
elif event.key == pygame.K_RIGHT and dx == 0:
dx = BLOCK_SIZE
dy = 0
elif event.key == pygame.K_UP and dy == 0:
dy = -BLOCK_SIZE
dx = 0
elif event.key == pygame.K_DOWN and dy == 0:
dy = BLOCK_SIZE
dx = 0
# ----- 更新蛇头位置 -----
x += dx
y += dy
# ----- 墙壁碰撞检测 -----
if x < 0 or x >= WIDTH or y < 0 or y >= HEIGHT:
game_close = True
# 更新蛇身体
head = [x, y]
snake_body.append(head)
if len(snake_body) > snake_len:
del snake_body[0]
# ----- 自身碰撞检测 -----
for segment in snake_body[:-1]:
if segment == head:
game_close = True
# ----- 渲染画面 -----
screen.fill(BLACK)
# 绘制食物
pygame.draw.rect(screen, RED, (food_x, food_y, BLOCK_SIZE, BLOCK_SIZE))
# 绘制蛇(头亮绿、身深绿)
for i, segment in enumerate(snake_body):
color = GREEN if i == len(snake_body)-1 else DARK_GREEN
pygame.draw.rect(screen, color, (segment[0], segment[1], BLOCK_SIZE, BLOCK_SIZE))
# 显示信息
show_text(f"Score: {snake_len - 1}", WHITE, 10, 10)
show_text(f"Speed: {speed}", WHITE, 10, 40)
pygame.display.update()
# ----- 吃食物逻辑 + 动态加速 -----
if x == food_x and y == food_y:
snake_len += 1
eat_count += 1
# 每吃5个加速一次,不超过最大速度
if eat_count % 5 == 0 and speed < MAX_SPEED:
speed += SPEED_INCREMENT
food_x, food_y = spawn_food(snake_body)
clock.tick(speed)
pygame.quit()
sys.exit()
# 外层循环实现安全重启
if __name__ == "__main__":
while True:
game_loop()
三、模块技术讲解
1. 项目整体架构
本项目采用典型游戏循环架构:
-
事件监听(键盘、关闭窗口)
-
逻辑更新(移动、碰撞、吃食物、加速)
-
画面渲染(清空画布、绘图、刷新)
-
帧率控制
完全符合标准游戏开发思想,非常适合新手入门游戏开发。
2. 核心技术点:蛇移动原理
贪吃蛇移动并不是整体移动,而是经典的「增头删尾」算法:
-
每一帧在前进方向新增一个蛇头
-
没吃到食物 → 删除尾部,保持长度不变,实现前进
-
吃到食物 → 不删尾部,长度+1,实现变长
这是所有贪吃蛇游戏的通用底层算法。
3. 防自杀移动逻辑
普通代码会出现:向右走瞬间按左键直接反向撞死自己。
本次优化规则:
-
当前左右移动时,禁止直接左右反向
-
当前上下移动时,禁止直接上下反向
代码核心:dx == 0 / dy == 0 判断,保证移动方向只能垂直切换。
4. 安全食物生成
旧版本食物可能刷新在蛇身体上,导致开局自动加分。
优化方案:循环随机生成坐标,直到坐标不在蛇身体列表中才返回。
彻底解决食物重叠Bug。
5. 动态加速系统
-
初始速度:10
-
每吃5个食物速度+1
-
最大速度限制20,防止游戏过快无法游玩
让游戏难度平滑递增,可玩性大幅提升。
6. 双色蛇身视觉优化
通过遍历蛇身体下标:
-
最后一个元素 = 蛇头(亮绿色)
-
其余 = 身体(深绿色)
玩家可以清晰分辨前进方向,手感更舒服。
7. 安全重启机制(重点工程优化)
很多新手代码用「递归调用 game_loop()」重启,多次游戏会栈溢出崩溃。
本版本使用外层 while 死循环:
一局结束 return → 外层重新调用,永不栈溢出,工业级稳定。
四、游戏操作说明
-
上下左右方向键控制移动
-
吃到红色食物加分、变长、提速
-
撞墙 / 撞到身体游戏结束
-
C = 重新开始
-
Q = 退出游戏
五、学习总结
通过本项目可以掌握以下编程能力:
-
Pygame 窗口、渲染、事件系统
-
游戏主循环设计思想
-
坐标系统与2D运动逻辑
-
列表模拟动态身体结构
-
碰撞检测算法
-
游戏状态机设计(运行、结束)
-
Bug修复与项目优化思维
六、拓展方向
-
添加背景音乐、吃食物音效
-
添加障碍物地图
-
添加最高分本地存储
-
实现穿墙模式
-
增加道具、减速、无敌效果
更多推荐


所有评论(0)