用Python和Pygame实现简单贪吃蛇游戏

1.pip安装pygame

  • pygam插件安装

pip install 插件名字 # 安装

pip uninstall 插件名字 # 卸载

pip install 插件名字 -i 指定下载的镜像网址

pip show 插件名字 # 查看插件名字

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

pip show pygame

2.pygame入门

详细看教程

3.代码

python 复制代码
"""
# 0, 90, 180, 270
#下, 右 , 上 , 左
Snake类:
    __init__(): # 指定默认方向向右
    move(): # 让蛇根据当前方法进行移动(移动一格)
        # 当前蛇头前进的方向复制一份
        # 获取移动坐标,移动坐标更新
        # 把新的头放在最前面通过insert()
        # 把蛇尾移除掉
    draw(): # 根据移动方向,旋转舌头图片角度

Game类:
    # 合适位置移动,适当延时
"""
import random
import sys
import time

import pygame

# 全局变量
SCREEN_WIDTH = 640  # 屏幕宽度
SCREEN_HEIGHT = 480  # 屏幕高度

BLOCK_SIZE = 20  # 方格的宽、高长度

COLOR_GRAY = (150, 150, 150)  # 灰色
COLOR_GREEN = (0, 150, 0)  # 绿色
COLOR_WHITE = (255, 255, 255)  # 白色
COLOR_RED = (255, 0, 0)  # 红色

DIRECTION_MOVE = {
    pygame.K_DOWN: (0, 1),  # down
    pygame.K_RIGHT: (1, 0),  #right
    pygame.K_UP: (0, -1),  # up
    pygame.K_LEFT: (-1, 0)  # left
}
DIRECTION_HEAD_ANGLE = {
    pygame.K_DOWN: 0,
    pygame.K_RIGHT: 90,
    pygame.K_UP: 180,
    pygame.K_LEFT: 270
}


