吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 748|回复: 10
收起左侧

[学习记录] 贪食蛇游戏代码

[复制链接]
zl2222 发表于 2024-9-16 13:57
import sys
import pygame
import random

WIDTH = 600
HEIGHT = 600


class Snake:
    def __init__(self, screen):
        self.screen = screen
        self.body = []  # 长度
        self.fx = pygame.K_RIGHT  # 方向
        self.init_body()

    def init_body(self, length=5):
        left, top = (0, 0)
        for i in range(5):
            if self.body:
                left, top = self.body[0].left, self.body[0].top
                node = pygame.Rect(left + 20, top, 20, 20)
            else:
                node = pygame.Rect(0, 0, 20, 20)  # 设置要绘画的正方形
            self.body.insert(0, node)

    def draw_snake(self):
        for n in self.body:
            pygame.draw.rect(self.screen, (62, 122, 178), n, 0)  # 绘制

    def add_node(self):
        if self.body:
            left, top = self.body[0].left, self.body[0].top
            if self.fx == pygame.K_RIGHT:
                left += 20
            elif self.fx == pygame.K_LEFT:
                left -= 20
            elif self.fx == pygame.K_UP:
                top -= 20
            else:
                top += 20
            node = pygame.Rect(left, top, 20, 20)
            self.body.insert(0, node)

    def del_node(self):
        self.body.pop()

    def move(self):
        self.del_node()
        self.add_node()

    def change(self, fx):
        LR = [pygame.K_LEFT, pygame.K_RIGHT]
        UD = [pygame.K_UP, pygame.K_DOWN]
        if fx in LR + UD:
            if fx in LR and self.fx in LR:
                return
            if fx in UD and self.fx in UD:
                return
            self.fx = fx

    def is_dead(self):
        if self.body[0].left not in range(WIDTH):
            return True
        if self.body[0].top not in range(HEIGHT):
            return True
        if self.body[0] in self.body[1:]:
            return True


class Food:
    def __init__(self):
        self.node = pygame.Rect(60, 80, 20, 20)
        self.flag = False

    def set(self):
        all_x_point = range(20, WIDTH - 20, 20)
        all_y_point = range(20, HEIGHT - 20, 20)
        left = random.choice(all_x_point)
        top = random.choice(all_y_point)
        self.node = pygame.Rect(left, top, 20, 20)
        self.flag = False

    def reset(self):
        self.flag = True


def show_text(screen, pos, text, color, font_bold=False, font_size=60, font_italic=False):
    # 获取系统字体,并设置文字大小
    cur_font = pygame.font.SysFont('arial', font_size)
    # 设置是否加粗属性
    cur_font.set_bold(font_bold)
    # 设置是否斜体属性
    cur_font.set_italic(font_italic)
    # 设置文字内容
    text_fmt = cur_font.render(text, 1, color)
    # 绘制文字
    screen.blit(text_fmt, pos)


def main():
    pygame.init()  # 初始化模块
    screen = pygame.display.set_mode([WIDTH, HEIGHT])  # 设置显示模块
    clock = pygame.time.Clock()  # 游戏帧数对象
    sk = Snake(screen)
    fd = Food()
    dead = False  # 标示蛇是否是死亡的

    while True:
        for e in pygame.event.get():  # 获取事件
            if e.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if e.type == pygame.KEYDOWN:
                sk.change(e.key)
                if e.key == pygame.K_SPACE:
                    sk = Snake(screen)
                    fd = Food()
                    dead = False

        screen.fill((255, 255, 255))
        # 画蛇
        sk.draw_snake()
        if not dead:
            # 蛇移动
            sk.move()
        # 判断是否死亡
        if sk.is_dead():
            # show_text(screen,(140,160),'你噶了!!!',(202,92,85),True,100)
            show_text(screen, (60, 200), 'game over', (202, 92, 85), True, 100)
            # show_text(screen,(100,300),'按空格重新开始',(116,181,103),False,font_size=30)
            show_text(screen, (180, 350), 'blank space  reset', (116, 181, 103), False, font_size=30)
            dead = True

        if fd.flag:
            # 放食物
            fd.set()
        pygame.draw.rect(screen, (231, 175, 95), fd.node, 0)
        # 吃食物
        if sk.body[0] == fd.node:
            sk.add_node()
            fd.reset()

        pygame.display.update()  # 更新显示
        clock.tick(5)


