用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()
相关推荐
0zxm2 分钟前
06 - Django 视图view
网络·后端·python·django
ROBOT玲玉43 分钟前
Milvus 中,FieldSchema 的 dim 参数和索引参数中的 “nlist“ 的区别
python·机器学习·numpy
Kai HVZ2 小时前
python爬虫----爬取视频实战
爬虫·python·音视频
古希腊掌管学习的神2 小时前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
m0_748244832 小时前
StarRocks 排查单副本表
大数据·数据库·python
B站计算机毕业设计超人2 小时前
计算机毕业设计PySpark+Hadoop中国城市交通分析与预测 Python交通预测 Python交通可视化 客流量预测 交通大数据 机器学习 深度学习
大数据·人工智能·爬虫·python·机器学习·课程设计·数据可视化
路人甲ing..2 小时前
jupyter切换内核方法配置问题总结
chrome·python·jupyter
游客5202 小时前
opencv中的常用的100个API
图像处理·人工智能·python·opencv·计算机视觉
每天都要学信号2 小时前
Python(第一天)
开发语言·python
凡人的AI工具箱3 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite