python pygame实现贪食蛇

文章目录

很简单的一个例子,开启小游戏制作大门。

步骤

1、安装依赖

python 复制代码
pip install pygame
2、创建snake.py,然后运行即可

代码:

python 复制代码
import pygame
import time
import random

# --- 1. 初始化 Pygame ---
pygame.init()

# --- 2. 定义颜色 (RGB 格式) ---
WHITE = (255, 255, 255)
YELLOW = (255, 255, 102)
BLACK = (0, 0, 0)
RED = (213, 50, 80)
GREEN = (0, 255, 0)
BLUE = (50, 153, 213)

# --- 3. 设置屏幕尺寸 ---
dis_width = 600
dis_height = 400

dis = pygame.display.set_mode((dis_width, dis_height))
pygame.display.set_caption('Pygame 贪吃蛇案例')

# --- 4. 游戏时钟 (控制帧率) ---
clock = pygame.time.Clock()

# --- 5. 定义蛇的参数 ---
snake_block = 10  # 蛇身每一格的大小
snake_speed = 15  # 游戏速度

# --- 6. 设置字体 ---
# 尝试使用系统默认字体,如果失败则使用备用字体
font_style = pygame.font.SysFont("bahnschrift", 25)
score_font = pygame.font.SysFont("comicsansms", 35)


def your_score(score):
    """显示当前分数"""
    value = score_font.render("分数: " + str(score), True, YELLOW)
    dis.blit(value, [0, 0])


def our_snake(snake_block, snake_list):
    """绘制蛇身"""
    for x in snake_list:
        pygame.draw.rect(dis, GREEN, [x[0], x[1], snake_block, snake_block])


def message(msg, color):
    """显示游戏结束信息"""
    mesg = font_style.render(msg, True, color)
    # 将文字居中显示
    text_rect = mesg.get_rect(center=(dis_width / 2, dis_height / 2))
    dis.blit(mesg, text_rect)


def gameLoop():
    """游戏主循环"""
    game_over = False
    game_close = False

    # 蛇的初始位置 (屏幕中心)
    x1 = dis_width / 2
    y1 = dis_height / 2

    x1_change = 0
    y1_change = 0

    snake_List = []
    Length_of_snake = 1

    # 随机生成第一个食物位置
    foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0
    foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0

    while not game_over:

        # --- 游戏结束界面循环 ---
        while game_close == True:
            dis.fill(BLACK)
            message("游戏结束! 按Q-退出 或 C-重玩", RED)
            your_score(Length_of_snake - 1)
            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:
                        gameLoop()

        # --- 事件监听 (按键控制) ---
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x1_change = -snake_block
                    y1_change = 0
                elif event.key == pygame.K_RIGHT:
                    x1_change = snake_block
                    y1_change = 0
                elif event.key == pygame.K_UP:
                    y1_change = -snake_block
                    x1_change = 0
                elif event.key == pygame.K_DOWN:
                    y1_change = snake_block
                    x1_change = 0

        # --- 边界检测 ---
        if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0:
            game_close = True

        # 更新位置
        x1 += x1_change
        y1 += y1_change
        dis.fill(BLACK)  # 背景色

        # --- 绘制食物 ---
        pygame.draw.rect(dis, RED, [foodx, foody, snake_block, snake_block])

        # --- 蛇身逻辑 ---
        snake_Head = []
        snake_Head.append(x1)
        snake_Head.append(y1)
        snake_List.append(snake_Head)

        if len(snake_List) > Length_of_snake:
            del snake_List[0]

        # --- 自身碰撞检测 (吃到自己) ---
        for x in snake_List[:-1]:
            if x == snake_Head:
                game_close = True

        our_snake(snake_block, snake_List)
        your_score(Length_of_snake - 1)

        pygame.display.update()

        # --- 吃食物检测 ---
        if x1 == foodx and y1 == foody:
            foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0
            foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0
            Length_of_snake += 1

        clock.tick(snake_speed)

    pygame.quit()
    quit()


# 启动游戏
if __name__ == "__main__":
    gameLoop()

操作方式

按方向键即可运行起来。

如果game over了,按q键即可退出(如果q无效,看是否是英文模式)。

解读

1、初始化与设置:

pygame.init():必须首先调用,用于初始化所有 Pygame 模块。

snake_block = 10:定义了蛇身和食物的大小。

snake_speed = 15:控制游戏循环的速度,数值越大蛇跑得越快。
2、游戏主循环 (gameLoop):

这是游戏的心脏。只要 game_over 为 False,循环就会一直运行。

clock.tick(snake_speed):这行代码限制了循环每秒运行的次数,从而控制游戏速度。
3、事件监听:

通过 pygame.event.get() 获取用户的操作。

我们监听 pygame.KEYDOWN 事件来判断用户按下了哪个方向键,并改变蛇的坐标变化量 (x1_change, y1_change)。
4、蛇的移动原理:

蛇其实是一个坐标列表 (snake_List)。

每一帧,我们计算蛇头的新坐标,将其加入列表末尾。

如果蛇没有吃到食物,我们就删除列表的第一个元素(蛇尾),这样蛇看起来就在移动。

如果吃到了食物,就不删除蛇尾,蛇的长度自然就增加了。
5、碰撞检测:

撞墙:判断蛇头的坐标是否超出了屏幕的长宽。

撞自己:遍历蛇身列表,看蛇头坐标是否与身体任何一部分重合。

吃食物:判断蛇头坐标是否与食物坐标完全一致。

相关推荐
数据狐(Datafox)几秒前
一文读懂京东商品详情 API:返回字段解读与 JSON 样例
开发语言·数据库·爬虫·json
MoRanzhi12034 分钟前
第3篇 · 使用 PyQt5 实现 2048 桌面版游戏:MVC 架构与撤销和重做
python·mvc·pyqt5·桌面应用开发·gui开发·2048游戏·撤销与重做
蚰蜒螟8 分钟前
从 Java SocketChannel 到 TCP 挥手:一次 close() 的完整调用链与引用计数解析
java·python·tcp/ip
坤坤子吖11 分钟前
Linux 线程同步与互斥——条件变量与线程同步
linux·开发语言·c++·笔记·学习
damoluomu11 分钟前
国产 Java CMS 的协议和坑,讲清楚
java·开发语言
Wang's Blog19 分钟前
Java 项目实战: 交友项目 - 黑名单:分页查询黑名单
java·开发语言·交友
Smoothcloud润云19 分钟前
GPU算力平台跑知识库问答,模型回答总跑偏?先排查检索链路
人工智能·python·深度学习·gpu算力·gpu
mklpo14722 分钟前
python3:如何按照实际执行需求导入模块,而不是启动时统一导入?(Python3.15)。2026-10-20
开发语言·人工智能·python
蚰蜒螟23 分钟前
从 Java write 到磁盘扇区:一次写入操作的完整内核穿越之旅
java·开发语言
en.en..34 分钟前
volatile 关键字整理(嵌入式 C 标准)
java·开发语言