Python 开心消消乐
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
-
推荐:「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💖点点关注,收藏不迷路💖 |
相关文章:

Python 开心消消乐
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...
mysql - 索引基本知识梳理
mysql索引基本知识梳理 索引介绍 官方介绍索引是帮助MySQL高效获取数据的数据结构, 原理为以空间换时间, mysql的索引采用的是B树的结构 索引的优缺点 优点: 提高查询效率降低数据库IO成本通过索引对数据进行排序, 降低排序成本, 降低CPU消耗 缺点:…...
Nginx SSL/TLS配置:搭建安全的HTTPS网站
随着互联网安全性的日益提升,HTTPS已经成为网站安全通信的标配。Nginx作为一款高性能的HTTP和反向代理服务器,支持SSL/TLS协议,使得我们可以轻松地搭建安全的HTTPS网站。下面,我们将详细介绍如何在Nginx上配置SSL/TLS,…...
echarts 折线图流光效果偏移或不显示
x轴数据需要字符串数组...

Redis数据类型(上篇)
前提:(key代表键) Redis常用的命令 命令作用keys *查看当前库所有的keyexists key判断某个key是否存在type key查看key是什么类型del key 删除指定的keyunlink key非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的…...

VMware虚拟机安装Linux
1.下载Linux的ISO镜像文件 阿里镜像源网站: https://developer.aliyun.com/mirror/ 清华大学镜像源网站: https://mirrors.tuna.tsinghua.edu.cn/本人选择的是:Centos7.9.2009标准版 https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/isos/x86_64/ 标准版&a…...
slurm是什么,怎么用? For slurm和For Pytorch有什么区别和联系?
1.slurm是什么? Slurm(Simple Linux Utility for Resource Management)是一种开源的、用于集群和超级计算机的作业调度系统。它主要用于管理和调度大规模计算任务,使得用户可以有效地利用集群中的计算资源。Slurm提供了一套功能强…...

类和对象【六】友元和内部类
文章目录 友元友元的作用友元的缺点友元函数语法:特点: 友元类语法:特点: 内部类概念特点 友元 友元的作用 友元提供了一种打破封装的方式,有时提供了便利。 友元的主要作用就是打破封装 即可以让一个类的友元函数…...

一点点 cv 经验 1:cv方向、模型评估、输入尺寸、目标检测器设计
一点点 cv 经验 1:cv方向、模型评估、输入尺寸、目标检测器设计 cv 方向Pytorch数据集划分 模型评估误差偏差方差噪声 输入尺寸方法一:让数据适应模型方法二:修改模型适应数据方法三:划分Patch,分别处理 目标检测器结构…...
Java-SpringBoot集成Langchain4j文本嵌入模型实现向量相似度查询
集成Pg数据库并创建vector字段类型 运行pgvector容器 根据需要进行容器目录挂载 docker run --name pgvector \-e POSTGRES_PASSWORD123456 \-p 5432:5432 \-d --platform linux/amd64 ankane/pgvector:latest 进入docker容器并创建vector字段类型 docker exec -it pgvecto…...

正宇软件:引领数字人大新纪元,开启甘肃人大代表履职新篇章
在数字化强国的主旋律之下,政府工作的数字化、智能化转型已成为提升治理效能、增强人民满意度的关键一环。在这个大背景下,正宇软件技术开发有限公司以其卓越的技术实力和丰富的行业经验,成为了政府信息化建设的杰出代表。甘肃省人大代表履职…...
UniApp中,在页面显示时触发子组件的重新渲染
在UniApp中,要在页面显示时触发子组件的重新渲染,可以利用生命周期钩子函数来实现。具体来说,可以在页面的onShow生命周期钩子中调用子组件的方法或者改变子组件的props,从而触发子组件的重新渲染。 首先,确保子组件有…...

Linux(三)
Linux(三) Linux网络配置管理网络基础知识 IP地址A类 由1个字节网络地址3个字节主机地址B类 由2个字节网络地址2个主机地址C类 由3个字节网络地址1个主机地址D类:主要用于组播E类:为将来使用保留 子网掩码子网掩码作用网关DNS服务器 Linux用户管理用户的…...
2024年郫都区区级农业生产社会化服务重点服务组织评定申报条件材料、程序要求
第一章 总 则 第一条 为深入贯彻《中共中央办公厅 国务院办公厅关于促进小农户和现代农业发展有机衔接的意见》《农业农村部关于加快发展农业社会化服务的指导意见》精神,充分发挥农业生产社会化服务组织在引领现代农业发展、打造新时代更高水平“天府粮仓”郫都…...
Java入门须知术语
文章目录 前言JVM (Java Virtual Machine)JVM的组成部分JVM的作用为什么需要JVM JRE(Java Runtime Environment)JRE的组成部分JRE的作用为什么需要JRE JDK(Java Development Kit,Java开发工具包)JDK的组成部分JDK的作用…...
Spring Boot中集成WebSocket
目录 WebSocket简介WebSocket原理WebSocket的使用场景在Spring Boot中集成WebSocket 创建Spring Boot项目添加依赖配置WebSocket创建WebSocket处理器配置WebSocket端点前端使用WebSocket添加WebSocket拦截器 WebSocket简介 WebSocket是一种在单个TCP连接上进行全双工通信的…...
18.多分类问题代码实现
在机器学习中,多分类问题是一类常见的问题,它涉及到将输入数据划分为多个类别中的一个。例如,在图像识别中,我们可能需要将图像分为不同的类别,如手写数字识别(MNIST数据集)就是将手写数字图像分…...

实时通信的方式——WebRTC
文章目录 基于WebRTC实现音视频通话P2P通信原理如何发现对方? 不同的音视频编解码能力如何沟通?(媒体协商SDP)如何联系上对方?(网络协商) 常用的API音视频采集getUserMedia核心对象RTCPeerConne…...

Android 使用 ActivityResultLauncher 申请权限
前面介绍了 Android 运行时权限。 其中,申请权限的步骤有些繁琐,需要用到:ActivityCompat.requestPermissions 函数和 onRequestPermissionsResult 回调函数,今天就借助 ActivityResultLauncher 来简化书写。 步骤1:创…...

如何将前端项目打包并部署到不同服务器环境
学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学,可以点心心支持一下哈(笔记是根据b站尚硅谷的前端讲师【张天禹老师】整理的,用于自己复盘,有需要学习的可以去b站学习原版视频&…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...

EasyRTC音视频实时通话功能在WebRTC与智能硬件整合中的应用与优势
一、WebRTC与智能硬件整合趋势 随着物联网和实时通信需求的爆发式增长,WebRTC作为开源实时通信技术,为浏览器与移动应用提供免插件的音视频通信能力,在智能硬件领域的融合应用已成必然趋势。智能硬件不再局限于单一功能,对实时…...

【Vue】scoped+组件通信+props校验
【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性, 令样式只作用于当前组件的标签 作用:防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...

旋量理论:刚体运动的几何描述与机器人应用
旋量理论为描述刚体在三维空间中的运动提供了强大而优雅的数学框架。与传统的欧拉角或方向余弦矩阵相比,旋量理论通过螺旋运动的概念统一了旋转和平移,在机器人学、计算机图形学和多体动力学领域具有显著优势。这种描述不仅几何直观,而且计算…...
【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
Nginx 是什么:高性能的HTTP和反向代理Web服务器。怎么用:通过配置文件定义代理规则、负载均衡、静态资源服务等。为什么用:提升Web服务性能、高并发处理、负载均衡和反向代理。优缺点:轻量高效,但动态处理能力较弱&am…...