欢迎光临
我们一直在努力

我用 Seed Evolving 做了个 Python 版贪吃蛇游戏

上一篇我用 Seed Evolving 做了一个金价监控 Agent,这次想换一个轻松一点的方向:做一个 Python 版贪吃蛇小游戏。

因为它不只是“让模型写一段代码”,而是能完整体现 Seed Evolving 在一个小项目里的作用:拆需求、定规则、规划代码结构、补齐游戏循环、处理边界情况,最后生成一个能直接运行的小游戏。

在这里插入图片描述

一、我想做什么

我一开始给 Seed Evolving 的需求很简单:

我想用 Python 做一个贪吃蛇小游戏。
要求能控制蛇移动、吃食物加分、撞墙或撞到自己就结束。
代码最好适合新手阅读,能直接运行。

Seed Evolving 没有直接给我一大坨代码,而是先把需求拆成了几个模块:

  • 游戏窗口:用 Pygame 创建窗口和主循环。
  • 蛇的数据结构:用列表保存蛇头和蛇身坐标。
  • 方向控制:监听方向键或 WASD。
  • 食物生成:随机生成,不能出现在蛇身上。
  • 碰撞检测:撞墙或撞到自己就 Game Over。
  • 分数和重开:吃到食物加分,结束后按 R 重新开始。
  • 这一步很有用,因为小游戏最容易写着写着变成“所有逻辑都塞进 while True”。Seed Evolving 先把结构拆出来,后面写代码就顺很多。

    二、整体方案

    这次的工具结构可以理解成这样:

    Pygame 窗口

    事件监听:方向键 / WASD / 退出 / 重开

    游戏状态更新:蛇移动、吃食物、碰撞检测

    画面渲染:网格、蛇、食物、分数、结束提示

    Seed Evolving 在这里主要做了两类事。

    第一类是开发指导:

    • 建议用 Pygame 做 2D 小游戏。
    • 建议用“格子坐标”管理蛇和食物,而不是直接用像素坐标。
    • 建议把随机食物、绘制方块、重置游戏拆成函数。
    • 提醒我处理“反向移动”这个经典 bug。

    第二类是代码生成:

    • 生成基础游戏循环。
    • 生成键盘控制逻辑。
    • 生成蛇移动和吃食物逻辑。
    • 生成撞墙、撞身体、重开游戏逻辑。

    在这里插入图片描述

    三、准备环境

    这次只需要 Python 和 Pygame。

    pip install pygame

    运行方式:

    python seed_evolving_snake.py

    如果是在 VS Code 里,直接打开文件运行也可以。

    四、核心实现思路

    1. 用格子坐标管理游戏

    Seed Evolving 建议不要直接用像素坐标写蛇的位置,而是先定义“每个格子多大”,再让蛇在格子里移动。

    CELL_SIZE = 24
    COLS = 24
    ROWS = 20
    WIDTH = CELL_SIZE * COLS
    HEIGHT = CELL_SIZE * ROWS

    这样蛇头 (10, 8) 表示第 10 列、第 8 行,而不是屏幕上的具体像素点。绘制时再乘以 CELL_SIZE 就行。

    2. 用列表保存蛇身

    蛇的身体本质上就是一串坐标。列表第一个元素是蛇头,后面的元素是蛇身。

    snake = [
    (COLS // 2, ROWS // 2),
    (COLS // 2 1, ROWS // 2),
    (COLS // 2 2, ROWS // 2),
    ]
    direction = (1, 0)

    每次移动时,把新的蛇头插到列表最前面;如果没有吃到食物,就删掉最后一节身体。

    3. 随机生成食物

    食物不能出现在蛇身上,所以生成后要检查一下。

    def random_food(snake):
    while True:
    pos = (random.randint(0, COLS 1), random.randint(0, ROWS 1))
    if pos not in snake:
    return pos

    这段是 Seed Evolving 特别提醒我的地方:如果不判断 pos not in snake,食物可能直接刷在蛇身下面,看起来就像“凭空消失”。

    4. 处理方向控制

    方向控制除了监听按键,还要避免蛇直接反向。例如蛇正在向右走时,不能马上向左,否则会直接撞到自己。

    if event.key in (pygame.K_UP, pygame.K_w) and direction != (0, 1):
    direction = (0, 1)
    elif event.key in (pygame.K_DOWN, pygame.K_s) and direction != (0, 1):
    direction = (0, 1)
    elif event.key in (pygame.K_LEFT, pygame.K_a) and direction != (1, 0):
    direction = (1, 0)
    elif event.key in (pygame.K_RIGHT, pygame.K_d) and direction != (1, 0):
    direction = (1, 0)

    这个小判断看起来不起眼,但它是贪吃蛇里非常典型的边界问题。

    5. 移动、吃食物和碰撞

    游戏每一帧都会计算新的蛇头位置,然后判断是否撞墙、撞自己、吃到食物。

    head_x, head_y = snake[0]
    dx, dy = direction
    new_head = (head_x + dx, head_y + dy)

    hit_wall = new_head[0] < 0 or new_head[0] >= COLS or new_head[1] < 0 or new_head[1] >= ROWS
    hit_self = new_head in snake

    if hit_wall or hit_self:
    game_over = True
    else:
    snake.insert(0, new_head)
    if new_head == food:
    score += 1
    food = random_food(snake)
    else:
    snake.pop()

    Seed Evolving 给我的建议是:先把“死亡判断”放在前面,只有没死才更新蛇身。这样逻辑更清楚。

    五、实测效果

    运行后会出现一个深色背景的贪吃蛇窗口:

    • 方向键或 WASD 控制移动。
    • 吃到红色食物后加分。
    • 撞墙或撞到自己后显示 Game Over。
    • 游戏结束后按 R 可以重新开始。

    在这里插入图片描述

    在这里插入图片描述

    六、Seed Evolving 具体帮了什么

    这次我感觉 Seed Evolving 对小游戏开发的帮助主要在 4 个地方。

    1. 把需求拆成可实现模块

    一开始只是“做个贪吃蛇”,但 Seed Evolving 把它拆成窗口、蛇、食物、方向、碰撞、分数、重开几个模块。这个拆解让代码不会乱。

    2. 提醒我处理经典边界

    比如:

    • 食物不能生成在蛇身上。
    • 不能直接反向移动。
    • 撞墙和撞自己都要 Game Over。
    • 游戏结束后要能重开。

    这些都是小游戏里很容易漏掉的小细节。

    3. 让代码适合新手阅读

    我让 Seed Evolving 不要把代码写得太炫技,而是拆成几个函数:

    random_food()
    draw_grid()
    draw_block()
    reset_game()
    main()

    这样每个函数只做一件事,后面想改速度、颜色、窗口大小都比较方便。

    4. 帮我保留后续扩展空间

    这个版本是基础版,但后续可以继续扩展:

    • 加开始菜单。
    • 加难度选择。
    • 加最高分记录。
    • 加音效。
    • 加障碍物模式。
    • 加暂停功能。

    这也是我喜欢用 Seed Evolving 做小项目的原因:它不只是补全代码,还会帮你把下一步能怎么迭代想清楚。

    七、踩坑记录

    1. Pygame 坐标和格子坐标不要混用

    一开始最容易混的是像素坐标和格子坐标。后来我按 Seed Evolving 的建议统一用格子坐标保存状态,绘制时再转换成像素,代码就清楚很多。

    2. 反向移动一定要限制

    如果不限制反向移动,蛇向右走时按左键会直接撞到自己,游戏体验很怪。

    3. 食物不能刷在蛇身上

    这个问题肉眼不一定马上发现,但玩几轮就会遇到。所以 random_food() 里必须判断食物位置不在蛇身列表里。

    4. Game Over 后不要继续更新蛇身

    游戏结束后只负责等待退出或重开,不继续移动蛇,否则画面状态会越来越乱。

    总结

    这次用 Seed Evolving 做贪吃蛇,最大的感受是:它很适合帮我把一个小想法变成一个完整项目。

    它不是只生成一段代码,而是参与了整个过程:

    • 拆需求。
    • 设计数据结构。
    • 提醒边界情况。
    • 生成核心代码。
    • 保留后续扩展方向。

    贪吃蛇本身不复杂,但很适合练习“如何把一个小游戏做完整”。从这个角度看,Seed Evolving 像是一个会陪你把小项目一点点搭起来的编程助手。

    下一期如果继续做小游戏,我想试试用 Seed Evolving 做一个带关卡和道具的小游戏。

    附:完整代码

    import random
    import sys

    import pygame

    CELL_SIZE = 24
    COLS = 24
    ROWS = 20
    WIDTH = CELL_SIZE * COLS
    HEIGHT = CELL_SIZE * ROWS
    FPS = 10

    BG_COLOR = (18, 24, 38)
    GRID_COLOR = (30, 39, 58)
    SNAKE_COLOR = (68, 199, 123)
    SNAKE_HEAD_COLOR = (110, 231, 183)
    FOOD_COLOR = (248, 113, 113)
    TEXT_COLOR = (226, 232, 240)

    def random_food(snake):
    while True:
    pos = (random.randint(0, COLS 1), random.randint(0, ROWS 1))
    if pos not in snake:
    return pos

    def draw_grid(screen):
    for x in range(0, WIDTH, CELL_SIZE):
    pygame.draw.line(screen, GRID_COLOR, (x, 0), (x, HEIGHT))
    for y in range(0, HEIGHT, CELL_SIZE):
    pygame.draw.line(screen, GRID_COLOR, (0, y), (WIDTH, y))

    def draw_block(screen, pos, color):
    x, y = pos
    rect = pygame.Rect(x * CELL_SIZE + 2, y * CELL_SIZE + 2, CELL_SIZE 4, CELL_SIZE 4)
    pygame.draw.rect(screen, color, rect, border_radius=6)

    def draw_text(screen, font, text, x, y):
    image = font.render(text, True, TEXT_COLOR)
    screen.blit(image, (x, y))

    def reset_game():
    snake = [(COLS // 2, ROWS // 2), (COLS // 2 1, ROWS // 2), (COLS // 2 2, ROWS // 2)]
    direction = (1, 0)
    food = random_food(snake)
    score = 0
    game_over = False
    return snake, direction, food, score, game_over

    def main():
    pygame.init()
    pygame.display.set_caption("Seed Evolving Snake")
    screen = pygame.display.set_mode((WIDTH, HEIGHT + 56))
    clock = pygame.time.Clock()
    font = pygame.font.SysFont("Microsoft YaHei", 22)
    small_font = pygame.font.SysFont("Microsoft YaHei", 18)

    snake, direction, food, score, game_over = reset_game()

    while True:
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    pygame.quit()
    sys.exit()

    if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_r and game_over:
    snake, direction, food, score, game_over = reset_game()
    elif event.key in (pygame.K_UP, pygame.K_w) and direction != (0, 1):
    direction = (0, 1)
    elif event.key in (pygame.K_DOWN, pygame.K_s) and direction != (0, 1):
    direction = (0, 1)
    elif event.key in (pygame.K_LEFT, pygame.K_a) and direction != (1, 0):
    direction = (1, 0)
    elif event.key in (pygame.K_RIGHT, pygame.K_d) and direction != (1, 0):
    direction = (1, 0)

    if not game_over:
    head_x, head_y = snake[0]
    dx, dy = direction
    new_head = (head_x + dx, head_y + dy)

    hit_wall = new_head[0] < 0 or new_head[0] >= COLS or new_head[1] < 0 or new_head[1] >= ROWS
    hit_self = new_head in snake

    if hit_wall or hit_self:
    game_over = True
    else:
    snake.insert(0, new_head)
    if new_head == food:
    score += 1
    food = random_food(snake)
    else:
    snake.pop()

    screen.fill(BG_COLOR)
    draw_grid(screen)

    draw_block(screen, food, FOOD_COLOR)
    for index, part in enumerate(snake):
    draw_block(screen, part, SNAKE_HEAD_COLOR if index == 0 else SNAKE_COLOR)

    pygame.draw.rect(screen, (15, 23, 42), (0, HEIGHT, WIDTH, 56))
    draw_text(screen, font, f"Score: {score}", 16, HEIGHT + 14)
    draw_text(screen, small_font, "Arrow/WASD move | R restart", WIDTH 250, HEIGHT + 18)

    if game_over:
    overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
    overlay.fill((0, 0, 0, 150))
    screen.blit(overlay, (0, 0))
    draw_text(screen, font, "Game Over", WIDTH // 2 58, HEIGHT // 2 28)
    draw_text(screen, small_font, "Press R to restart", WIDTH // 2 72, HEIGHT // 2 + 8)

    pygame.display.flip()
    clock.tick(FPS)

    if __name__ == "__main__":
    main()

    赞(0)
    未经允许不得转载:171主机测评 » 我用 Seed Evolving 做了个 Python 版贪吃蛇游戏
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址