gtn/engine/plugins/pygame.py

209 lines
6 KiB
Python

"""
Définit un plugin qui gère les évenements pygame.
"""
from engine import *
import pygame
from engine.math import Vec2
class PygamePlugin(Plugin):
"""
Plugin qui gère les évenements pygame.
"""
@staticmethod
def _initialize_pygame(world: World) -> None:
pygame.init()
# Initialisation des ressources
world.set(Display(pygame.display.set_mode((640, 480))))
world.set(Keyboard(set(), set(), set()))
world.set(Mouse(set(), set(), set(), Vec2(0.0, 0.0)))
@staticmethod
def _check_events(world: World) -> None:
keys = world[Keyboard]._keys.copy()
keys_pressed: set[str] = set()
keys_released: set[str] = set()
buttons = world[Mouse]._buttons.copy()
buttons_pressed: set[int] = set()
buttons_released: set[int] = set()
mouse_position = world[Mouse]._position
for event in pygame.event.get():
if event.type == pygame.QUIT:
world[Game].stop()
elif event.type == pygame.KEYDOWN:
key_name = pygame.key.name(event.key)
keys.add(key_name)
keys_pressed.add(key_name)
elif event.type == pygame.KEYUP:
key_name = pygame.key.name(event.key)
keys.remove(key_name)
keys_released.add(key_name)
elif event.type == pygame.MOUSEBUTTONDOWN:
buttons.add(event.button)
buttons_pressed.add(event.button)
elif event.type == pygame.MOUSEBUTTONUP:
buttons.remove(event.button)
buttons_released.add(event.button)
elif event.type == pygame.MOUSEMOTION:
mouse_position = Vec2(float(event.pos[0]), float(event.pos[1]))
world.set(Keyboard(keys, keys_pressed, keys_released))
world.set(Mouse(buttons, buttons_pressed, buttons_released, mouse_position))
@staticmethod
def _terminate_pygame(world: World) -> None:
pygame.quit()
def apply(self, game: Game) -> None:
"""
Applique le plugin a un jeu.
Paramètres:
game: Le jeu auquel appliquer le plugin.
"""
game.add_startup_tasks(self._initialize_pygame)
game.add_pre_update_tasks(self._check_events)
game.add_shutdown_tasks(self._terminate_pygame)
class Display:
"""
Ressource qui represente la fenetre du jeu.
"""
def __init__(self, surface: pygame.Surface) -> None:
self.surface = surface
@property
def width(self) -> int:
"""
Renvoie la largeur de la fenetre
Retourne:
La largeur de la fenetre
"""
return self.surface.get_width()
@property
def height(self) -> int:
"""
Renvoie la hauteur de la fenetre
Retourne:
La hauteur de la fenetre
"""
return self.surface.get_height()
class Keyboard:
"""
Ressource qui représente les entrées utilisateurs sur le clavier à la frame actuelle.
"""
def __init__(self, keys: set[str], pressed: set[str], released: set[str]) -> None:
self._keys = keys
self._pressed = pressed
self._released = released
def is_key_pressed(self, key_name: str) -> bool:
"""
Renvoie True si la touche *key_name* a commencé a être appuyée pendant la frame actuelle.
Paramètres:
key_name: Le nom de la touche à tester.
Retourne:
True si la touche *key_name* a commencé a être appuyée pendant la frame actuelle.
"""
return key_name in self._pressed
def is_key(self, key_name: str) -> bool:
"""
Renvoie True si la touche *key_name* est actuellement appuyée.
Paramètres:
key_name: Le nom de la touche à tester.
Retourne:
True si la touche *key_name* est actuellement appuyée.
"""
return key_name in self._keys
def is_key_released(self, key_name: str) -> bool:
"""
Renvoie True si la touche *key_name* a été relachée pendant la frame actuelle.
Paramètres:
key_name: Le nom de la touche à tester.
Retourne:
True si la touche *key_name* a été relachée pendant la frame actuelle.
"""
return key_name in self._released
class Mouse:
"""
Ressource qui représente l'état de la souris à la frame actuelle.
"""
def __init__(
self, buttons: set[int], pressed: set[int], released: set[int], position: Vec2
) -> None:
self._buttons = buttons
self._pressed = pressed
self._released = released
self._position = position
def is_button_pressed(self, button: int) -> bool:
"""
Renvoie True si le bouton *button* a commencé a être appuyée pendant la frame actuelle.
Paramètres:
button: Le numéro du bouton à tester.
Retourne:
True si le bouton *button* a commencé a être appuyée pendant la frame actuelle.
"""
return button in self._pressed
def is_button(self, button: int) -> bool:
"""
Renvoie True si le bouton *button* est actuellement appuyé.
Paramètres:
button: Le numéro du bouton à tester.
Retourne:
True si le bouton *button* est actuellement appuyé.
"""
return button in self._buttons
def is_button_released(self, button: int) -> bool:
"""
Renvoie True si le bouton *button* a été relaché pendant la frame actuelle.
Paramètres:
button: Le numéro du bouton à tester.
Retourne:
True si le bouton *button* aLongrightarrow relaché pendant la frame actuelle.
"""
return button in self._released
@property
def position(self) -> Vec2:
"""
Renvoie la position de la souris.
Retourne:
La position de la souris.
"""
return self._position