Python 开心消消乐


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

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

  • 专栏导航

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

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

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

    📒文章目录


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

效果图

项目结构

程序代码

run.py

python 复制代码
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

python 复制代码
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

python 复制代码
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

python 复制代码
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

python 复制代码
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💖点点关注,收藏不迷路💖 |

相关推荐
Null箘4 分钟前
从零创建一个 Django 项目
后端·python·django
云空8 分钟前
《解锁 Python 数据挖掘的奥秘》
开发语言·python·数据挖掘
青莳吖19 分钟前
Java通过Map实现与SQL中的group by相同的逻辑
java·开发语言·sql
Buleall26 分钟前
期末考学C
java·开发语言
重生之绝世牛码28 分钟前
Java设计模式 —— 【结构型模式】外观模式详解
java·大数据·开发语言·设计模式·设计原则·外观模式
小蜗牛慢慢爬行34 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
玖年40 分钟前
Python re模块 用法详解 学习py正则表达式看这一篇就够了 超详细
python
Algorithm157644 分钟前
云原生相关的 Go 语言工程师技术路线(含博客网址导航)
开发语言·云原生·golang
岑梓铭44 分钟前
(CentOs系统虚拟机)Standalone模式下安装部署“基于Python编写”的Spark框架
linux·python·spark·centos
shinelord明1 小时前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程