Ajout du système d'objets cliquable et changement du système #21

Merged
tipragot merged 6 commits from button into main 2023-10-27 15:48:38 +00:00
5 changed files with 113 additions and 43 deletions
Showing only changes of commit 09bb41c278 - Show all commits

View file

@ -478,6 +478,14 @@ class Game:
error(f"Error during post-update task: {e}") error(f"Error during post-update task: {e}")
world.apply() world.apply()
# On execute les taches de pré rendu du jeu
for task in self._pre_render_tasks:
try:
task(world)
except Exception as e:
error(f"Error during pre-render task: {e}")
world.apply()
# On execute les taches de rendu du jeu # On execute les taches de rendu du jeu
for task in self._render_tasks: for task in self._render_tasks:
try: try:

View file

@ -3,6 +3,9 @@ Definit un plugin qui verifie si un objet Hover est cliqué.
""" """
from engine import * from engine import *
from typing import Callable
from engine.plugins.hover import Hover
from engine.plugins.pygame import Mouse
class ClickablePlugin(Plugin): class ClickablePlugin(Plugin):
@ -12,16 +15,40 @@ class ClickablePlugin(Plugin):
@staticmethod @staticmethod
def _update(world: World) -> None: def _update(world: World) -> None:
"""
Met à jour les objets cliquables du monde.
"""
for entity in world.query(Clickable):
if Hover in entity:
if world[Mouse].is_button_pressed(1):
entity[Clickable].callback(world, entity)
if world[Mouse].is_button(1):
entity.set(Clicked())
else:
entity.remove(Clicked)
else:
entity.remove(Clicked)
def apply(self, game: Game) -> None:
"""
Applique le plugin a un jeu.
Paramètres:
game: Le jeu auquel appliquer le plugin.
"""
game.add_pre_update_tasks(self._update)
class Clickable: class Clickable:
""" """
Un composant qui marque une entitée comme pouvant etre cliqué. Un composant qui marque une entitée comme pouvant etre cliquer.
""" """
def __init__(self, callback: Callable[[World, Entity], None]) -> None:
self.callback = callback
class Clicked: class Clicked:
""" """
Un composant qui marque une entitée comme etant cliqué. Un composant qui marque une entitée comme en train d'être cliquée.
""" """

View file

