Python 开心消消乐

news2024/12/27 11:44:35

在这里插入图片描述
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
在这里插入图片描述

  • 推荐:「stormsha的主页」👈,持续学习,不断总结,共同进步,为了踏实,做好当下事儿~

  • 专栏导航

    • Python系列: Python面试题合集,剑指大厂
    • Git系列: Git操作技巧
    • GO系列: 记录博主学习GO语言的笔记,该笔记专栏尽量写的试用所有入门GO语言的初学者
    • 数据库系列: 详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 运维系列: 总结好用的命令,高效开发
    • 算法与数据结构系列: 总结数据结构和算法,不同类型针对性训练,提升编程思维

    非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

    💖The Start💖点点关注,收藏不迷路💖

    📒文章目录

    • 效果图
    • 项目结构
    • 程序代码


完整代码:https://gitcode.com/stormsha1/games/overview

效果图

消消乐

项目结构

在这里插入图片描述

程序代码

run.py

import sys  
import pygame  
from pygame.locals import KEYDOWN, QUIT, K_q, K_ESCAPE, MOUSEBUTTONDOWN  
from dissipate.level import Manager  
from dissipate.level_tree import LevelTreeManager  
from dissipate.sounds import Sounds  
  
  
class Game:  
    """  
    游戏主类,负责初始化和主循环  
    """  
    def __init__(self):  
        """  
        初始化游戏  
        """        pygame.init()  
        pygame.mixer.init()  
        pygame.display.set_caption('开心消消乐')  # 设置游戏窗口标题  
        pygame.mouse.set_visible(False)  # 隐藏鼠标指针  
  
        # 初始化游戏管理器和声音  
        self.tree = LevelTreeManager()  # 树管理器,用于主菜单  
        self.manager = Manager(0, 0)  # 游戏管理器,用于处理游戏逻辑  
        self.world_bgm = pygame.mixer.Sound(Sounds.WORLD_BGM.value)  # 世界背景音乐  
        self.game_bgm = pygame.mixer.Sound(Sounds.GAME_BGM.value)  # 游戏背景音乐  
  
        # 提高游戏性能的优化  
        self.get_events = pygame.event.get  # 获取事件的方法  
        self.update_window = pygame.display.flip  # 刷新窗口的方法  
  
        self.sound_sign = 0  # 用于控制背景音乐切换的标志  
  
    def run(self):  
        """主游戏循环"""  
        while True:  
            self.handle_music()  # 处理背景音乐  
            self.draw()  # 绘制游戏界面  
            self.handle_events()  # 处理用户输入事件  
            self.update()  # 更新显示  
  
    def handle_music(self):  
        """根据游戏级别管理背景音乐"""  
        if self.manager.level == 0:  
            if self.sound_sign == 0:  
                self.game_bgm.stop()  # 停止游戏背景音乐  
                self.world_bgm.play(-1)  # 循环播放世界背景音乐  
                self.sound_sign = 1  
        else:  
            if self.sound_sign == 1:  
                self.world_bgm.stop()  # 停止世界背景音乐  
                self.game_bgm.play(-1)  # 循环播放游戏背景音乐  
                self.sound_sign = 0  
  
    def draw(self):  
        """根据级别绘制相应的游戏界面"""  
        if self.manager.level == 0:  
            self.tree.draw_tree(self.manager.energy_num, self.manager.money)  # 绘制主菜单界面  
        else:  
            self.manager.set_level_mode(self.manager.level)  # 设置当前关卡模式  
            sprite_group = self.manager.draw()  # 绘制游戏关卡界面  
            if self.manager.type == 0:  
                self.manager.eliminate_animals()  # 消除动物  
                self.manager.death_map()  # 更新死亡地图  
                self.manager.swap(sprite_group)  # 处理交换逻辑  
            self.manager.judge_level()  # 判断关卡状态  
  
    def handle_events(self):  
        """处理用户输入事件"""  
        for event in self.get_events():  
            if event.type == KEYDOWN:  
                if event.key in (K_q, K_ESCAPE):  
                    sys.exit()  # 按下 Q 或 ESC 键退出游戏  
            elif event.type == QUIT:  
                sys.exit()  # 点击关闭按钮退出游戏  
            elif event.type == MOUSEBUTTONDOWN:  
                mouse_x, mouse_y = event.pos  # 获取鼠标点击位置  
                if self.manager.level == 0:  
                    self.tree.mouse_select(  
                        self.manager, mouse_x,  
                        mouse_y,  
                        self.manager.level,  
                        self.manager.energy_num,  
                        self.manager.money  
                    )  # 处理主菜单鼠标选择  
                self.manager.mouse_select(mouse_x, mouse_y)  # 处理游戏内鼠标选择  
  
    def update(self):  
        """  
        更新鼠标图像并刷新显示  
        :return:  
        """        self.manager.mouse_image()  # 更新鼠标图像  
        self.update_window()  # 刷新显示  
  
  
if __name__ == '__main__':  
    game = Game()  # 创建游戏实例  
    game.run()  # 启动游戏

level.py

