From 50d1218493a56686cb59cb6892edb2eeb9950af6 Mon Sep 17 00:00:00 2001 From: Tipragot Date: Fri, 3 Nov 2023 09:56:14 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20d'un=20syst=C3=A8me=20de=20sons=20multi?= =?UTF-8?q?ples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../click0.wav => assets/global/click/0.wav | Bin .../click1.wav => assets/global/click/1.wav | Bin .../click2.wav => assets/global/click/2.wav | Bin src/plugins/assets.py | 9 ++-- src/plugins/sound.py | 43 ++++++++++++++++++ src/scenes/__init__.py | 5 ++ src/scenes/base_game.py | 16 +++++-- src/scenes/menu.py | 9 ++-- 8 files changed, 70 insertions(+), 12 deletions(-) rename assets save/sounds/click/click0.wav => assets/global/click/0.wav (100%) rename assets save/sounds/click/click1.wav => assets/global/click/1.wav (100%) rename assets save/sounds/click/click2.wav => assets/global/click/2.wav (100%) diff --git a/assets save/sounds/click/click0.wav b/assets/global/click/0.wav similarity index 100% rename from assets save/sounds/click/click0.wav rename to assets/global/click/0.wav diff --git a/assets save/sounds/click/click1.wav b/assets/global/click/1.wav similarity index 100% rename from assets save/sounds/click/click1.wav rename to assets/global/click/1.wav diff --git a/assets save/sounds/click/click2.wav b/assets/global/click/2.wav similarity index 100% rename from assets save/sounds/click/click2.wav rename to assets/global/click/2.wav diff --git a/src/plugins/assets.py b/src/plugins/assets.py index b952546..188357d 100644 --- a/src/plugins/assets.py +++ b/src/plugins/assets.py @@ -221,9 +221,12 @@ def loading_scene(target: Scene, name: str, clear_cache: bool = True): else: file = asset_iterator.files.pop().replace("\\", "/") ressource_extension = file.split(".")[-1] - ressource_name = file[ - len(f"assets/{name}/") : -len(ressource_extension) - 1 - ] + prefix = ( + "assets/global/" + if file.startswith("assets/global/") + else f"assets/{name}/" + ) + ressource_name = file[len(prefix) : -len(ressource_extension) - 1] if ressource_extension in ("png", "jpg"): assets.load_texture(ressource_name, file) if ressource_extension in ("mp3", "wav", "ogg"): diff --git a/src/plugins/sound.py b/src/plugins/sound.py index 0396041..6bc76b8 100644 --- a/src/plugins/sound.py +++ b/src/plugins/sound.py @@ -3,10 +3,12 @@ Un plugin permettant de jouer des sons. """ +import random from typing import Callable import pygame from engine import GlobalPlugin, KeepAlive from engine.ecs import Entity, World +from plugins.assets import Assets class Channels(KeepAlive, dict[Entity, pygame.mixer.Channel]): @@ -35,6 +37,32 @@ class Sound: self.callback = callback +class MultiSound: + """ + Composant qui quand il est ajouté a une entité, il joue un son aléatoire + parmis la liste de ses sons, il est ensuite retiré de l'entité. + + Ce composant est fait pour être définis en tant que constante + puis utilisé ensuite, pour cela il prend seulement le nom des + sons au lieu des sons eux memes. Les sons seront donc récupérés + a l'aide de `Assets`. + """ + + def __init__( + self, + *sound_names: str, + loop: bool = False, + volume: float = 1.0, + fade_ms: int = 0, + callback: Callable[[World, Entity], object] = lambda _w, _e: None, + ): + self.sound_names = sound_names + self.loop = loop + self.volume = volume + self.fade_ms = fade_ms + self.callback = callback + + def __initialize(world: World): """ Ajoute les ressources utiles pour le plugin. @@ -46,6 +74,20 @@ def __update_sounds(world: World): """ Met à jour les sons du jeu. """ + # Ajout des sons aléatoires + assets = world[Assets] + for entity in world.query(MultiSound): + multi_sound = entity[MultiSound] + sound = assets.get_sound(random.choice(multi_sound.sound_names)) + entity[Sound] = Sound( + sound, + multi_sound.loop, + multi_sound.volume, + multi_sound.fade_ms, + multi_sound.callback, + ) + del entity[MultiSound] + # Ajout des sons non gérés channels = world[Channels] sound_entities = world.query(Sound) @@ -64,6 +106,7 @@ def __update_sounds(world: World): callback = entity[Sound].callback del entity[Sound] callback(world, entity) + channels_to_remove.append(entity) elif entity not in sound_entities: channel.stop() channels_to_remove.append(entity) diff --git a/src/scenes/__init__.py b/src/scenes/__init__.py index 44fb452..83db103 100644 --- a/src/scenes/__init__.py +++ b/src/scenes/__init__.py @@ -1,3 +1,8 @@ """ Module contenant toutes les scènes du jeu. """ + +from plugins.sound import MultiSound + + +CLICK_SOUND = MultiSound("click/0", "click/1", "click/2") diff --git a/src/scenes/base_game.py b/src/scenes/base_game.py index fcd935e..6a75341 100644 --- a/src/scenes/base_game.py +++ b/src/scenes/base_game.py @@ -5,8 +5,8 @@ Définit 3 scènes de jeu basique from enum import Enum import random import pygame -from engine import CurrentScene, Scene, Plugin -from engine.ecs import World +from engine import CurrentScene, KeepAlive, Scene, Plugin +from engine.ecs import Entity, World from engine.math import Vec2 from plugins import assets from plugins import render @@ -18,7 +18,7 @@ from plugins.render import Sprite from plugins.text import Text from plugins.writing import Writing from plugins.click import Clickable -from scenes import menu +from scenes import CLICK_SOUND, menu class GameMode(Enum): @@ -67,6 +67,14 @@ class PlayAgain: """ +def __return_to_menu(world: World, _entity: Entity): + """ + Reviens sur le menu lorsque l'on clique sur la flèche de retour. + """ + world[CurrentScene] = menu.SCENE + world.new_entity().set(KeepAlive(), CLICK_SOUND) + + def __initialize_world(world: World): world.set(Number(random.randint(0, 99))) world.set(IsRunning()) @@ -77,7 +85,7 @@ def __initialize_world(world: World): HoveredTexture( world[Assets].get_texture("arrow"), world[Assets].get_texture("arrow_hover") ), - Clickable(lambda world, entity: world.set(CurrentScene(menu.SCENE))), + Clickable(__return_to_menu), ) world.new_entity().set( Sprite( diff --git a/src/scenes/menu.py b/src/scenes/menu.py index 7586546..93f42b5 100644 --- a/src/scenes/menu.py +++ b/src/scenes/menu.py @@ -3,8 +3,9 @@ La scène du menu principal du jeu. Dans cette scène nous pouvons choisir le mode de jeu. """ -from scenes import base_game -from engine import CurrentScene, Scene +from scenes import CLICK_SOUND, base_game +from scenes.story import directory_search +from engine import CurrentScene, KeepAlive, Scene from engine.ecs import Entity, World from engine.math import Vec2 from plugins import render @@ -13,8 +14,6 @@ from plugins.assets import Assets from plugins.click import Clickable from plugins.hover import HoveredTexture from plugins.render import Sprite -from plugins.sound import Sound -from scenes.story import directory_search def __create_button(world: World, assets: Assets, i: int, name: str): @@ -40,7 +39,7 @@ def __on_click_butons(world: World, _entity: Entity, name: str): """ Fonction qui s'execute quand on clique sur un bouton. """ - world.new_entity().set(Sound(world[Assets].get_sound("click"))) + world.new_entity().set(KeepAlive(), CLICK_SOUND) match name: case "classique": world[CurrentScene] = base_game.CLASSIC