Ajout d'un système d'audio

This commit is contained in:
Tipragot 2023-11-01 18:45:55 +01:00
parent b60f3bd5ea
commit fa8b5042ba
5 changed files with 102 additions and 4 deletions

View file

@ -44,6 +44,14 @@ class Entity:
"""
return self.__identifier
def __eq__(self, __value: object) -> bool:
if isinstance(__value, Entity):
return self.__identifier == __value.identifier
return False
def __hash__(self) -> int:
return self.__identifier
def __repr__(self) -> str:
return f"Entity({self.__identifier})"

View file

@ -5,13 +5,23 @@ Module d'exemple de l'utilisation du moteur de jeu.
from engine import Scene, start_game
from plugins import assets, defaults
from plugins.animation import Animation
from plugins.sound import Sound
start_game(
defaults.PLUGIN,
assets.loading_scene(
Scene(
[lambda world: world.new_entity().set(Animation("animations/intro"))],
[
lambda world: world.new_entity().set(
Animation(
"animations/intro",
callback=lambda world, entity: entity.set(
Sound(world[assets.Assets].get_sound("edqsd"))
),
)
)
],
[],
[],
),

View file

@ -85,8 +85,8 @@ def __update_animations(world: World) -> None:
PLUGIN = GlobalPlugin(
[],
[],
[__update_animations],
[],
[],
)

View file

@ -2,7 +2,7 @@
Plugin qui rassemple tous les plugins globaux.
"""
from plugins import animation, assets, display, inputs, render, text, timing
from plugins import animation, assets, display, inputs, render, sound, text, timing
PLUGIN = (
@ -10,7 +10,8 @@ PLUGIN = (
+ timing.PLUGIN
+ assets.PLUGIN
+ inputs.PLUGIN
+ animation.PLUGIN
+ sound.PLUGIN
+ text.PLUGIN
+ animation.PLUGIN
+ render.PLUGIN
)

79
src/plugins/sound.py Normal file
View file

@ -0,0 +1,79 @@
"""
Un plugin permettant de jouer des sons.
"""
from typing import Callable
import pygame
from engine import GlobalPlugin, KeepAlive
from engine.ecs import Entity, World
class Channels(KeepAlive, dict[Entity, pygame.mixer.Channel]):
"""
Ressource qui stoque les sons actuellement joués dans le jeu.
"""
class Sound:
"""
Composant permettant de jouer un son.
"""
def __init__(
self,
sound: pygame.mixer.Sound,
loop: bool = False,
volume: float = 1.0,
fade_ms: int = 0,
callback: Callable[[World, Entity], object] = lambda _w, _e: None,
):
self.sound = sound
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.
"""
world.set(Channels())
def __update_sounds(world: World):
"""
Met à jour les sons du jeu.
"""
# Ajout des sons non gérés
channels = world[Channels]
sound_entities = world.query(Sound)
for entity in sound_entities:
if entity not in channels:
sound = entity[Sound]
channel = sound.sound.play(sound.loop, fade_ms=sound.fade_ms)
if channel is not None: # type: ignore
channel.set_volume(sound.volume)
channels[entity] = channel
# On supprime les sons qui sont arrêtés ou qui n'ont plus d'entité
channels_to_remove: list[Entity] = []
for entity, channel in channels.items():
if not channel.get_busy() and Sound in entity:
callback = entity[Sound].callback
del entity[Sound]
callback(world, entity)
elif entity not in sound_entities:
channel.stop()
channels_to_remove.append(entity)
for entity in channels_to_remove:
del channels[entity]
PLUGIN = GlobalPlugin(
[__initialize],
[],
[__update_sounds],
[],
)