ecs #58
25
src/main.py
25
src/main.py
|
@ -3,10 +3,21 @@ Module d'exemple de l'utilisation du moteur de jeu.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from engine import Scene, start_game
|
from engine import Scene, start_game
|
||||||
|
from engine.ecs import World
|
||||||
from plugins import assets, defaults
|
from plugins import assets, defaults
|
||||||
from plugins.animation import Animation
|
from plugins.coroutine import Coroutine, condition, wait
|
||||||
from plugins.render import Sprite
|
from plugins.inputs import MousePosition
|
||||||
from plugins.sound import Sound
|
|
||||||
|
|
||||||
|
def super_fonction_du_turfu(world: World):
|
||||||
|
"""
|
||||||
|
Fonction du turfu qui s'execute sur plusieurs frames.
|
||||||
|
"""
|
||||||
|
print("LOL")
|
||||||
|
yield wait(10.0)
|
||||||
|
print("LOL 10 secondes après")
|
||||||
|
yield condition(lambda world: world.get(MousePosition).x > 500)
|
||||||
|
print("La souris est a droite !")
|
||||||
|
|
||||||
|
|
||||||
start_game(
|
start_game(
|
||||||
|
@ -15,13 +26,7 @@ start_game(
|
||||||
Scene(
|
Scene(
|
||||||
[
|
[
|
||||||
lambda world: world.new_entity().set(
|
lambda world: world.new_entity().set(
|
||||||
Animation(
|
Coroutine(super_fonction_du_turfu(world)),
|
||||||
"animations/intro",
|
|
||||||
callback=lambda world, entity: entity.set(
|
|
||||||
Sound(world[assets.Assets].get_sound("edqsd"))
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Sprite(world[assets.Assets].get_texture("intro")),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
|
85
src/plugins/coroutine.py
Normal file
85
src/plugins/coroutine.py
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
"""
|
||||||
|
Plugin permettant d'executer des coroutine.
|
||||||
|
|
||||||
|
Une coroutine est une fonction qui est executée sur plusieurs frames,
|
||||||
|
cela permet d'executer du code comme si il s'agissait d'une fonction
|
||||||
|
classique tout en laissant tourner la boucle du jeu. Il est a noter que
|
||||||
|
cette fonction n'est pas lancé dans une autre thread, la fonction est
|
||||||
|
executé dans le thread principal, mais lorsqu'un `yield` est utilisé,
|
||||||
|
l'execution de la fonction est arrêté jusqu'a ce que la condition donné
|
||||||
|
par le `yield` soit remplie, ce qui permet au thread principal de pouvoir
|
||||||
|
continuer de faire le rendu et la logique du jeu. Faire un traivail bloquant
|
||||||
|
dans une coroutine auras donc un impacte sur le nombre d'images par secondes
|
||||||
|
du jeu.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
from typing import Callable, Generator, Optional
|
||||||
|
from engine import GlobalPlugin
|
||||||
|
from engine.ecs import Entity, World
|
||||||
|
from plugins.timing import GlobalTime
|
||||||
|
|
||||||
|
|
||||||
|
def wait(seconds: float) -> Callable[[World], bool]:
|
||||||
|
"""
|
||||||
|
Utilitaire de `Coroutine` permettant d'attendre un certain temps.
|
||||||
|
"""
|
||||||
|
stop_time = time() + seconds
|
||||||
|
return lambda world: world[GlobalTime] >= stop_time
|
||||||
|
|
||||||
|
|
||||||
|
def condition(condition_function: Callable[[World], bool]) -> Callable[[World], bool]:
|
||||||
|
"""
|
||||||
|
Utilitaire de `Coroutine` permettant d'attendre que la condition soit réalisé avant
|
||||||
|
de continuer l'execution.
|
||||||
|
"""
|
||||||
|
return condition_function
|
||||||
|
|
||||||
|
|
||||||
|
class Coroutine:
|
||||||
|
"""
|
||||||
|
Composant permettant d'executer une coroutine.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, generator: Generator[Callable[[World], bool], None, None]):
|
||||||
|
self.generator = generator
|
||||||
|
self.__condition: Optional[ # pylint: disable=unused-private-member
|
||||||
|
Callable[[World], bool]
|
||||||
|
] = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update(entity: Entity):
|
||||||
|
"""
|
||||||
|
Met à jour la coroutine d'une entité.
|
||||||
|
|
||||||
|
Si l'entité n'as pas de `Coroutine` la fonction ne fait rien.
|
||||||
|
"""
|
||||||
|
if Coroutine not in entity:
|
||||||
|
return
|
||||||
|
coroutine = entity[Coroutine]
|
||||||
|
if coroutine.__condition is None:
|
||||||
|
coroutine.__condition = next( # pylint: disable=unused-private-member
|
||||||
|
coroutine.generator, None
|
||||||
|
)
|
||||||
|
if coroutine.__condition is None:
|
||||||
|
del entity[Coroutine]
|
||||||
|
return
|
||||||
|
if coroutine.__condition(entity.world):
|
||||||
|
coroutine.__condition = None # pylint: disable=unused-private-member
|
||||||
|
|
||||||
|
|
||||||
|
def __update_coroutines(world: World):
|
||||||
|
"""
|
||||||
|
Met à jour les coroutine du jeu.
|
||||||
|
"""
|
||||||
|
for entity in world.query(Coroutine):
|
||||||
|
Coroutine.update(entity)
|
||||||
|
|
||||||
|
|
||||||
|
PLUGIN = GlobalPlugin(
|
||||||
|
[],
|
||||||
|
[__update_coroutines],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
)
|
|
@ -2,7 +2,17 @@
|
||||||
Plugin qui rassemple tous les plugins globaux.
|
Plugin qui rassemple tous les plugins globaux.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from plugins import animation, assets, display, inputs, render, sound, text, timing
|
from plugins import (
|
||||||
|
animation,
|
||||||
|
assets,
|
||||||
|
coroutine,
|
||||||
|
display,
|
||||||
|
inputs,
|
||||||
|
render,
|
||||||
|
sound,
|
||||||
|
text,
|
||||||
|
timing,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
PLUGIN = (
|
PLUGIN = (
|
||||||
|
@ -10,6 +20,7 @@ PLUGIN = (
|
||||||
+ timing.PLUGIN
|
+ timing.PLUGIN
|
||||||
+ assets.PLUGIN
|
+ assets.PLUGIN
|
||||||
+ inputs.PLUGIN
|
+ inputs.PLUGIN
|
||||||
|
+ coroutine.PLUGIN
|
||||||
+ sound.PLUGIN
|
+ sound.PLUGIN
|
||||||
+ text.PLUGIN
|
+ text.PLUGIN
|
||||||
+ animation.PLUGIN
|
+ animation.PLUGIN
|
||||||
|
|
Loading…
Reference in a new issue