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