ecs #58

Merged
raphael merged 70 commits from ecs into main 2023-11-03 15:29:36 +00:00
5 changed files with 102 additions and 4 deletions
Showing only changes of commit fa8b5042ba - Show all commits

View file

@ -44,6 +44,14 @@ class Entity:
""" """
return self.__identifier 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: def __repr__(self) -> str:
return f"Entity({self.__identifier})" 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 engine import Scene, start_game
from plugins import assets, defaults from plugins import assets, defaults
from plugins.animation import Animation from plugins.animation import Animation
from plugins.sound import Sound
start_game( start_game(
defaults.PLUGIN, defaults.PLUGIN,
assets.loading_scene( assets.loading_scene(
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( PLUGIN = GlobalPlugin(
[],
[], [],
[__update_animations], [__update_animations],
[], [],
[],
) )

View file

@ -2,7 +2,7 @@
Plugin qui rassemple tous les plugins globaux. 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 = ( PLUGIN = (
@ -10,7 +10,8 @@ PLUGIN = (
+ timing.PLUGIN + timing.PLUGIN
+ assets.PLUGIN + assets.PLUGIN
+ inputs.PLUGIN + inputs.PLUGIN
+ animation.PLUGIN + sound.PLUGIN
+ text.PLUGIN + text.PLUGIN
+ animation.PLUGIN
+ render.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],
[],
)