Meilleur gestion de l'audio lors du changement de scènes

This commit is contained in:
Tipragot 2023-10-29 15:43:48 +01:00
parent fabb474e5c
commit 5cd161fd35

View file

@ -589,13 +589,13 @@ class Sound:
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.name = name
self.volume = volume
self._loop = loop
self._is_paying = False
self.loop = loop
self.callback = callback
self.stop_on_remove = stop_on_remove
class Scene:
@ -644,7 +644,7 @@ def start_game(
assets = Assets(surface)
# creation des channels pour les sons
channels: dict[Entity, pygame.mixer.Channel] = {}
channels: dict[Entity, tuple[bool, pygame.mixer.Channel]] = {}
# On récupère la première scène
scene = scenes.get(start_scene)
@ -741,6 +741,35 @@ def start_game(
for system in scene.update_systems:
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
for entity in world.query(Animation):
animation = entity[Animation]
@ -804,36 +833,6 @@ def start_game(
),
)
# On update assets._sound en fonction des nouvelles entité.
for entity in world.query(Sound):
channel = channels.get(entity)
if channel is None:
sound = assets.get_sound(entity[Sound]._name)
channel: Optional[pygame.mixer.Channel] = sound.play(
loops=-1 if entity[Sound]._loop else 0
)
if channel is None: # type: ignore
continue
channels[entity] = channel
channel.set_volume(entity[Sound].volume)
# On verifie si le son est terminé
if not channel.get_busy():
entity[Sound]._is_paying = False
callback = entity[Sound].callback
del entity[Sound]
del channels[entity]
callback(world, entity)
entities_to_delete: list[Entity] = []
for entity, channel in channels.items():
if Sound not in entity:
channel.stop()
entities_to_delete.append(entity)
for entity in entities_to_delete:
del channels[entity]
# Mise a jour de la fenêtre
rect = Display._calculate_surface_rect()
pygame.transform.set_smoothscale_backend("MMX")