Merge pull request 'Ajoute d'un systeme de son' (#34) from sound into main

Reviewed-on: #34
This commit is contained in:
CoCo_Sol 2023-10-29 15:11:48 +00:00 committed by Gitea
commit 15ec2c3fdc
No known key found for this signature in database
3 changed files with 80 additions and 1 deletions

BIN
assets/sounds/click.wav Normal file

Binary file not shown.

View file

@ -283,6 +283,7 @@ class Assets:
# Cache des ressources # Cache des ressources
self.__textures: dict[str, pygame.Surface] = {} self.__textures: dict[str, pygame.Surface] = {}
self.__fonts: dict[int, pygame.font.Font] = {} self.__fonts: dict[int, pygame.font.Font] = {}
self.__sounds: dict[str, pygame.mixer.Sound] = {}
def get_texture(self, name: str) -> pygame.Surface: def get_texture(self, name: str) -> pygame.Surface:
""" """
@ -346,6 +347,22 @@ class Assets:
""" """
return Vec2(*self.get_font(size).size(text)) return Vec2(*self.get_font(size).size(text))
def get_sound(self, name: str) -> pygame.mixer.Sound:
"""
Renvoie le son qui correspond au nom *name*.
Paramètres:
name: Le nom du son.
Retourne:
Le son qui correspond au nom *name*.
"""
sound = self.__sounds.get(name)
if sound is None:
sound = pygame.mixer.Sound(f"assets/sounds/{name}")
self.__sounds[name] = sound
return sound
class Time(float): class Time(float):
""" """
@ -561,6 +578,26 @@ class Clickable:
self.callback = callback self.callback = callback
class Sound:
"""
Composant qui une entité emettrant un son.
"""
def __init__(
self,
name: str,
volume: float = 0.5,
loop: bool = False,
callback: Callable[[World, Entity], object] = lambda _w, _e: None,
stop_on_remove: bool = False,
) -> None:
self.name = name
self.volume = volume
self.loop = loop
self.callback = callback
self.stop_on_remove = stop_on_remove
class Scene: class Scene:
""" """
Une scène dans le jeu. Une scène dans le jeu.
@ -606,6 +643,9 @@ def start_game(
# Chargements des assets # Chargements des assets
assets = Assets(surface) assets = Assets(surface)
# creation des channels pour les sons
channels: dict[Entity, tuple[bool, pygame.mixer.Channel]] = {}
# On récupère la première scène # On récupère la première scène
scene = scenes.get(start_scene) scene = scenes.get(start_scene)
@ -701,6 +741,35 @@ def start_game(
for system in scene.update_systems: for system in scene.update_systems:
system(world) system(world)
# Gestion des sons en cours
sound_entities = world.query(Sound)
entities_to_delete: list[Entity] = []
for entity, (stop_on_remove, channel) in channels.items():
if Sound in entity:
entity_sound = entity[Sound]
channel.set_volume(entity_sound.volume)
if not channel.get_busy():
entities_to_delete.append(entity)
del entity[Sound]
entity_sound.callback(world, entity)
continue
if stop_on_remove and entity not in sound_entities:
entities_to_delete.append(entity)
channel.stop()
for entity in entities_to_delete:
del channels[entity]
# Ajout des sons non gérés
for entity in sound_entities:
if entity not in channels:
entity_sound = entity[Sound]
sound = assets.get_sound(entity_sound.name)
channel = sound.play(loops=-1 if entity_sound.loop else 0)
if channel is None: # type: ignore
continue
channel.set_volume(entity_sound.volume)
channels[entity] = entity_sound.stop_on_remove, channel
# Mise à jour des animations # Mise à jour des animations
for entity in world.query(Animation): for entity in world.query(Animation):
animation = entity[Animation] animation = entity[Animation]

View file

@ -6,11 +6,13 @@ from engine import (
Centered, Centered,
Clickable, Clickable,
Display, Display,
Entity,
Game, Game,
HoveredTexture, HoveredTexture,
Order, Order,
Position, Position,
Scene, Scene,
Sound,
Texture, Texture,
World, World,
) )
@ -26,10 +28,18 @@ def __create_button(world: World, i: int, name: str):
Centered(), Centered(),
Texture(f"menu/button_{name}.png"), Texture(f"menu/button_{name}.png"),
HoveredTexture(f"menu/button_{name}_hover.png"), HoveredTexture(f"menu/button_{name}_hover.png"),
Clickable(lambda world, _: world[Game].change_scene(name)), Clickable(lambda world, entity: on_click_butons(world, entity, name)),
) )
def on_click_butons(world: World, entity: Entity, name: str):
"""
Fonction qui s'execute quand on clique sur un bouton.
"""
entity[Sound] = Sound("click.wav")
world[Game].change_scene(name)
def __initialize_world(world: World): def __initialize_world(world: World):
""" """
Initialise le monde du menu. Initialise le monde du menu.