Ajoute d'un systeme de son #34

Merged
CoCo_Sol merged 12 commits from sound into main 2023-10-29 15:11:50 +00:00
Showing only changes of commit 609a00ea11 - Show all commits

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):
""" """
@ -578,15 +595,8 @@ class Sound:
self._loop = loop self._loop = loop
self._is_paying = False self._is_paying = False
self._sound: pygame.mixer.Sound
self._chanel: pygame.mixer.Channel
self.callback = callback self.callback = callback
def __del__(self):
self._sound.stop()
self._chanel.stop()
class Scene: class Scene:
""" """
@ -633,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, 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)
@ -791,29 +804,36 @@ def start_game(
), ),
) )
# On met le son # On update assets._sound en fonction des nouvelles entité.
for entity in world.query(Sound): for entity in world.query(Sound):
# On verifie si le son est deja actif. channel = channels.get(entity)
if not entity[Sound]._is_paying: if channel is None:
# On charge le son et on le joue. sound = assets.get_sound(entity[Sound]._name)
if os.path.exists("assets/sounds/" + entity[Sound]._name): channel: Optional[pygame.mixer.Channel] = sound.play(
entity[Sound]._is_paying = True
entity[Sound]._sound = pygame.mixer.Sound(
"assets/sounds/" + entity[Sound]._name
)
entity[Sound]._sound.set_volume(entity[Sound].volume)
entity[Sound]._chanel = entity[Sound]._sound.play(
loops=-1 if entity[Sound]._loop else 0 loops=-1 if entity[Sound]._loop else 0
) )
if channel is None: # type: ignore
continue
channels[entity] = channel
else: channel.set_volume(entity[Sound].volume)
# si le son est joue.
if not entity[Sound]._chanel.get_busy(): # On verifie si le son est terminé
if not channel.get_busy():
entity[Sound]._is_paying = False entity[Sound]._is_paying = False
callback = entity[Sound].callback callback = entity[Sound].callback
del entity[Sound] del entity[Sound]
del channels[entity]
callback(world, 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 # Mise a jour de la fenêtre
rect = Display._calculate_surface_rect() rect = Display._calculate_surface_rect()
pygame.transform.set_smoothscale_backend("MMX") pygame.transform.set_smoothscale_backend("MMX")