Amélioration des systèmes de base

This commit is contained in:
Tipragot 2023-10-25 15:36:29 +02:00
parent b07814c440
commit f56fe137fa
4 changed files with 182 additions and 33 deletions

View file

@ -264,15 +264,29 @@ class Game:
*plugins: Les plugins a ajouter au jeu.
"""
self._running = False
self._pre_startup_tasks: list[Callable[[World], None]] = []
self._startup_tasks: list[Callable[[World], None]] = []
self._post_startup_tasks: list[Callable[[World], None]] = []
self._pre_update_tasks: list[Callable[[World], None]] = []
self._update_tasks: list[Callable[[World], None]] = []
self._post_update_tasks: list[Callable[[World], None]] = []
self._pre_render_tasks: list[Callable[[World], None]] = []
self._render_tasks: list[Callable[[World], None]] = []
self._post_render_tasks: list[Callable[[World], None]] = []
self._pre_shutdown_tasks: list[Callable[[World], None]] = []
self._shutdown_tasks: list[Callable[[World], None]] = []
self._post_shutdown_tasks: list[Callable[[World], None]] = []
for plugin in plugins:
plugin.apply(self)
def add_pre_startup_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront en premier avant le démarrage du jeu.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._pre_startup_tasks.extend(tasks)
def add_startup_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront au démarrage du jeu.
@ -284,6 +298,14 @@ class Game:
raise RuntimeError("Cannot add a task while the loop is running")
self._startup_tasks.extend(tasks)
def add_post_startup_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront en dernier après le démarrage du jeu.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._post_startup_tasks.extend(tasks)
def add_pre_update_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront au debut de chaque mise à jour du jeu.
@ -317,6 +339,17 @@ class Game:
raise RuntimeError("Cannot add a task while the loop is running")
self._post_update_tasks.extend(tasks)
def add_pre_render_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront au début de chaque mise à jour du jeu pour le rendu.
Paramètres:
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._pre_render_tasks.extend(tasks)
def add_render_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront après chaque mise à jour du jeu pour le rendu.
@ -328,6 +361,25 @@ class Game:
raise RuntimeError("Cannot add a task while the loop is running")
self._render_tasks.extend(tasks)
def add_post_render_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront après chaque mise à jour du jeu pour le rendu.
Paramètres:
*tasks: Les taches à ajouter.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._post_render_tasks.extend(tasks)
def add_pre_shutdown_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront au début de la fin de la boucle de jeu.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._pre_shutdown_tasks.extend(tasks)
def add_shutdown_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront à la fin de la boucle de jeu.
@ -339,6 +391,14 @@ class Game:
raise RuntimeError("Cannot add a task while the loop is running")
self._shutdown_tasks.extend(tasks)
def add_post_shutdown_tasks(self, *tasks: Callable[[World], None]) -> None:
"""
Ajoute des taches qui s'executeront à la fin de la fin de la boucle de jeu.
"""
if self._running:
raise RuntimeError("Cannot add a task while the loop is running")
self._post_shutdown_tasks.extend(tasks)
def run(self, world: World = World()) -> World:
"""
Lance la boucle de jeu.
@ -351,6 +411,14 @@ class Game:
world.set(self)
world.apply()
# On execute les taches de pré initialisation du monde
for task in self._pre_startup_tasks:
try:
task(world)
except Exception as e:
error(f"Error during pre-startup task: {e}")
world.apply()
# On execute les taches d'initialisation du monde
for task in self._startup_tasks:
try:
@ -359,6 +427,14 @@ class Game:
error(f"Error during startup task: {e}")
world.apply()
# On execute les taches de post initialisation du monde
for task in self._post_startup_tasks:
try:
task(world)
except Exception as e:
error(f"Error during post-startup task: {e}")
world.apply()
while self._running:
# On execute les taches de pré mise à jour du monde
for task in self._pre_update_tasks:
@ -392,6 +468,22 @@ class Game:
error(f"Error during render task: {e}")
world.apply()
# On execute les taches de fin de rendu du jeu
for task in self._post_render_tasks:
try:
task(world)
except Exception as e:
error(f"Error during post-render task: {e}")
world.apply()
# On execute les taches de pré fin de boucle
for task in self._pre_shutdown_tasks:
try:
task(world)
except Exception as e:
error(f"Error during pre-shutdown task: {e}")
world.apply()
# On exécute les taches de fin du monde
for task in self._shutdown_tasks:
try:
@ -400,6 +492,14 @@ class Game:
error(f"Error during shutdown task: {e}")
world.apply()
# On execute les taches de post fin de boucle
for task in self._post_shutdown_tasks:
try:
task(world)
except Exception as e:
error(f"Error during post-shutdown task: {e}")
world.apply()
# On retourne le monde
return world

View file

