Merge pull request 'Système d'animations' (#22) from animations into main

Reviewed-on: #22
This commit is contained in:
Tipragot 2023-10-27 16:20:41 +00:00 committed by Gitea
commit f8c9799757
No known key found for this signature in database
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.math import Vec2
from engine.plugins.animation import AnimatedSprite, AnimationPlugin
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 (
Order,
RenderPlugin,
Position,
Offset,
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 random import random
@ -26,6 +26,7 @@ game = Game(
RenderPlugin(),
HoverPlugin(),
ClickablePlugin(),
AnimationPlugin(),
)
@ -38,39 +39,26 @@ def spawn_sprites(world: World) -> None:
red = random() < 0.1
entity = world.create_entity(
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),
)
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
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:
"""
Change la position des sprites.

View file

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