import os  
from random import randint  
import pygame  
from pygame.locals import *  
from pygame.time import delay  
from dissipate.img import img_basic  
from dissipate.sounds import Sounds, play_sound  
from dissipate.sprites import Board, Element  
  
  
class Manager:  
    """Game manager."""  
    # 游戏屏幕的大小设置为900x600像素  
    __screen_size = (900, 600)  
    # 使用pygame库设置屏幕模式,DOUBLEBUF是双缓冲,32是位深度  
    screen = pygame.display.set_mode(__screen_size, DOUBLEBUF, 32)  
    # 砖块的大小设置为50x50像素  
    __brick_size = 50  
    # 加载背景图片并转换为优化格式  
    __bg = pygame.image.load(os.path.join(img_basic, 'bg.png')).convert()  
    # 停止宽度,可能用于游戏结束或暂停的界面  
    stop_width = 63  
    # 当前选中的砖块位置,格式为[row, col]  
    selected = [-1, -1]  
    # 交换标志,可能用于交换砖块或游戏逻辑  
    swap_sign = -1  
    # 上一次选中的砖块位置,格式为[row, col]  
    last_sel = [-1, -1]  
    # 是否交换的标志,用于判断是否发生了交换  
    value_swapped = False  
    # 死亡地图的标志,可能用于显示或隐藏死亡相关的游戏元素  
    death_sign = True  
    # 消除4个砖块时选中的位置,格式为[row, col]  
    boom_sel = [-1, -1]  
    # 当前关卡,0表示树(可能是特殊关卡或菜单)  
    level = 0  
    # 玩家的金钱数量  
    money = 100  
    # 能量点数  
    energy_num = 30  
    # 数字标志,可能用于显示或隐藏数字相关的游戏元素  
    num_sign = True  
    # 游戏类型,0为进行中,1为通过,-1为失败,2为树  
    type = 2  
    # 是否重置布局的标志  
    reset_mode = True  
    # 每个关卡的初始步数  
    init_step = 15  
    # 当前游戏剩余的步数  
    step = init_step  
    # 玩家的得分  
    score = 0  
    # 中等得分的两个阈值  
    min = 20  
    max = 50  
    # 已消除动物的数量列表,长度为6,可能代表6种不同的动物  
    animal_num = [0, 0, 0, 0, 0, 0]  
    # 剩余需要消除的冰块数量  
    ice_num = 0  
    # 成功板,继承自Board类,位置在[200, 0]  
    success_board = Board(Board.success, [200, 0])  
    # 失败板,继承自Board类,位置在[200, 0]  
    fail_board = Board(Board.fail, [200, 0])  
    # 游戏网格的高度和宽度,都是9  
    height, width = 9, 9  
    # 选中的行和列,初始值为5  
    row, col = 5, 5  
    # 冰块列表,21x21的二维列表,-1表示无冰块,1表示有冰块  
    ice_list = [[-1 for _ in range(21)] for _ in range(21)]  
    # 动物列表,21x21的二维列表,-2表示已消除,-1表示无动物,0-4表示不同的动物  
    animal = [[-1 for _ in range(21)] for _ in range(21)]  
    # 砖块的x和y位置列表,用于确定砖块在屏幕上的位置  
    list_x, list_y = (__screen_size[0] - 11 * __brick_size) / 2, (__screen_size[1] - 11 * __brick_size) / 2  
  
    def __init__(self, width, height):  
        self.height = height  
        self.width = width  
        self.list_x = (Manager.__screen_size[0] - self.width * Manager.__brick_size) / 2  
        self.list_y = (Manager.__screen_size[1] - self.height * Manager.__brick_size) / 2  
        self.row, self.col = Manager.xy_rc(self.list_x, self.list_y)  
        self.list_x, self.list_y = Manager.rc_xy(self.row, self.col)  
        self.ice_list = [[-1 for _ in range(21)] for _ in range(21)]  
        self.animal = [[-1 for _ in range(21)] for _ in range(21)]  
        self.reset_animals()  
  
    def reset_animals(self):  
        """  
        用于将游戏板上的动物随机重置为0到5之间的数字,  
        其中0可能表示没有动物,1到5表示不同类型的动物。  
        """        # 遍历由self.row和self.col确定的起始行和列,直到高度和宽度决定的结束行和列  
        for row in range(self.row, self.row + self.height):  
            # 对于每一行row,遍历由self.col和self.col + self.width确定的起始列和结束列  
            for col in range(self.col, self.col + self.width):  
                # 为当前位置(row, col)随机分配一个动物编号,编号范围从0到5  
                # randint是random模块中的一个函数,用于生成一个指定范围内的随机整数  
                self.animal[row][col] = randint(0, 5)  
  
    @staticmethod  
    def rc_xy(row, col):  
        """(row, col) -> (x, y)"""  
        return int(Manager.list_x + (col - Manager.col) * Manager.__brick_size), int \  
            (Manager.list_y + (row - Manager.row) * Manager.__brick_size)  
  
    @staticmethod  
    def xy_rc(x, y):  
        """(x, y) -> (row, col)"""  
        return int((y - Manager.list_y) / Manager.__brick_size + Manager.row), int \  
            ((x - Manager.list_x) / Manager.__brick_size + Manager.col)  
  
    @staticmethod  
    def draw_brick(x, y):  
        """Draw a brick at (x, y)."""  
        brick = Element(Element.brick, (x, y))  
        Manager.screen.blit(brick.image, brick.rect)  
  
    def draw_task(self, task_animal_num, which_animal, board_position=(400, 90), animal_position=(430, 35),  
                  txt_position=(455, 60)):  
        """  
        绘制任务板  
        """        txt_size = 24  
        txt_color = (0, 0, 0)  
        Board(Board.task_board, board_position).draw(self.screen)  
        if which_animal == 6:  
            task_animal = Element(Element.ice, animal_position)  
        else:  
            task_animal = Element(Element.animals[which_animal], animal_position)  
        task_animal.image = pygame.transform.smoothscale(task_animal.image, (40, 40))  
        task_animal.draw(self.screen)  
        if which_animal == 6:  
            if task_animal_num - self.ice_num <= 0:  
                Board(Board.ok, (txt_position[0], txt_position[1] + 15)).draw(self.screen)  
            else:  
                self.load_text(str(task_animal_num - self.ice_num), txt_position, txt_size, txt_color)  
        else:  
            if task_animal_num - self.animal_num[which_animal] <= 0:  
                Board(Board.ok, (txt_position[0], txt_position[1] + 15)).draw(self.screen)  
            else:  
                self.load_text(str(task_animal_num - self.animal_num[which_animal]), txt_position, txt_size, txt_color)  
  
    def draw(self):  
        """绘制背景、动物等元素。"""  
        # 绘制背景  
        self.screen.blit(Manager.__bg, (0, 0))  
        # 显示剩余步数  
        Board(Board.step_board, (0, 142)).draw(self.screen)  
        tens, single = divmod(self.step, 10)  
        if tens == 0:  
            Board(Board.num_format % single, (790, 110)).draw(self.screen)  
        else:  
            Board(Board.num_format % tens, (775, 110)).draw(self.screen)  
            Board(Board.num_format % single, (805, 110)).draw(self.screen)  
        # 显示关卡和暂停按钮  
        Board(Board.level_format % self.level, (30, 105)).draw(self.screen)  
        Element(Element.stop, Element.stop_position).draw(self.screen)  
  
        # 绘制砖块、冰块和动物  
        brick_group = pygame.sprite.Group()  
        animal_group = pygame.sprite.Group()  
        ice_group = pygame.sprite.Group()  
        for i in range(0, 21):  
            for j in range(0, 21):  
                x, y = Manager.rc_xy(i, j)  
                if self.animal[i][j] != -1:  
                    brick_group.add(Element(Element.brick, (x, y)))  
                    animal_group.add(Element(Element.animals[self.animal[i][j]], (x, y)))  
                if self.ice_list[i][j] != -1:  
                    ice_group.add(Element(Element.ice, (x, y)))  
        brick_group.draw(self.screen)  
        ice_group.draw(self.screen)  
        for animal_list in animal_group:  
            self.screen.blit(animal_list.image, animal_list.rect)  
        if self.level == 1:  
            self.draw_task(10, 4)  
        elif self.level == 2:  
            self.draw_task(21, 1)  
        elif self.level == 3:  
            self.draw_task(16, 4, (300, 90), (330, 35), (360, 60))  
            self.draw_task(16, 5, (500, 90), (530, 35), (560, 60))  
        elif self.level == 4:  
            self.draw_task(18, 5, (300, 90), (330, 35), (360, 60))  
            self.draw_task(18, 2, (500, 90), (530, 35), (560, 60))  
        elif self.level == 5:  
            self.draw_task(28, 2, (300, 90), (330, 35), (360, 60))  
            self.draw_task(28, 0, (500, 90), (530, 35), (560, 60))  
        elif self.level == 6:  
            self.draw_task(70, 4)  
        elif self.level == 7:  
            self.draw_task(36, 1)  
            self.draw_task(36, 2, (300, 90), (330, 35), (360, 60))  
            self.draw_task(36, 0, (500, 90), (530, 35), (560, 60))  
        elif self.level == 8:  
            self.draw_task(15, 6)  
        elif self.level == 9:  
            self.draw_task(49, 6)  
        else:  
            self.draw_task(39, 6)  
  
        # 显示选择的动物  
        if self.selected != [-1, -1]:  
            frame_sprite = Element(Element.frame, Manager.rc_xy(self.selected[0], self.selected[1]))  
            self.screen.blit(frame_sprite.image, frame_sprite.rect)  
  
        # 显示得分  
        self.load_text('得分:' + str(self.score), (300, 550), 30)  
        pygame.draw.rect(self.screen, (50, 150, 50, 180), Rect(300, 570, self.score * 2, 25))  
        pygame.draw.rect(self.screen, (100, 200, 100, 180), Rect(300, 570, 200, 25), 2)  
        return animal_group  
  
    def mouse_image(self):  
        # 加载鼠标图片  
        mouse_cursor = pygame.image.load(os.path.join(img_basic, 'mouse.png')).convert_alpha()  
        mouse_x, mouse_y = pygame.mouse.get_pos()  
        # 计算鼠标左上角位置  
        mouse_x -= mouse_cursor.get_width() / 2  
        mouse_y -= mouse_cursor.get_height() / 2  
        # 绘制鼠标图片  
        self.screen.blit(mouse_cursor, (mouse_x, mouse_y))  
  
    def mouse_select(self, mousex, mousey):  
        if self.type == 1:  # 已通关  
            if Board.button_position[0][0] < mousex < Board.button_position[0][0] + 100 \  
                    and Board.button_position[0][1] - 50 < mousey < Board.button_position[0][  
                1]:  # 点击重玩按钮  
                if self.energy_num < 5:  
                    self.level = 0  
                self.reset_mode = True  
            elif Board.button_position[1][0] < mousex < Board.button_position[1][0] + 100 \  
                    and Board.button_position[1][1] - 50 < mousey < Board.button_position[1][  
                1]:  # 点击下一关按钮  
                if self.level < 10:  
                    if self.energy_num < 5:  
                        self.level = 0  
                    else:  
                        self.level += 1  
                    self.reset_mode = True  
            elif 610 < mousex < 610 + 55 and 205 - 55 < mousey < 205:  # x  
                self.level = 0  
                self.reset_mode = True  
  
        elif self.type == -1:  # 未通过  
            if Board.button_position[1][0] < mousex < Board.button_position[1][0] + 100 \  
                    and Board.button_position[1][1] - 50 < mousey < Board.button_position[1][1]:  # 点击重玩按钮  
                if self.energy_num < 5:  
                    self.level = 0  
                self.reset_mode = True  
            elif Board.button_position[0][0] < mousex < Board.button_position[0][0] + 100 \  
                    and Board.button_position[0][1] - 50 < mousey < Board.button_position[0][  
                1]:  # 点击再来5步按钮  
                if self.money < 5:  
                    self.level = 0  
                else:  
                    self.money -= 5  
                    self.step += 5  
                    self.type = 0  # 正在游戏  
                    self.fail_board = Board(Board.fail, [200, 0])  
            elif 610 < mousex < 610 + 55 and 205 - 55 < mousey < 205:  
                self.level = 0  
                self.reset_mode = True  
  
        elif self.type == 0:  # 游戏中  
            if self.list_x < mousex < self.list_x + Manager.__brick_size * self.width \  
                    and self.list_y < mousey < self.list_y + Manager.__brick_size * self.height:  
                mouse_selected = Manager.xy_rc(mousex, mousey)  
                if self.animal[mouse_selected[0]][mouse_selected[1]] != -1:  
                    play_sound(Sounds.CLICK)  
                    self.selected = mouse_selected  
                    if (self.last_sel[0] == self.selected[0]  
                        and abs(self.last_sel[1] - self.selected[1]) == 1) \  
                            or (self.last_sel[1] == self.selected[1]  
                                and abs(self.last_sel[0] - self.selected[0]) == 1):  
                        self.swap_sign = 1  # 有效移动,交换  
            elif Element.stop_position[0] < mousex < Element.stop_position[0] + self.stop_width and \  
                    Element.stop_position[1] < mousey < Element.stop_position[1] + self.stop_width:  # 点击退出按钮  
                play_sound(Sounds.CLICK_BUTTON)  
                self.level = 0  
                self.reset_mode = True  
            else:  
                self.selected = [-1, -1]  
  
    def swap(self, group):  
        """在棋盘上交换两个选定的动物。"""  
        last_sprite = None  
        selected_sprite = None  
        if self.swap_sign == -1:  # 尚未交换  
            self.last_sel = self.selected  
        if self.swap_sign == 1:  
            last_x, last_y = Manager.rc_xy(self.last_sel[0], self.last_sel[1])  
            sel_x, sel_y = Manager.rc_xy(self.selected[0], self.selected[1])  
            if self.last_sel[0] == self.selected[0]:  # 纵向交换  
                for animal_list in group:  
                    if animal_list.rect.topleft == (last_x, last_y):  
                        last_sprite = animal_list  
                        last_sprite.speed = [self.selected[1] - self.last_sel[1], 0]  
                    elif animal_list.rect.topleft == (sel_x, sel_y):  
                        selected_sprite = animal_list  
                        selected_sprite.speed = [self.last_sel[1] - self.selected[1], 0]  
            else:  # 横向交换  
                for animal_list in group:  
                    if animal_list.rect.topleft == (last_x, last_y):  
                        last_sprite = animal_list  
                        last_sprite.speed = [0, self.selected[0] - self.last_sel[0]]  
                    elif animal_list.rect.topleft == (sel_x, sel_y):  
                        selected_sprite = animal_list  
                        selected_sprite.speed = [0, self.last_sel[0] - self.selected[0]]  
            while last_sprite and last_sprite.speed != [0, 0]:  
                delay(5)  
                self.draw_brick(last_x, last_y)  
                self.draw_brick(sel_x, sel_y)  
                last_sprite.move(last_sprite.speed)  
                selected_sprite.move(selected_sprite.speed)  
                self.screen.blit(last_sprite.image, last_sprite.rect)  
                self.screen.blit(selected_sprite.image, selected_sprite.rect)  
                pygame.display.flip()  
  
            self.swap_values()  
            if self.eliminate_animals():  
                self.step -= 1  
            else:  
                self.swap_values()  
            self.value_swapped = False  
            self.boom_sel = self.selected  
            self.swap_sign = -1  
            self.selected = [-1, -1]  
  
    def swap_values(self):  
        """交换值。"""  
        (xl, yl), (xc, yc) = self.last_sel, self.selected  
        self.animal[xl][yl], self.animal[xc][yc] = self.animal[xc][yc], self.animal[xl][yl]  
  
    def load_text(self, text, position, txt_size, txt_color=(255, 255, 255)):  
        """显示给定位置、大小和颜色的文本。"""  
        my_font = pygame.font.SysFont("黑体", txt_size)  
        text_screen = my_font.render(text, True, txt_color)  
        self.screen.blit(text_screen, position)  
  
    def death_map(self):  
        """检查是否没有有效的移动。"""  
        for i in range(self.row, self.row + self.height):  
            for j in range(self.col, self.col + self.width):  
                if self.animal[i][j] != -1:  
                    if self.animal[i][j] == self.animal[i][j + 1]:  
                        if (self.animal[i][j] in [self.animal[i - 1][j - 1], self.animal[i + 1][j - 1]] and  
                            self.animal[i][j - 1] != -1) or (  
                                self.animal[i][j] in [self.animal[i - 1][j + 2], self.animal[i + 1][j + 2]] and  
                                self.animal[i][j + 2] != -1):  
                            self.death_sign = False  
                            break                    if self.animal[i][j] == self.animal[i + 1][j]:  
                        if (self.animal[i][j] in [self.animal[i - 1][j - 1], self.animal[i - 1][j + 1]] and  
                            self.animal[i - 1][j] != -1) or (  
                                self.animal[i][j] in [self.animal[i + 2][j - 1], self.animal[i + 2][j + 1]] and  
                                self.animal[i + 2][j] != -1):  
                            self.death_sign = False  
                            break                    else:  
                        if self.animal[i - 1][j - 1] == self.animal[i][j]:  
                            if (self.animal[i][j] == self.animal[i - 1][j + 1] and self.animal[i - 1][j] != -1) or (  
                                    self.animal[i][j] == self.animal[i + 1][j - 1] and self.animal[i][j - 1] != -1):  
                                self.death_sign = False  
                                break                        if self.animal[i][j] == self.animal[i + 1][j + 1]:  
                            if (self.animal[i][j] == self.animal[i - 1][j + 1] and self.animal[i][j + 1] != -1) \  
                                    or (self.animal[i][j] == self.animal[i + 1][j - 1] and self.animal[i + 1][j] != -1):  
                                self.death_sign = False  
                                break        if self.death_sign:  
            delay(500)  
            Element(Element.none_animal, (230, 150)).draw(self.screen)  
            pygame.display.flip()  
            delay(500)  
            temp = [self.step, self.score, self.animal_num, self.ice_num, self.energy_num]  
            self.reset_mode = True  
            self.set_level_mode(self.level)  
            self.step = temp[0]  
            self.score = temp[1]  
            self.animal_num = temp[2]  
            self.ice_num = temp[3]  
            self.energy_num = temp[4]  
        else:  
            self.death_sign = True  
  
    def exists_left(self, i, j, num):  
        """检查 (i, j) 左边是否至少有 {num} 个连续的相同动物。"""  
        for t in range(0, num):  
            if self.animal[i][j] != self.animal[i][j - t] or self.animal[i][j] < 0:  
                return False  
        return True  
    def exists_right(self, i, j, num):  
        """检查 (i, j) 右边是否至少有 {num} 个连续的相同动物。"""  
        for t in range(0, num):  
            if self.animal[i][j] != self.animal[i][j + t] or self.animal[i][j] < 0:  
                return False  
        return True  
    def exists_up(self, i, j, num):  
        """检查 (i, j) 上方是否至少有 {num} 个连续的相同动物。"""  
        for t in range(0, num):  
            if self.animal[i][j] != self.animal[i - t][j] or self.animal[i][j] < 0:  
                return False  
        return True  
    def exists_down(self, i, j, num):  
        """检查 (i, j) 下方是否至少有 {num} 个连续的相同动物。"""  
        for t in range(0, num):  
            if self.animal[i][j] != self.animal[i + t][j] or self.animal[i][j] < 0:  
                return False  
        return True  
    def change_left(self, i, j, num):  
        """改变动物的左侧。"""  
        self.value_swapped = True  
        self.score += num  
        for k in range(0, int(num)):  
            self.animal[i][j - k] = -2  
  
    def change_right(self, i, j, num):  
        """改变动物的右侧。"""  
        self.value_swapped = True  
        self.score += num  
        for k in range(0, num):  
            self.animal[i][j + k] = -2  
  
    def change_up(self, i, j, num):  
        """改变动物上方。"""  
        self.value_swapped = True  
        self.score += num  
        for k in range(0, num):  
            self.animal[i - k][j] = -2  
  
    def change_down(self, i, j, num):  
        """改变动物下方。"""  
        self.value_swapped = True  
        self.score += num  
        for k in range(0, num):  
            self.animal[i + k][j] = -2  
  
    def eliminate_animals(self):  
        """消除动物。"""  
        score_level = self.score  
        self.value_swapped = False  
  
        for i in range(self.row, self.row + self.height):  
            for j in range(self.col, self.col + self.width):  
                if self.exists_right(i, j, 5):  
                    self.value_swapped = True  
                    if self.exists_down(i, j + 2, 3):  
                        self.animal_num[self.animal[i][j]] += 7  
                        Sounds.eliminate(5)  # 消除音效 5                        self.change_right(i, j, 5)  
                        self.change_down(i, j + 2, 3)  
                    else:  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_right(i, j, 5)  
                elif self.exists_right(i, j, 4):  
                    self.value_swapped = True  
                    if self.exists_down(i, j + 1, 3):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_right(i, j, 4)  
                        self.change_down(i, j + 1, 3)  
                    elif self.exists_down(i, j + 2, 3):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_right(i, j, 4)  
                        self.change_down(i, j + 2, 3)  
                    else:  
                        self.animal_num[self.animal[i][j]] += 4  
                        Sounds.eliminate(2)  # 消除音效 2                        self.change_right(i, j, 4)  
                elif self.exists_right(i, j, 3):  
                    self.value_swapped = True  
                    if self.exists_down(i, j, 3):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_right(i, j, 3)  
                        self.change_down(i, j, 3)  
                    elif self.exists_down(i, j + 1, 3):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_right(i, j, 3)  
                        self.change_down(i, j + 1, 3)  
                    elif self.exists_down(i, j + 2, 3):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_right(i, j, 3)  
                        self.change_down(i, j + 2, 3)  
                    else:  
                        self.animal_num[self.animal[i][j]] += 3  
                        Sounds.eliminate(1)  # 消除音效 1                        self.change_right(i, j, 3)  
                elif self.exists_down(i, j, 5):  
                    self.value_swapped = True  
                    if self.exists_right(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 7  
                        Sounds.eliminate(5)  # 消除音效 5                        self.change_down(i, j, 5)  
                        self.change_right(i + 2, j, 3)  
                    elif self.exists_left(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 7  
                        Sounds.eliminate(5)  # 消除音效 5                        self.change_down(i, j, 5)  
                        self.change_left(i + 2, j, 3)  
                    else:  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_down(i, j, 5)  
                elif self.exists_down(i, j, 4):  
                    self.value_swapped = True  
                    if self.exists_left(i + 1, j, 3):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_down(i, j, 4)  
                        self.change_left(i + 1, j, 3)  
                    elif self.exists_right(i + 1, j, 3):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_down(i, j, 4)  
                        self.change_right(i + 1, j, 3)  
                    elif self.exists_left(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_down(i, j, 4)  
                        self.change_left(i + 2, j, 3)  
                    elif self.exists_right(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_down(i, j, 4)  
                        self.change_right(i + 2, j, 3)  
                    else:  
                        self.animal_num[self.animal[i][j]] += 4  
                        Sounds.eliminate(2)  # 消除音效 2                        self.change_down(i, j, 4)  
                elif self.exists_down(i, j, 3):  
                    self.value_swapped = True  
                    if self.exists_left(i + 1, j, 3):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_down(i, j, 3)  
                        self.change_left(i + 1, j, 3)  
                    elif self.exists_right(i + 1, j, 3):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_down(i, j, 3)  
                        self.change_right(i + 1, j, 3)  
                    elif self.exists_left(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_down(i, j, 3)  
                        self.change_left(i + 2, j, 3)  
                    elif self.exists_right(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_down(i, j, 3)  
                        self.change_right(i + 2, j, 3)  
                    elif self.exists_left(i + 2, j, 2) and self.exists_right(i + 2, j, 2):  
                        self.animal_num[self.animal[i][j]] += 5  
                        Sounds.eliminate(3)  # 消除音效 3                        self.change_down(i, j, 3)  
                        self.change_left(i + 2, j, 2)  
                        self.change_right(i + 2, j, 2)  
                    elif self.exists_left(i + 2, j, 2) and self.exists_right(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_down(i, j, 3)  
                        self.change_left(i + 2, j, 2)  
                        self.change_right(i + 2, j, 3)  
                    elif self.exists_left(i + 2, j, 3) and self.exists_right(i + 2, j, 2):  
                        self.animal_num[self.animal[i][j]] += 6  
                        Sounds.eliminate(4)  # 消除音效 4                        self.change_down(i, j, 3)  
                        self.change_left(i + 2, j, 3)  
                        self.change_right(i + 2, j, 2)  
                    elif self.exists_left(i + 2, j, 3) and self.exists_right(i + 2, j, 3):  
                        self.animal_num[self.animal[i][j]] += 7  
                        Sounds.eliminate(5)  # 消除音效 5                        self.change_down(i, j, 3)  
                        self.change_left(i + 2, j, 3)  
                        self.change_right(i + 2, j, 3)  
                    else:  
                        self.animal_num[self.animal[i][j]] += 3  
                        Sounds.eliminate(1)  # 消除音效 1                        self.change_down(i, j, 3)  
  
        self.fall_animal()  
        score_level = self.score - score_level  # 计分级别  
  
        # 显示 & 朗读:好,棒,了不起,极好,令人难以置信  
        if score_level < 5:  
            return self.value_swapped  
        if score_level < 8:  # 5 好  
            Sounds.score_level(0)  
            Element(Element.score_level[0], (350, 250)).draw(self.screen)  
            pygame.display.flip()  
            delay(500)  
        elif score_level < 10:  # 8 棒  
            Sounds.score_level(1)  
            Element(Element.score_level[1], (350, 250)).draw(self.screen)  
            pygame.display.flip()  
            delay(500)  
        elif score_level < 15:  # 10 了不起  
            Sounds.score_level(2)  
            Element(Element.score_level[2], (350, 250)).draw(self.screen)  
            pygame.display.flip()  
            delay(500)  
        elif score_level < 20:  # 15 极好  
            Sounds.score_level(3)  
            Element(Element.score_level[3], (350, 250)).draw(self.screen)  
            pygame.display.flip()  
            delay(500)  
        elif score_level >= 20:  # 20 令人难以置信  
            Sounds.score_level(4)  
            Element(Element.score_level[4], (350, 250)).draw(self.screen)  
            pygame.display.flip()  
            delay(500)  
  
        return self.value_swapped  # 返回交换值标记  
  
    def fall_animal(self):  
        """动物下落动画。"""  
        clock = pygame.time.Clock()  
        position = []  
        ice_position = []  
  
        # 收集需要下落的动物的位置  
        for i in range(self.row, self.row + self.height):  
            for j in range(self.col, self.col + self.width):  
                if self.animal[i][j] == -2:  
                    x, y = self.rc_xy(i, j)  
                    position.append((x, y))  
                    if self.ice_list[i][j] == 1:  
                        ice_position.append((x, y))  
  
        # 下落动画  
        if position:  
            for index in range(0, 9):  
                clock.tick(20)  
                for pos in position:  
                    self.draw_brick(pos[0], pos[1])  
                    if pos in ice_position:  
                        Element(Element.ice_format % index, (pos[0], pos[1])).draw(self.screen)  
                    Element(Element.boom_format % index, (pos[0], pos[1])).draw(self.screen)  
                    pygame.display.flip()  
  
        # 实现下落  
        for i in range(self.row, self.row + self.height):  
            brick_position = []  
            fall_animal_list = []  
            speed = [0, 1]  
  
            # 收集需要下落的动物的位置信息  
            for j in range(self.col, self.col + self.width):  
                if self.animal[i][j] == -2:  
                    x, y = self.rc_xy(i, j)  
                    if self.ice_list[i][j] == 1:  
                        play_sound(Sounds.ICE_BREAKING)  
                        self.ice_num += 1  
                        self.ice_list[i][j] = -1  
  
                    brick_position.append((x, y))  
  
                    # 收集需要下落的动物的信息  
                    for m in range(i, self.row - 1, -1):  
                        if self.animal[m - 1][j] != -1:  
                            x, y = self.rc_xy(m - 1, j)  
                            brick_position.append((x, y))  
                            animal = Element(Element.animals[self.animal[m - 1][j]], (x, y))  
                            fall_animal_list.append(animal)  
                            self.animal[m][j] = self.animal[m - 1][j]  
                        else:  
                            self.animal[m][j] = randint(0, 5)  
                            break  
  
            # 动物下落实现  
            while speed != [0, 0] and fall_animal_list:  
                for position in brick_position:  
                    self.draw_brick(position[0], position[1])  
                for animal_sprite in fall_animal_list:  
                    animal_sprite.move(speed)  
                    animal_sprite.draw(self.screen)  
                    speed = animal_sprite.speed  
                pygame.display.flip()  
  
    def judge_next(self, tp, score):  
        """判断是否达到下一关。"""  
        if tp == 1:  # 通过  
            self.load_fns_window(score)  
        elif tp == -1:  # 失败  
            self.load_fail_window()  
  
    def load_fail_window(self):  
        """显示失败界面和按钮。"""  
        sound_sign = 0  
        step_add = Board(Board.step_add, Board.button_position[0])  # 左侧:再来5步  
        retry = Board(Board.replay, Board.button_position[1])  # 右侧:重玩  
        self.screen.blit(self.fail_board.image, self.fail_board.rect)  # 失败界面  
        self.screen.blit(step_add.image, step_add.rect)  
        self.screen.blit(retry.image, retry.rect)  
        while self.fail_board.speed != [0, 0]:  
            self.draw()  
            self.screen.blit(self.fail_board.image, self.fail_board.rect)  
            self.fail_board.move()  
            pygame.display.flip()  
            if sound_sign == 0:  
                play_sound(Sounds.BOARD_SOUND)  
                sound_sign = 1  
  
    def load_fns_window(self, score):  
        """显示成功界面、分数和按钮。"""  
        sound_sign = 0  
        replay = Board(Board.replay, Board.button_position[0])  # 左侧:重玩  
        self.screen.blit(self.success_board.image, self.success_board.rect)  # 成功界面  
        if self.level < 10:  # 如果不是最后一关  
            next_level = Board(Board.next, Board.button_position[1])  # 右侧:下一关  
            self.screen.blit(next_level.image, next_level.rect)  
        self.screen.blit(replay.image, replay.rect)  
        while self.success_board.speed != [0, 0]:  
            self.draw()  
            self.screen.blit(self.success_board.image, self.success_board.rect)  
            self.success_board.move()  
            pygame.display.flip()  
            if sound_sign == 0:  
                play_sound(Sounds.BOARD_SOUND)  
                sound_sign = 1  
        self.displayStars(score)  # 显示星星  
        # 金币  
        self.load_text(str(self.score * 2), (Board.starts_position[0][0] + 75, Board.starts_position[0][0] + 46), 20,  
                       (0, 0, 0))  
  
    def displayStars(self, score):  
        """根据分数显示星星。"""  
        star1 = Board(Board.stars, Board.starts_position[0])  
        star2 = Board(Board.stars, Board.starts_position[1])  
        star3 = Board(Board.stars, Board.starts_position[2])  
        if 0 <= score < self.min:  
            self.load_text('1', (Board.starts_position[1][0] + 48, Board.starts_position[1][1] + 35), 20, (0, 0, 0))  
            self.screen.blit(star1.image, star1.rect)  
        elif self.min <= score <= self.max:  
            self.load_text('2', (Board.starts_position[1][0] + 48, Board.starts_position[1][1] + 35), 20, (0, 0, 0))  
            self.screen.blit(star1.image, star1.rect)  
            self.screen.blit(star2.image, star2.rect)  
        elif score > self.max:  
            self.load_text('5', (Board.starts_position[1][0] + 48, Board.starts_position[1][1] + 35), 20, (0, 0, 0))  
            self.screen.blit(star1.image, star1.rect)  
            self.screen.blit(star2.image, star2.rect)  
            self.screen.blit(star3.image, star3.rect)  
        pygame.display.flip()  
  
    def set_level_mode(self, level):  
        """设置关卡模式及其步骤。"""  
        self.level = level  
        if self.reset_mode:  # 如果需要重置模式  
            self.num_sign = True  
            if level == 1:  
                self.__init__(7, 7)  
                self.animal[7][9] = self.animal[7][10] = self.animal[7][11] = self.animal[8][10] = self.animal[11][7] = \  
                    self.animal[11][13] = self.animal[12][7] = self.animal[12][8] = self.animal[12][12] = \  
                    self.animal[12][13] = \  
                    self.animal[13][7] = self.animal[13][8] = self.animal[13][9] = self.animal[13][11] = \  
                    self.animal[13][12] = \  
                    self.animal[13][13] = -1  
                self.init_step = 17  # 初始步骤17  
            elif level == 2:  
                self.__init__(4, 8)  
                self.init_step = 16  # 初始步骤16  
            elif level == 3:  
                self.__init__(7, 7)  
                self.init_step = 18  # 初始步骤18  
            elif level == 4:  
                self.__init__(9, 7)  
                row, col = self.row, self.col  
                self.animal[row][col] = self.animal[row][col + 7] = self.animal[row][col + 8] = self.animal[row + 1][  
                    col + 8] = \  
                    self.animal[row + 5][col] = self.animal[row + 6][col] = self.animal[row + 6][col + 1] = \  
                    self.animal[row + 6][col + 8] = -1  
                self.init_step = 20  
            elif level == 5:  
                self.__init__(8, 9)  
                row, col = self.row, self.col  
                self.animal[row][col + 7] = self.animal[row + 2][col] = self.animal[row + 5][col] = \  
                    self.animal[row + 3][col + 7] = \  
                    self.animal[row + 6][col + 7] = self.animal[row + 8][col] = -1  
                self.init_step = 20  
            elif level == 6:  
                self.__init__(9, 9)  
                row, col = self.row, self.col  
                self.animal[row][col] = self.animal[row][col + 8] = self.animal[row + 2][col + 4] = \  
                    self.animal[row + 3][col + 2] = \  
                    self.animal[row + 3][col + 6] = self.animal[row + 8][col] = self.animal[row + 8][col + 8] = -1  
                for i in range(row + 4, row + 6):  
                    for j in range(col + 3, col + 6):  
                        self.animal[i][j] = -1  
                self.init_step = 28  
            elif level == 7:  
                self.__init__(9, 9)  
                row, col = self.row, self.col  
                for i in range(row, row + 9):  
                    self.animal[i][col + 4] = -1  
                for j in range(col, col + 4):  
                    self.animal[row + 3][j] = -1  
                for j in range(col + 5, col + 9):  
                    self.animal[row + 5][j] = -1  
                self.init_step = 25  
            elif level == 8:  
                self.__init__(7, 8)  
                row, col = self.row, self.col  
                for i in range(row + 2, row + 5):  
                    for j in range(col + 1, col + 6):  
                        self.ice_list[i][j] = 1  
                self.init_step = 21  
            elif level == 9:  
                self.__init__(9, 9)  
                row, col = self.row, self.col  
                self.animal[row][col + 4] = self.animal[row + 4][col] = self.animal[row + 4][col + 8] = \  
                    self.animal[row + 8][col + 4] = -1  
                for i in range(row + 1, row + 8):  
                    for j in range(col + 1, col + 8):  
                        self.ice_list[i][j] = 1  
                self.init_step = 35  
            else:  
                self.__init__(9, 9)  
                row, col = self.row, self.col  
                for i in range(row, row + 2):  
                    for j in range(col, col + 9):  
                        self.animal[i][j] = -1  
                self.animal[row][col + 4] = randint(0, 5)  
                self.animal[row + 1][col + 2] = randint(0, 5)  
                self.animal[row + 1][col + 4] = randint(0, 5)  
                self.animal[row + 1][col + 6] = randint(0, 5)  
                self.animal[row + 2][col + 1] = self.animal[row + 3][col + 1] = self.animal[row + 2][col + 3] = \  
                    self.animal[row + 3][col + 3] = \  
                    self.animal[row + 2][col + 5] = self.animal[row + 3][col + 5] = self.animal[row + 2][col + 7] = \  
                    self.animal[row + 3][col + 7] = self.animal[row + 8][col] = self.animal[row + 8][col + 8] = -1  
                for i in range(row + 4, row + 8):  
                    for j in range(col, col + 9):  
                        self.ice_list[i][j] = 1  
                self.ice_list[row + 2][col + 4] = self.ice_list[row + 3][col + 2] = self.ice_list[row + 3][col + 4] = \  
                    self.ice_list[row + 3][col + 6] = 1  
                self.init_step = 40  
            self.type = 0  
            self.energy_num -= 5  
            self.success_board = Board(Board.success, [200, 0])  # 成功的面板  
            self.fail_board = Board(Board.fail, [200, 0])  # 失败的面板  
            self.step = self.init_step  
            self.score = 0  
            self.animal_num = [0, 0, 0, 0, 0, 0]  
            self.ice_num = 0  
            self.reset_mode = False  
  
    def num_add(self):  
        """增加得分"""  
        if self.num_sign:  
            self.money += self.score * 2  
            if self.score < self.min:  
                self.energy_num += 1  
            elif self.score < self.max:  
                self.energy_num += 2  
            else:  
                self.energy_num += 5  
            self.num_sign = False  
  
    def judge_level(self):  
        """检查关卡是否通过"""  
        if self.step <= 0:  
            self.type = -1  # 游戏结束  
        if self.level == 1:  
            if self.animal_num[4] >= 10:  # L1: 10 只青蛙  
                self.type = 1  # 通过第一关  
                self.num_add()  
        elif self.level == 2:  
            if self.animal_num[1] >= 21:  # L2: 21 只熊  
                self.type = 1  # 通过第二关  
                self.num_add()  
        elif self.level == 3:  
            if self.animal_num[4] >= 16 and self.animal_num[5] >= 16:  # L3: 16 只青蛙和 16 头牛  
                self.type = 1  # 通过第三关  
                self.num_add()  
        elif self.level == 4:  
            if self.animal_num[5] >= 18 and self.animal_num[2] >= 18:  # L4: 18 头牛和 18 只小鸡  
                self.type = 1  # 通过第四关  
                self.num_add()  
        elif self.level == 5:  
            if self.animal_num[2] >= 28 and self.animal_num[0] >= 28:  # L5: 28 只小鸡和 28 只狐狸  
                self.type = 1  # 通过第五关  
                self.num_add()  
        elif self.level == 6:  
            if self.animal_num[4] >= 70:  # L6: 70 只青蛙  
                self.type = 1  # 通过第六关  
                self.num_add()  
        elif self.level == 7:  
            if self.animal_num[2] >= 36 and self.animal_num[1] >= 36 \  
                    and self.animal_num[0] >= 36:  # L7: 36 只小鸡、36 只熊和 36 只狐狸  
                self.type = 1  # 通过第七关  
                self.num_add()  
        elif self.level == 8:  
            if self.ice_num >= 15:  # L8: 15 冰块  
                self.type = 1  # 通过第八关  
                self.num_add()  
        elif self.level == 9:  
            if self.ice_num >= 49:  # L9: 49 冰块  
                self.type = 1  # 通过第九关  
                self.num_add()  
        else:  
            if self.ice_num >= 39:  # L10: 39 冰块  
                self.type = 1  # 通过第十关  
                self.num_add()  
  
        self.judge_next(self.type, self.score)

level_tree.py

import pygame  
from pygame import DOUBLEBUF  
from pygame.time import delay  
  
from dissipate.sounds import play_sound, Sounds  # 导入声音播放功能和声音资源  
from dissipate.sprites import Tree  # 导入关卡树的类  
  
  
class LevelTreeManager:  
    """  
    关卡树管理器类,用于管理关卡树及其相关功能。  
    """    __screen_size = (900, 600)  # 屏幕尺寸  
    screen = pygame.display.set_mode(__screen_size, DOUBLEBUF, 32)  # 设置屏幕显示模式  
    fruit_list = []  # 用于存储水果对象的列表  
    fruit_image = pygame.image.load(Tree.fruit).convert_alpha()  # 加载水果图片  
    fruit_width = fruit_image.get_width()  # 获取水果图片宽度  
    fruit_height = fruit_image.get_height()  # 获取水果图片高度  
    type = 0  # 场景类型,0 表示关卡树场景,1 表示能量场景  
    energy_full = False  # 能量已满标志  
    money_empty = False  # 金钱不足标志  
  
    def display_text(self, text, position, txt_size=25, txt_color=(255, 255, 255)):  
        """  
        显示指定的文本内容。  
        参数:  
        text: 要显示的文本  
        position: 文本位置  
        txt_size: 文本大小  
        txt_color: 文本颜色  
        """        my_font = pygame.font.SysFont(None, txt_size)  # 创建字体对象  
        text_screen = my_font.render(text, True, txt_color)  # 渲染文本  
        self.screen.blit(text_screen, position)  # 在屏幕上绘制文本  
  
    def draw_tree(self, energy_num, money_num):  
        """  
        绘制游戏中的关卡树和相关资源。  
        参数:  
        energy_num: 当前能量值  
        money_num: 当前金钱数量  
        """        Tree(Tree.tree, (0, 600)).draw(self.screen)  # 绘制关卡树  
        Tree(Tree.energy_num, Tree.energy_num_position).draw(self.screen)  # 绘制能量数  
        if energy_num > 30:  
            self.display_text(str(30) + '/30', (22, 55), 21)  # 显示最大能量值  
        else:  
            self.display_text(str(energy_num) + '/30', (22, 55), 21)  # 显示当前能量值  
        Tree(Tree.money, (15, 135)).draw(self.screen)  # 绘制金钱  
        self.display_text(str(money_num), (32, 124), 21)  # 显示当前金钱数量  
        for i in range(0, 10):  # 绘制水果  
            Tree(Tree.fruit, Tree.position[i]).draw(self.screen)  
            self.display_text(str(i + 1), (Tree.position[i][0] + 15, Tree.position[i][1] - 47))  
        if self.type == 1:  
            Tree(Tree.energy_buy, Tree.energy_buy_position).draw(self.screen)  # 绘制购买能量按钮  
            if self.energy_full:  
                self.display_text('energy is full!', (430, 310), 30, (255, 0, 0))  # 显示能量已满提示  
                pygame.display.flip()  # 更新屏幕显示  
                delay(500)  # 延迟500毫秒  
                self.energy_full = False  # 重置能量已满标志  
            if self.money_empty:  
                self.display_text('money is not enough!', (410, 310), 30, (255, 0, 0))  # 显示金钱不足提示  
                pygame.display.flip()  # 更新屏幕显示  
                delay(500)  # 延迟500毫秒  
                self.money_empty = False  # 重置金钱不足标志  
  
    def mouse_select(self, mgr, mouse_x, mouse_y, level, energy_num, money_num):  
        """  
        处理鼠标事件。  
        参数:  
        mgr: 管理器对象  
        mouse_x: 鼠标x坐标  
        mouse_y: 鼠标y坐标  
        level: 当前等级  
        energy_num: 当前能量值  
        money_num: 当前金钱数量  
        """        if self.type == 0:  # 关卡树场景  
            for i in range(0, 10):  
                if Tree.position[i][0] < mouse_x < Tree.position[i][0] + self.fruit_width \  
                        and Tree.position[i][1] - self.fruit_height < mouse_y < Tree.position[i][1]:  
                    if energy_num <= 0:  
                        self.type = 1  # 切换到能量场景  
                    else:  
                        level = i + 1  # 更新等级  
            if Tree.energy_num_position[0] < mouse_x < Tree.energy_num_position[0] + 60 \  
                    and Tree.energy_num_position[1] - 60 < mouse_y < Tree.energy_num_position[1]:  # 点击能量图标  
                play_sound(Sounds.CLICK)  # 播放点击音效  
                self.type = 1  # 切换到能量场景  
        else:  # 能量场景  
            if 408 < mouse_x < 600 and 263 < mouse_y < 313:  # 点击“购买能量”按钮  
                play_sound(Sounds.CLICK_BUTTON)  # 播放点击按钮音效  
                if money_num < 50:  
                    self.money_empty = True  # 金钱不足标志设为真  
                if energy_num >= 30:  
                    self.energy_full = True  # 能量已满标志设为真  
                elif energy_num < 30 and money_num >= 50:  
                    energy_num += 5  # 增加能量  
                    money_num -= 50  # 减少金钱  
            elif 619 < mouse_x < 638 and 158 < mouse_y < 177:  # 点击“X”按钮  
                self.type = 0  # 切换回关卡树场景  
        mgr.level, mgr.energy_num, mgr.money = level, energy_num, money_num  # 更新管理器对象中的等级、能量和金钱信息

sprites.py

import os  
from pygame.sprite import Sprite  
from pygame.image import load  
  
from dissipate.img import img_basic, img_energy, img_board, img_text, img_level, img_button, img_animal, img_ice, \  
    img_boom  
  
  
# 基类,GameSprite类定义了所有游戏精灵的基类,包括加载图像、设置位置和绘制方法。  
class GameSprite(Sprite):  
    def __init__(self, icon, position):  
        # 初始化GameSprite类,继承自pygame的Sprite类。  
        super().__init__()  
        # 加载图像并转换为具有透明通道的格式。  
        self.image = load(icon).convert_alpha()  
        # 获取图像的矩形区域。  
        self.rect = self.image.get_rect()  
        # 设置精灵的位置。  
        self.rect.topleft = position  
        self.rect.bottomleft = position  
  
    def draw(self, screen):  
        # 将精灵绘制到屏幕上。  
        screen.blit(self.image, self.rect)  
  
  
class Tree(GameSprite):  
    """  
    关卡树类,显示关卡树和相关资源。  
    """    # 树、果实、能量数字、金钱和购买能量按钮的图像路径。  
    tree = os.path.join(img_basic, 'tree.png')  
    fruit = os.path.join(img_basic, 'fruit.png')  
    energy_num = os.path.join(img_energy, 'num.png')  
    money = os.path.join(img_basic, 'money.png')  
    energy_buy = os.path.join(img_energy, 'buy.png')  
  
    # 树、果实、能量数字、购买能量按钮的位置定义。  
    x, y = 340, 510  
    h = 90  
    position = (  
        [x, y],  
        [x + 50, y - 25],  
        [x + 105, y - 45],  
        [x - 5, y - h - 5],  
        [x + 55, y - 25 - h + 10],  
        [x + 105, y - 45 - h],  
        [x, y - h * 2],  
        [x + 50 + 10, y - 25 - h * 2 - 5],  
        [x + 105 + 25, y - 45 - h * 2 - 14],  
        [x + 30, y - h * 3 - 30]  
    )  # 果实位置  
    energy_num_position = (15, 70)  # 能量位置  
    energy_buy_position = (250, 400)  # 购买能量位置  
  
    def __init__(self, icon, position):  
        """  
        初始化树对象  
        """        # 重写GameSprite的构造函数,用于初始化树对象。  
        super().__init__(icon, position)  
        self.image = load(icon).convert_alpha()  
        self.rect = self.image.get_rect()  
        self.rect.bottomleft = position  
  
  
class Board(GameSprite):  
    """  
    游戏面板类,显示游戏面板和相关资源。  
    Board类继承自GameSprite类,用于创建和显示游戏板的精灵,并包含移动逻辑。  
    """    # 游戏板、数字格式、任务板、成功、失败、下一步、重玩、星星、金钱的图像路径。  
    step_board = os.path.join(img_board, 'step.png')  
    num_format = os.path.join(img_text, '%d.png')  
    task_board = os.path.join(img_basic, 'task.png')  
    ok = os.path.join(img_basic, 'ok.png')  
    level_format = os.path.join(img_level, '%d.png')  
    success = os.path.join(img_board, 'success.png')  
    fail = os.path.join(img_board, 'fail.png')  
    step_add = os.path.join(img_button, 'step_add.png')  
    next = os.path.join(img_button, 'next.png')  
    replay = os.path.join(img_button, 'replay.png')  
    stars = os.path.join(img_basic, 'star.png')  
    money = os.path.join(img_basic, 'money.png')  
  
    # 按钮和星星的位置定义。  
    button_position = [[300, 465], [500, 465]]  
    starts_position = [[330, 340], [413, 340], [495, 340]]  
  
    def __init__(self, icon, position):  
        """  
        初始化板对象  
        """        super().__init__(icon, position)  
        # 重写GameSprite的构造函数,用于初始化板对象。  
        self.image = load(icon).convert_alpha()  
        self.speed = [0, 44]  # 初始速度  
        self.rect = self.image.get_rect()  
        self.rect.bottomleft = position  
  
    def move(self):  
        """  
        根据速度移动面板  
        """        self.rect = self.rect.move(self.speed)  
        if self.rect.bottom >= 543:  # 到达底部边界  
            self.speed = [0, -45]  
        if self.speed == [0, -45] and self.rect.bottom <= 450:  # 到达顶部边界  
            self.speed = [0, 0]  
  
  
class Element(GameSprite):  
    """  
    Element类继承自GameSprite类,用于创建和显示游戏中元素的精灵,并包含移动逻辑。  
    """    # 动物、冰、砖块、框架、爆炸数字、冰的数字格式、分数等级、无动物、退出的图像路径。  
    animals = (  
        os.path.join(img_animal, 'fox.png'),  
        os.path.join(img_animal, 'bear.png'),  
        os.path.join(img_animal, 'chick.png'),  
        os.path.join(img_animal, 'eagle.png'),  
        os.path.join(img_animal, 'frog.png'),  
        os.path.join(img_animal, 'cow.png')  
    )  
    ice = os.path.join(img_ice, 'normal.png')  
    brick = os.path.join(img_basic, 'brick.png')  
    frame = os.path.join(img_basic, 'frame.png')  
    boom_format = os.path.join(img_boom, '%d.png')  
    ice_format = os.path.join(img_ice, '%d.png')  
  
    # 分数图片  
    score_level = (  
        os.path.join(img_text, 'good.png'),  
        os.path.join(img_text, 'great.png'),  
        os.path.join(img_text, 'amazing.png'),  
        os.path.join(img_basic, 'excellent.png'),  
        os.path.join(img_basic, 'unbelievable.png')  
    )  
    none_animal = os.path.join(img_basic, 'none_animal.png')  
    stop = os.path.join(img_basic, 'exit.png')  
    stop_position = (20, 530)  
  
    def __init__(self, icon, position):  
        """  
        初始化元素对象  
        """        # 重写GameSprite的构造函数,用于初始化元素对象。  
        super().__init__(icon, position)  
        self.image = load(icon).convert_alpha()  
        self.rect = self.image.get_rect()  
        self.rect.topleft = position  
        self.speed = [0, 0]  # 初始速度  
        self.init_position = position  # 初始位置  
  
    def move(self, speed):  
        """  
        以给定速度移动元素  
        """        self.speed = speed  
        self.rect = self.rect.move(self.speed)  
        if self.speed[0] != 0:  # 水平移动  
            if abs(self.rect.left - self.init_position[0]) == self.rect.width:  
                self.init_position = self.rect.topleft  
                self.speed = [0, 0]  
        else:  # 垂直移动  
            if abs(self.rect.top - self.init_position[1]) == self.rect.height:  
                self.init_position = self.rect.topleft  
                self.speed = [0, 0]

sounds.py

from enum import Enum  
from pygame.mixer import Sound  
from dissipate.sound import *  
  
  
# 声音枚举类,用于管理和播放游戏中的各种声音  
class Sounds(Enum):  
    GAME_BGM = os.path.join(sound_basic, 'GameSceneBGM.ogg')  # 游戏场景背景音乐  
    WORLD_BGM = os.path.join(sound_basic, 'WorldSceneBGM.ogg')  # 世界场景背景音乐  
    ELIMINATE_FORMAT = os.path.join(sound_eliminate, '%d.ogg')  # 消除音效格式  
    SCORE_LEVEL = (  
        os.path.join(sound_basic, 'good.ogg'),  # 分数等级 "好"  
        os.path.join(sound_basic, 'great.ogg'),  # 分数等级 "很好"  
        os.path.join(sound_basic, 'amazing.ogg'),  # 分数等级 "惊人"  
        os.path.join(sound_basic, 'excellent.ogg'),  # 分数等级 "优秀"  
        os.path.join(sound_basic, 'unbelievable.ogg')  # 分数等级 "难以置信"  
    )  
    CLICK = os.path.join(sound_basic, 'click.bubble.ogg')  # 点击气泡音效  
    BOARD_SOUND = os.path.join(sound_basic, 'board.ogg')  # 板子音效  
    CLICK_BUTTON = os.path.join(sound_basic, 'click_common_button.ogg')  # 点击按钮音效  
    MONEY = os.path.join(sound_basic, 'money.ogg')  # 金钱音效  
    ICE_BREAKING = os.path.join(sound_basic, 'ice_break.ogg')  # 冰块破碎音效  
  
    @staticmethod  
    def eliminate(idx):  
        """播放指定索引的消除音效"""  
        Sound(Sounds.ELIMINATE_FORMAT.value % idx).play()  
  
    @staticmethod  
    def score_level(idx):  
        """播放指定索引的分数等级音效"""  
        Sound(Sounds.SCORE_LEVEL.value[idx]).play()  
  
  
def play_sound(sound: Enum):  
    """播放指定声音,循环次数为1(即不循环)"""  
    Sound(sound.value).play()

完整代码:https://gitcode.com/stormsha1/games/overview


🔥🔥🔥道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

💖The End💖点点关注,收藏不迷路💖

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1700346.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

硬盘录像机DVR如何连接到外网的视频监控接入网关(国标网关)

目录 一、要求 二、工作准备 三、接入 1、查看SIP服务器ID号和相关国标对接参数&#xff0c;如下&#xff1a; 2、DVR国标参数配置 3、进行连接 &#xff08;1&#xff09;设备接入 &#xff08;2&#xff09;配置通道 &#xff08;3&#xff09;通道接入 &#xff0…

蓝桥杯算法心得——李白打酒(加强版)

大家好&#xff0c;我是晴天学长&#xff0c;记忆化搜索&#xff0c;找到技巧非常重要&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 2) .算法思路 1.memo三维表示记录的结果 3&#xff09;.算法步骤 1…

[ FreeRTOS 基础知识] RTOS 背景介绍

文章目录 RTOS简介IOTOSFreertos简介RTOS划分 RTOS简介 &#xff08;1&#xff09;实时操作系统&#xff0c;本用于追求实时性的嵌入式系统。 典型&#xff1a;ucos、uclinux、vxworks &#xff08;实时性的指当事件产生的时候&#xff0c;需要花多久的时间做出响应。&#xf…

俄罗斯半导体领域迈出坚实步伐:首台光刻机诞生,目标直指7纳米工艺

近日&#xff0c;国外媒体纷纷报道&#xff0c;俄罗斯在半导体技术领域取得了重要突破&#xff0c;首台光刻机已经制造完成并正在进行严格的测试阶段。这一里程碑式的事件标志着俄罗斯在自主发展半导体技术的道路上迈出了坚实的一步。 据俄罗斯联邦工业和贸易部副部长瓦西里-什…

【电源专题】功率电感器啸叫原因及典型案例

啸叫产生的原因 声波是在空气中传播的弹性波,人的可听到的频率范围大约20~20kHz。在DC-DC转换器的功率电感器中,当流过人耳可听范围频率的交流电流以及脉冲波时,电感器主体会发生振动,该现象称为"线圈噪音",有时也称为啸叫。 啸叫一般是由电感器产生,…

cmake使用交叉编译工具链并验证

目录 一、内容 二、配置 1. 准备cmake文件 2. 使用交叉编译 三、验证 1. 构建阶段验证 2. 编译阶段验证 一、内容 目的&#xff1a;在X86环境下编译ARM平台软件 编写交叉编译配置文件&#xff1a;xx.cmake 执行cmake命令时指定&#xff1a;cmake \ -DCMAKE_TOOLCHAIN_F…

什么是容器:从基础到进阶的全面介绍

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

【JavaEE初阶】HTTP协议|HTTP请求|URL基本格式|URLencode

&#x1f4a1;推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击跳转到网站】 HTTP请求(Request) 认识URL URL基本格式 平时我们俗称的"⽹址"其实就是说的URL(Uniform Resource Loc…

Linux内核重置root密码

Ubuntu 首先重新启动Ubuntu系统&#xff0c;然后快速按下shift键&#xff0c;以调出grub启动菜单在这里我们选择第二个&#xff08;Ubuntu高级选项&#xff09;&#xff0c;选中后按下Enter键 选择最高的Linux内核版本所对应的recovery mode模式&#xff0c;按e键编辑启动项 在…

【JavaEE初阶】网络初识|局域网和广域网|交换机和路由器|IP地址|端口号

&#x1f4a1;推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击跳转到网站】 关键概念 1.局域网LAN和广域网WAN &#xff08;1&#xff09;局域⽹&#xff0c;即Local Area Network&#xff0…

云界洞见——基于移动云云数据库MySQL应用实践

目录 简介1 新手入门1.1 创建MySQL实例1.2 公网连接MySQL实例 2 操作指南2.1 创建数据库2.2 数据备份设置2.3 日志管理2.4 监控告警2.5 代码审计 3 应用场景4 总结 如今&#xff0c;大型企业如金融企业和银行等&#xff0c;在下一代的微服务架构转型要求下&#xff0c;需要基础…

C++的数论相关算法

数论是数学的一个分支&#xff0c;主要研究整数的性质和关系。在计算机科学中&#xff0c;数论算法对于密码学、优化问题和算法分析等方面都具有重要作用。C作为一种高效的编程语言&#xff0c;非常适合用来实现这些算法。下面我们将介绍几个C中的数论相关算法&#xff0c;包括…

linux入门到精通-第十九章-libevent(开源高性能事件通知库)

目录 参考什么是libevent应用核心实现libevent的地基event_base等待事件产生&#xff0c;循环监听event_loop退出循环监听event_base_loopexit创建事件工作流程 安装一&#xff08;源码安装&#xff0c;推荐&#xff09;现在源码配置编译安装验证安装 安装二&#xff08;可能因…

【记忆空间】 史上最详细,移动固态硬盘,西数BLACK D30拆解,测评,外观与内饰解析。第一期:外观与内饰。

【记忆空间】 史上最详细&#xff0c;移动固态硬盘&#xff0c;西数BLACK D30拆解&#xff0c;测评&#xff0c;外观与内饰解析。第一期&#xff1a;外观与内饰。 外观实拍&#xff0c;正面&#xff0c;整体黑色&#xff0c;外壳是一个塑料的材质。 外观实拍&#xff1a;侧面…

Android Studio开发之路(十四)自定义Titlebar以及设置顶部状态栏颜色

一、描述 项目需求&#xff0c;我要做一个下图这样的titlebar,包括一个返回按钮&#xff0c;一个关闭按钮&#xff0c;一个文本框。默认的titlebar按钮设计不太满足我的需求&#xff0c;于是我打算自定义一个titlebar组件&#xff0c;应用到我的每一个页面 二、titlebar组件设…

新计划,不断变更!做自己,接受不美好!猪肝移植——早读(逆天打工人爬取热门微信文章解读)

时间不等人 引言Python 代码第一篇 做自己&#xff0c;没有很好也没关系第二篇结尾 引言 新计划&#xff1a; 早上一次性发几个视频不现实 所以更改一下 待后面有比较稳定的框架再优化 每天早上更新 早到8点 晚到10点 你刚刚好上班或者上课 然后偷瞄的看两眼 学习一下 补充知…

HCIP-Datacom-ARST自选题库__BGP判断【20道题】

1.传统的BGP-4只能管理IPV4单播路由信息&#xff0c;MP-BGP为了提供对多种网络层协议的支持&#xff0c;对BGP-4进行了扩展。其中MP-BGP对IPv6单播网络的支持特性称为BGP4&#xff0c;BGP4通过Next Hop属性携带路由下一跳地址信息。 2.BGP4通过Update报文中的Next Hop属性携带…

C++之运算符重载

在C中&#xff0c;运算符重载是一种特殊的函数&#xff0c;它允许程序员重新定义或重载大部分内置运算符&#xff0c;以便它们可以用于用户自定义的数据类型。通过运算符重载&#xff0c;可以使自定义类型的使用更加直观和自然。 不是所有运算符都可以被重载&#xff1a; .&a…

聊聊变异测试

软件质量保障 所寫即所思&#xff5c;一个阿里质量人对测试的所感所悟。 1. 介绍 有句话说&#xff1a;证实容易&#xff0c;证伪难。正如测试一样&#xff0c;证明缺陷存在容易&#xff0c;但证明不存在缺陷难。而变异测试颠覆了这一原则&#xff0c;如果我们知道存在缺陷&am…

ARM+FPGA+NVIDIA AI摄像头软硬件定制

拥有资深ISP图像技术团队&#xff0c;是英伟达、地平线等合作伙伴&#xff0c;我们的团队掌握目前市面上大部分车载平台的ISP图像画质服务能力&#xff0c;能自主开发图像ISP和增强算法。我们具有多名经验丰富光学设计专家&#xff0c;掌握车载模组光学设计能力&#xff0c;资深…