if __name__ == '__main__':
    main()

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
freckle + 1 + 1 谢谢@Thanks!
495flandre + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

freckle 发表于 2024-9-16 15:10
本帖最后由 freckle 于 2024-9-16 15:13 编辑

使用Fitten Code Chat优化了下
[Python] 纯文本查看 复制代码
import sys
import pygame
import random

# 游戏窗口的宽度和高度
WIDTH, HEIGHT = 600, 600
# 每个节点的大小
NODE_SIZE = 20


class Snake:
    def __init__(self, screen):
        self.screen = screen  # 游戏画面
        # 初始化蛇的身体为一个包含一个节点的列表
        self.body = [pygame.Rect(0, 0, NODE_SIZE, NODE_SIZE)]  # 长度
        # 蛇的移动方向,默认向右
        self.direction = pygame.K_RIGHT  
        self.init_body()  # 初始化蛇的身体

    def init_body(self, length=5):
        # 根据指定的长度初始化蛇的身体
        for i in range(1, length):
            new_node = self.body[0].copy()  # 复制蛇头
            new_node.left -= i * NODE_SIZE  # 计算新节点的位置
            self.body.append(new_node)  # 添加新节点到身体列表

    def draw(self):
        # 绘制蛇的每个节点
        for segment in self.body:
            pygame.draw.rect(self.screen, (62, 122, 178), segment)  # 绘制蛇的身体

    def add_segment(self):
        # 在蛇头位置添加一个新节点
        new_segment = self.body[0].copy()  # 复制蛇头
        # 根据当前方向移动新节点的位置
        if self.direction == pygame.K_RIGHT:
            new_segment.left += NODE_SIZE
        elif self.direction == pygame.K_LEFT:
            new_segment.left -= NODE_SIZE
        elif self.direction == pygame.K_UP:
            new_segment.top -= NODE_SIZE
        else:  # K_DOWN
            new_segment.top += NODE_SIZE
        self.body.insert(0, new_segment)  # 将新节点插入到蛇头的位置

    def move(self):
        # 移动蛇
        self.add_segment()  # 添加新节点
        self.body.pop()  # 删除尾部的节点

    def change_direction(self, new_direction):
        # 改变蛇的移动方向
        opposites = {
            pygame.K_LEFT: pygame.K_RIGHT, 
            pygame.K_RIGHT: pygame.K_LEFT,
            pygame.K_UP: pygame.K_DOWN, 
            pygame.K_DOWN: pygame.K_UP
        }
        # 禁止反向改变方向
        if new_direction in opposites and self.direction == opposites[new_direction]:
            return  
        self.direction = new_direction  # 更新方向

    def is_dead(self):
        # 检查蛇是否死亡
        head = self.body[0]  # 蛇头
        # 判断蛇头是否撞墙
        if not (0 <= head.left < WIDTH and 0 <= head.top < HEIGHT):
            return True
        # 判断蛇头是否撞到自己的身体
        if head in self.body[1:]:
            return True
        return False  # 蛇是活着的