@ -3,31 +3,71 @@ Définis des classes utiles.
"""
import math
class Vec2:
"""
Un vecteur 2D
"""
def __init__(self, x: float, y: float) -> None:
self.x = x
self.y = y
def __init__(self, x: float = 0, y: float = 0) -> None:
self.x = float(x)
self.y = float(y)
def __add__(self, other: "Vec2") -> "Vec2":
return Vec2(self.x + other.x, self.y + other.y)
def __add__(self, other: object) -> "Vec2":
if isinstance(other, Vec2):
return Vec2(self.x + other.x, self.y + other.y)
elif isinstance(other, float):
return Vec2(self.x + other, self.y + other)
return Vec2(float("nan"), float("nan"))
def __sub__(self, other: "Vec2") -> "Vec2":
return Vec2(self.x - other.x, self.y - other.y)
def __sub__(self, other: object) -> "Vec2":
if isinstance(other, Vec2):
return Vec2(self.x - other.x, self.y - other.y)
elif isinstance(other, float):
return Vec2(self.x - other, self.y - other)
return Vec2(float("nan"), float("nan"))
def __mul__(self, other: "Vec2") -> "Vec2":
return Vec2(self.x * other.x, self.y * other.y)
def __mul__(self, other: object) -> "Vec2":
if isinstance(other, Vec2):
return Vec2(self.x * other.x, self.y * other.y)
elif isinstance(other, float):
return Vec2(self.x * other, self.y * other)
return Vec2(float("nan"), float("nan"))
def __div__(self, other: "Vec2") -> "Vec2":
return Vec2(self.x / other.x, self.y / other.y)
def __truediv__(self, other: object) -> "Vec2":
if isinstance(other, Vec2):
return Vec2(self.x / other.x, self.y / other.y)
elif isinstance(other, float):
return Vec2(self.x / other, self.y / other)
return Vec2(float("nan"), float("nan"))
def __eq__(self, other: object) -> bool:
if isinstance(other, Vec2):
return self.x == other.x and self.y == other.y
return False
def __hash__(self) -> int:
return hash((self.x, self.y))
def __neg__(self) -> "Vec2":
return Vec2(-self.x, -self.y)
@property
def length(self) -> float:
"""
Retourne la longueur du vecteur.
"""
return math.sqrt(self.x**2 + self.y**2)
@property
def normalized(self) -> "Vec2":
"""
Retourne une version normalisé du vecteur.
"""
length = self.length
return Vec2(self.x / length, self.y / length)
def __repr__(self) -> str:
return f"Vec2({self.x}, {self.y})"

View file

@ -3,9 +3,8 @@ Définit un plugin qui gère les évenements pygame.
"""
from engine import *
import pygame
from engine.math import Vec2
import pygame
class PygamePlugin(Plugin):
@ -14,14 +13,20 @@ class PygamePlugin(Plugin):
"""
@staticmethod
def _initialize_pygame(world: World) -> None:
def _initialize(world: World) -> None:
pygame.init()
# Initialisation des ressources
world.set(Display(pygame.display.set_mode((640, 480))), Keyboard(), Mouse())
world.set(
Display(pygame.display.set_mode((800, 600), pygame.RESIZABLE)),
Keyboard(),
Mouse(),
)
@staticmethod
def _check_events(world: World) -> None:
world[Display].size = Vec2(*pygame.display.get_surface().get_size())
keyboard = world[Keyboard]
keyboard.pressed.clear()
keyboard.released.clear()
@ -51,7 +56,16 @@ class PygamePlugin(Plugin):
mouse.position = Vec2(float(event.pos[0]), float(event.pos[1]))
@staticmethod
def _terminate_pygame(world: World) -> None:
def _flip_display(world: World) -> None:
"""
Met a jour le rendu de l'écran.
"""
display = world[Display]
pygame.display.flip()
pygame.display.get_surface().fill((0, 0, 0))
@staticmethod
def _terminate(world: World) -> None:
pygame.quit()
def apply(self, game: Game) -> None:
@ -61,9 +75,10 @@ class PygamePlugin(Plugin):
Paramètres:
game: Le jeu auquel appliquer le plugin.
"""
game.add_startup_tasks(self._initialize_pygame)
game.add_pre_startup_tasks(self._initialize)
game.add_pre_update_tasks(self._check_events)
game.add_shutdown_tasks(self._terminate_pygame)
game.add_post_render_tasks(self._flip_display)
game.add_post_shutdown_tasks(self._terminate)
class Display:
@ -71,28 +86,22 @@ class Display:
Ressource qui represente la fenetre du jeu.
"""
def __init__(self, surface: pygame.Surface) -> None:
self.surface = surface
def __init__(self, display: pygame.Surface) -> None:
self.size: Vec2 = Vec2(*display.get_size())
@property
def width(self) -> int:
def width(self) -> float:
"""
Renvoie la largeur de la fenetre
Retourne:
La largeur de la fenetre
Retourne la largeur de la fenetre.
"""
return self.surface.get_width()
return self.size.x
@property
def height(self) -> int:
def height(self) -> float:
"""
Renvoie la hauteur de la fenetre
Retourne:
La hauteur de la fenetre
Retourne la hauteur de la fenetre.
"""
return self.surface.get_height()
return self.size.y
class Keyboard:

View file

@ -24,7 +24,7 @@ class TimePlugin(Plugin):
"""
Applique le plugin a un jeu.
"""
game.add_startup_tasks(self._initialize_time)
game.add_pre_startup_tasks(self._initialize_time)
game.add_pre_update_tasks(self._update_time)