Système d'animations #22

Merged
tipragot merged 3 commits from animations into main 2023-10-27 16:20:43 +00:00
3 changed files with 85 additions and 28 deletions

View file

@ -0,0 +1,69 @@
"""
Définit un plugin qui permet d'afficher des animations.
"""
from typing import Callable
from engine import *
from engine.plugins.render import Offset, Texture
from engine.plugins.timing import Delta
import json
class AnimationPlugin(Plugin):
"""
Plugin qui permet d'afficher des animations.
"""
@staticmethod
def _update(world: World) -> None:
"""
Met à jour les animations.
"""
for entity in world.query(AnimatedSprite):
animation: AnimatedSprite = entity[AnimatedSprite]
if animation.time == 0:
if animation.end_image == "" and Texture in entity:
animation.end_image = entity[Texture]
animation.time += world[Delta]
frame_index = int(animation.time * animation.fps)
if frame_index >= animation.frame_count:
entity.set(Texture(animation.end_image))
entity.remove(AnimatedSprite, Offset)
animation.callback(world, entity)
else:
entity.set(
Offset(animation.offset.x, animation.offset.y),
Texture(
f"animations/{animation.images_folder}/{frame_index:04}.png"
),
)
def apply(self, game: Game) -> None:
"""
Applique le plugin a un jeu.
Paramètres:
game: Le jeu auquel appliquer le plugin.
"""
game.add_pre_render_tasks(self._update)
class AnimatedSprite:
"""
Composant qui represente un sprite animé.
"""
def __init__(
self,
animation_name: str,
callback: Callable[[World, Entity], None] = lambda _w, _e: None,
) -> None:
self.images_folder = animation_name
self.callback = callback
with open(f"textures/animations/{animation_name}/info.json") as f:
info = json.load(f)
self.end_image: str = info.get("end_image", "")
self.offset = Offset(info["offset"]["x"], info["offset"]["y"])
self.frame_count: int = info["frame_count"]
self.fps: int = info["fps"]
self.time = 0.0

View file

@ -5,16 +5,16 @@ Ceci est un exemple de comment l'on peut utiliser le moteur du jeu.
from engine import * from engine import *
from engine.math import Vec2 from engine.math import Vec2
from engine.plugins.animation import AnimatedSprite, AnimationPlugin
from engine.plugins.clickable import Clickable, ClickablePlugin from engine.plugins.clickable import Clickable, ClickablePlugin
from engine.plugins.hover import Hover, HoverPlugin from engine.plugins.hover import HoverPlugin
from engine.plugins.render import ( from engine.plugins.render import (
Order, Order,
RenderPlugin, RenderPlugin,
Position, Position,
Offset,
Texture, Texture,
) )
from engine.plugins.timing import Time, Delta, TimePlugin from engine.plugins.timing import Delta, TimePlugin
from engine.plugins.pygame import Display, Keyboard, PygamePlugin from engine.plugins.pygame import Display, Keyboard, PygamePlugin
from random import random from random import random
@ -26,6 +26,7 @@ game = Game(
RenderPlugin(), RenderPlugin(),
HoverPlugin(), HoverPlugin(),
ClickablePlugin(), ClickablePlugin(),
AnimationPlugin(),
) )
@ -38,39 +39,26 @@ def spawn_sprites(world: World) -> None:
red = random() < 0.1 red = random() < 0.1
entity = world.create_entity( entity = world.create_entity(
Position(random() * Display.WIDTH, random() * Display.HEIGHT), Position(random() * Display.WIDTH, random() * Display.HEIGHT),
Texture("directory.png") if red else Texture("test.png"), Texture("directory.png") if red else Texture("error.png"),
Order(1 if red else 0), Order(1 if red else 0),
) )
if red: if red:
entity.set(Clickable(lambda world, entity: print("click"))) entity.set(
Clickable(
lambda world, entity: entity.set(
AnimatedSprite(
"search_directory",
lambda world, entity: print("finished !"),
)
)
)
)
# On ajoutant la tache # On ajoutant la tache
game.add_startup_tasks(spawn_sprites) game.add_startup_tasks(spawn_sprites)
# On créer un tache pour vérifier le système d'hover
def change_on_hover(world: World) -> None:
"""
Change la texture du sprite quand on passe la souris sur lui.
"""
for entity in world.query(Position, Texture):
if Hover in entity:
entity.set(
Texture(
f"animations/search_directory/{(int(world[Time] * 60) % 270):04}.png"
)
)
entity.set(Offset(-48, -176))
else:
entity.set(Texture("directory.png"))
entity.remove(Offset)
# On ajoute la tache
game.add_update_tasks(change_on_hover)
def move_sprites(world: World) -> None: def move_sprites(world: World) -> None:
""" """
Change la position des sprites. Change la position des sprites.

View file

@ -1,5 +1,5 @@
{ {
"base_image": "directory.png", "end_image": "directory.png",
"offset": { "offset": {
"x": -48, "x": -48,
"y": -176 "y": -176