@ -3,8 +3,9 @@ Definit un plugin qui verifie si la souris est sur un element (qui a une texture
""" """
from engine import * from engine import *
from engine.math import Vec2
from engine.plugins.pygame import Mouse from engine.plugins.pygame import Mouse
from engine.plugins.render import Position, Texture, TextureManager from engine.plugins.render import Position, Offset, Texture, TextureManager
class HoverPlugin(Plugin): class HoverPlugin(Plugin):
@ -14,16 +15,21 @@ class HoverPlugin(Plugin):
@staticmethod @staticmethod
def _update(world: World) -> None: def _update(world: World) -> None:
entities = world.query(Hoverable, Texture, Position) entities = world.query(Texture, Position)
textures = world[TextureManager] textures = world[TextureManager]
mouse_pos = world[Mouse].position mouse_pos = world[Mouse].position
for entity in entities: for entity in entities:
entity_pos = entity[Position] # Récupération de la position et de la taille de l'entité
entity_pos: Vec2 = entity[Position]
if Offset in entity:
entity_pos = entity_pos + entity[Offset]
entity_size = Vec2(*textures[entity[Texture]].get_size())
if ( if (
entity_pos.x >= mouse_pos.x mouse_pos.x >= entity_pos.x
and mouse_pos.x >= textures[entity[Texture]].get_width() + entity_pos.x and mouse_pos.x <= entity_pos.x + entity_size.x
and entity_pos.y >= mouse_pos.y and mouse_pos.y >= entity_pos.y
and mouse_pos.y >= textures[entity[Texture]].get_height() + entity_pos.y and mouse_pos.y <= entity_pos.y + entity_size.y
): ):
entity.set(Hover()) entity.set(Hover())
else: else:
@ -36,13 +42,7 @@ class HoverPlugin(Plugin):
Paramètres: Paramètres:
game: Le jeu auquel appliquer le plugin. game: Le jeu auquel appliquer le plugin.
""" """
game.add_update_tasks(self._update) game.add_pre_update_tasks(self._update)
class Hoverable:
"""
Un composant qui marque une entitée comme pouvant etre survolée.
"""
class Hover: class Hover:

View file

@ -35,7 +35,9 @@ class RenderPlugin(Plugin):
entities = sorted(world.query(Order, Position), key=lambda e: e[Order]) entities = sorted(world.query(Order, Position), key=lambda e: e[Order])
for entity in entities: for entity in entities:
# Récupération de la position des entitées # Récupération de la position des entitées
position = entity[Position] position: Vec2 = entity[Position]
if Offset in entity:
position = position + entity[Offset]
# Affichage de la texture # Affichage de la texture
if Texture in entity: if Texture in entity:
@ -71,6 +73,12 @@ class Position(Vec2):
""" """
class Offset(Vec2):
"""
Composant qui represente un décalage de la position d'une entité.
"""
class Order(int): class Order(int):
""" """
Composant qui represente l'ordre d'affichage d'un objet. Composant qui represente l'ordre d'affichage d'un objet.
@ -85,11 +93,13 @@ class TextureManager:
def __init__(self, display: Display) -> None: def __init__(self, display: Display) -> None:
self._textures: dict[str, pygame.Surface] = {} self._textures: dict[str, pygame.Surface] = {}
for file in glob.iglob("textures/**/*.png", recursive=True): for file in glob.iglob("textures/**/*.png", recursive=True):
self._textures[file[9:]] = pygame.image.load(file).convert_alpha( self._textures[file[9:].replace("\\", "/")] = pygame.image.load(
display._surface file
) ).convert_alpha(display._surface)
for file in glob.iglob("textures/**/*.jpg", recursive=True): for file in glob.iglob("textures/**/*.jpg", recursive=True):
self._textures[file[9:]] = pygame.image.load(file).convert(display._surface) self._textures[file[9:].replace("\\", "/")] = pygame.image.load(
file
).convert(display._surface)
error_texture = pygame.Surface((256, 256)) error_texture = pygame.Surface((256, 256))
error_texture.fill((0, 0, 0)) error_texture.fill((0, 0, 0))
pygame.draw.rect(error_texture, (255, 0, 255), (0, 0, 128, 128)) pygame.draw.rect(error_texture, (255, 0, 255), (0, 0, 128, 128))

View file

@ -5,23 +5,27 @@ 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.hover import HoverPlugin from engine.plugins.clickable import Clickable, ClickablePlugin
from engine.plugins.hover import Hover, HoverPlugin
from engine.plugins.render import ( from engine.plugins.render import (
Order, Order,
RenderPlugin, RenderPlugin,
Position, Position,
Text, Offset,
TextColor, Texture,
TextSize,
) )
from engine.plugins.timing import Delta, TimePlugin from engine.plugins.timing import Time, 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
# Initialisation # Initialisation
game = Game( game = Game(
TimePlugin(), PygamePlugin("Guess The Number"), RenderPlugin(), HoverPlugin() TimePlugin(),
PygamePlugin("Guess The Number"),
RenderPlugin(),
HoverPlugin(),
ClickablePlugin(),
) )
@ -32,20 +36,41 @@ def spawn_sprites(world: World) -> None:
""" """
for i in range(100): for i in range(100):
red = random() < 0.1 red = random() < 0.1
world.create_entity( entity = world.create_entity(
Position(random() * Display.WIDTH, random() * Display.HEIGHT), Position(random() * Display.WIDTH, random() * Display.HEIGHT),
# Texture("test2.png") if red else Texture("test.png"), Texture("directory.png") if red else Texture("test.png"),
Text("Hello les gens"),
TextSize(50),
TextColor(255, 0, 0) if red else TextColor(255, 255, 255),
Order(1 if red else 0), Order(1 if red else 0),
) )
if red:
entity.set(Clickable(lambda world, entity: print("click")))
# 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"anim/edmond_serch_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.