# 蛇类
class Snake:
    def __init__(self):
        # 设置初始方向为下
        self.direction = pygame.K_DOWN
        # 定义蛇身
        self.snake_body = [
            # x y 宽高
            pygame.Rect(3 * BLOCK_SIZE, 3 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
            pygame.Rect(2 * BLOCK_SIZE, 3 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
            pygame.Rect(1 * BLOCK_SIZE, 3 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
        ]
        # 加载头图片
        head_img = pygame.image.load("res/head-red.png")
        # head_img = pygame.transform.rotate(head_img, 90)
        # 设置 头img的图片 和大小
        self.head_img = pygame.transform.scale(head_img, (BLOCK_SIZE, BLOCK_SIZE))

    # 回之蛇
    def draw(self, screen):
        for node in self.snake_body[1:]:
            # 绘制矩形  pygame.draw.rect(画布,颜色,node:位置和大小 边框)
            pygame.draw.rect(screen, COLOR_WHITE, node, border_radius=3)
        # 设置头 旋转
        head_img = pygame.transform.rotate(self.head_img, DIRECTION_HEAD_ANGLE[self.direction])
        # 设置头
        snake_head = self.snake_body[0]
        screen.blit(head_img, (snake_head.x, snake_head.y))

    def move(self):
        # 复制头
        new_node = self.snake_body[0].copy()
        # 确定移动方向
        pos = DIRECTION_MOVE[self.direction]
        # 更新坐标
        new_node.x += (pos[0] * BLOCK_SIZE)
        new_node.y += (pos[1] * BLOCK_SIZE)
        # 变换头部节点
        self.snake_body.insert(0, new_node)
        self.snake_body.pop()

    def check_collision(self):
        # 检查蛇头是否碰到墙壁
        # 判断蛇头是否 超出边界
        if self.snake_body[0].x < 0 or self.snake_body[0].x >= SCREEN_WIDTH or \
                self.snake_body[0].y < 0 or self.snake_body[0].y >= SCREEN_HEIGHT:
            print("死亡")
            print(f"分数为{len(self.snake_body)-3}")
            return True
        # 检查蛇头是否碰到自己的身体
        for node in self.snake_body[1:]:
            if self.snake_body[0].colliderect(node):
                print("死亡")
                print(f"分数为{len(self.snake_body)-3}")
                return True
        return False

    def is_direction_enable(self, event_key):
        # 按键方向是否合法
        # 按键不是上下左右按键,返回False
        if event_key not in DIRECTION_MOVE:
            return False
        # 如果方向为左右,同时,蛇能左右掉头,返回False
        LR = (pygame.K_RIGHT, pygame.K_LEFT)
        if event_key in LR and self.direction in LR:
            return False
        # 如果方向为上下,同时,蛇能上下掉头,返回False
        UD = (pygame.K_DOWN, pygame.K_UP)
        if event_key in UD and self.direction in UD:
            return False
        return True
        # 上面条件都进不去,返回True

    def update_direction(self, event_key):
        self.direction = event_key
        # 更新移动的方向

    def grow(self):
        node = self.snake_body[-1].copy()
        self.snake_body.append(node)


class Food():
    def __init__(self):
        # 食物的随机x, y坐标,不要超出范围
        x = random.randint(0, SCREEN_WIDTH // BLOCK_SIZE - 1)
        y = random.randint(0, SCREEN_HEIGHT // BLOCK_SIZE - 1)
        self.f_rect = pygame.Rect((x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))

    def draw(self, screen):
        pygame.draw.rect(screen, COLOR_RED, self.f_rect, border_radius=3)


class Game():
    def __init__(self, title):
        self.title = title
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption(self.title)

        self.img = pygame.image.load("res/snake_logo.png")
        pygame.display.set_icon(self.img)
        bg_image = pygame.image.load("res/bg.png")
        self.bg_img = pygame.transform.scale(bg_image, (SCREEN_WIDTH, SCREEN_HEIGHT))

    def start(self):
        s = Snake()
        f = Food()
        while True:
            events = pygame.event.get()
            for event in events:
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYDOWN:

                    # s.direction = event.key
                    if s.is_direction_enable(event.key):
                        s.update_direction(event.key)

            self.screen.blit(self.bg_img, (0, 0))

            # ---------------绘制网格
            # 绘制所有横线 y = 640 // 20 = 24  [0, 20, 40, 60, ... 640)
            for y in range(0, SCREEN_HEIGHT, BLOCK_SIZE):
                pygame.draw.line(self.screen, COLOR_GRAY, (0, y), (SCREEN_WIDTH, y))
            # 绘制所有竖线 x = 480 // 20 = 24  [0, 20, 40, 60, ... 480)
            for x in range(0, SCREEN_WIDTH, BLOCK_SIZE):
                pygame.draw.line(self.screen, COLOR_GRAY, (x, 0), (x, SCREEN_HEIGHT))
            # 画蛇
            s.draw(self.screen)
            # 画食物
            f.draw(self.screen)

            pygame.display.update()
            if s.check_collision():
                pygame.quit()
                sys.exit()
            # 蛇移动
            s.move()
            # 判断是否吃到食物
            if s.snake_body[0] == f.f_rect:
                f = Food()
                # 身体加长
                s.grow()
            #             游戏节奏
            time.sleep(0.1)


game = Game("林安生贪吃蛇")
game.start()
相关推荐
炸炸鱼.17 分钟前
Python 操作 MySQL 数据库
android·数据库·python·adb
_深海凉_1 小时前
LeetCode热题100-颜色分类
python·算法·leetcode
AC赳赳老秦1 小时前
OpenClaw email技能:批量发送邮件、自动回复,高效处理工作邮件
运维·人工智能·python·django·自动化·deepseek·openclaw
zhaoshuzhaoshu1 小时前
Python 语法之数据结构详细解析
python
AI问答工程师2 小时前
Meta Muse Spark 的"思维压缩"到底是什么?我用 Python 复现了核心思路(附代码)
人工智能·python
zfan5203 小时前
python对Excel数据处理(1)
python·excel·pandas
小饕3 小时前
我从零搭建 RAG 学到的 10 件事
python
老歌老听老掉牙3 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
HAPPY酷4 小时前
游戏架构论:三大核心玩法组件如何构建“世界观容器”
游戏
格鸰爱童话4 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习