class Food:
    def __init__(self):
        self.position = self.generate_food()  # 随机生成食物的位置

    def generate_food(self):
        # 随机生成食物的矩形区域
        x = random.randrange(1, (WIDTH // NODE_SIZE) - 1) * NODE_SIZE
        y = random.randrange(1, (HEIGHT // NODE_SIZE) - 1) * NODE_SIZE
        return pygame.Rect(x, y, NODE_SIZE, NODE_SIZE)  # 返回食物的位置矩形

    def reset(self):
        # 重置食物位置
        self.position = self.generate_food()  # 重新生成食物


def show_text(screen, pos, text, color, font_size=60, font_bold=False, font_italic=False):
    # 在屏幕上显示文字
    font = pygame.font.SysFont('arial', font_size, bold=font_bold, italic=font_italic)  # 设置字体
    text_surface = font.render(text, True, color)  # 渲染文字
    screen.blit(text_surface, pos)  # 将文字绘制到屏幕


def main():
    pygame.init()  # 初始化模块
    screen = pygame.display.set_mode((WIDTH, HEIGHT))  # 创建游戏窗口
    clock = pygame.time.Clock()  # 创建时钟对象以控制帧率
    snake = Snake(screen)  # 初始化蛇
    food = Food()  # 初始化食物
    game_over = False  # 游戏是否结束的标志

    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_SPACE and game_over:  # 如果按空格并且游戏结束
                    snake = Snake(screen)  # 重新初始化蛇
                    food = Food()  # 重新初始化食物
                    game_over = False  # 重置游戏状态
                else:
                    snake.change_direction(event.key)  # 改变蛇的方向

        screen.fill((255, 255, 255))  # 填充背景颜色为白色

        if not game_over:  # 如果游戏没有结束
            snake.move()  # 移动蛇
            if snake.body[0].colliderect(food.position):  # 判断蛇头是否碰到食物
                snake.add_segment()  # 增加蛇的长度
                food.reset()  # 重新生成食物
            game_over = snake.is_dead()  # 检查蛇是否死亡

        snake.draw()  # 绘制蛇
        pygame.draw.rect(screen, (231, 175, 95), food.position)  # 绘制食物

        if game_over:  # 如果游戏结束
            show_text(screen, (60, 200), 'game over', (202, 92, 85), 100)  # 显示游戏结束
            show_text(screen, (180, 350), 'press space to restart', (116, 181, 103), 30)  # 提示重新开始

        pygame.display.update()  # 更新屏幕
        clock.tick(10)  # 设置游戏运行帧率


if __name__ == '__main__':
    main()  # 执行主函数
lanjishu 发表于 2024-9-16 15:34
newGuy 发表于 2024-9-16 16:01
  File "D:\LPro\python\py_projects\project1\pythonProject\games\贪吃蛇\snake.py", line 2, in <module>
    import pygame
  File "D:\LPro\python\PythonJre\Lib\site-packages\pygame\__init__.py", line 291, in <module>
    import pygame.pkgdata
  File "D:\LPro\python\PythonJre\Lib\site-packages\pygame\pkgdata.py", line 25, in <module>
    from pkg_resources import resource_stream, resource_exists
  File "D:\LPro\python\PythonJre\Lib\site-packages\pkg_resources\__init__.py", line 2172, in <module>
    register_finder(pkgutil.ImpImporter, find_on_path)
                    ^^^^^^^^^^^^^^^^^^^
AttributeError: module 'pkgutil' has no attribute 'ImpImporter'. Did you mean: 'zipimporter'?
Koriki 发表于 2024-9-16 16:54
感谢分享,刚好需要
lopk666 发表于 2024-9-16 17:15
很厉害的了,学习了,感谢分享~
WJFCYLIB 发表于 2024-9-16 17:32
在哪里运行啊
Skylcue 发表于 2024-9-18 09:21
我复制试试,哈哈,看看能不能使
 楼主| zl2222 发表于 2024-9-25 17:30
freckle 发表于 2024-9-16 15:10
使用Fitten Code Chat优化了下
[mw_shl_code=python,true]import sys
import pygame

厉害 感觉方向好控制了
 楼主| zl2222 发表于 2024-9-25 17:31
newGuy 发表于 2024-9-16 16:01
File "D:\LPro\python\py_projects\project1\pythonProject\games\贪吃蛇\snake.py", line 2, in
    i ...

pip 包安装一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-5 06:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表