ecs #58

Merged
raphael merged 70 commits from ecs into main 2023-11-03 15:29:36 +00:00
3 changed files with 218 additions and 13 deletions
Showing only changes of commit c47cae3967 - Show all commits

View file

@ -3,6 +3,7 @@ Un plugin permettant d'afficher du texte à l'écran.
"""
from typing import Optional
import pygame
from engine import GlobalPlugin
@ -22,9 +23,9 @@ class Text:
text: str,
size: int = 50,
color: pygame.Color = pygame.Color(255, 255, 255),
position: Vec2 = Vec2(0),
order: float = -1.0,
origin: Vec2 = Vec2(0),
position: Optional[Vec2] = None,
order: Optional[float] = None,
origin: Optional[Vec2] = None,
):
self.text = text
self.size = size
@ -48,8 +49,11 @@ def __render_texts(world: World):
entity[Sprite].texture = texture
else:
entity[Sprite] = Sprite(texture)
if text.position is not None:
entity[Sprite].position = text.position
if text.order is not None:
entity[Sprite].order = text.order
if text.origin is not None:
entity[Sprite].origin = text.origin

View file

@ -3,15 +3,92 @@ Scène du jeu dans lequel Windows Defender se cache de Edmond dans les dossiers.
"""
from engine import Scene
from engine.ecs import Entity
from engine.ecs import Entity, World
from engine.math import Vec2
from plugins import assets as plugin_assets, render
from plugins import assets as plugin_assets, render, smooth
from plugins.click import Clicked
from plugins.inputs import Held, MousePosition
from plugins.assets import Assets
from plugins.render import Sprite
from plugins.sound import Sound
from plugins.text import Text
LINES = 3
COLUMNS = 5
SPACING = 200
NAMES = [
"Classique",
"Menteur",
"Tricheur",
"Histoire",
"Je t'aime",
"Hello",
"Cheval",
"Defender",
"Dansons",
"Secrets",
"Edmond",
"Mon Amour",
"Melatonin",
"Films",
"Cinéma",
]
POSITIONS = [
Vec2(1348, 903),
Vec2(988, 903),
Vec2(808, 737),
Vec2(628, 903),
Vec2(268, 903),
Vec2(1168, 405),
Vec2(988, 571),
Vec2(808, 405),
Vec2(448, 737),
Vec2(268, 405),
Vec2(1348, 239),
Vec2(988, 239),
Vec2(628, 73),
Vec2(448, 239),
Vec2(88, 239),
]
class Directory:
"""
Composant marquand une entité comme étant un dossier.
"""
class DefenderDirectory:
"""
Composant marquant une entité comme étant le dossier de Windows Defender.
"""
class BlockedDirectory:
"""
Composant marquant une entité comme etant un dossier bloqué.
"""
class SearchingDirectory:
"""
Composant marquant une entité comme etant un dossier en train de être fouillé.
"""
class DirectoryName:
"""
Composant marquant une entité comme étant le nom d'un dossier.
Ce composant contient l'entité auquel il est lie.
"""
def __init__(self, entity: Entity):
self.entity = entity
class DirectoryPosition(Vec2):
"""
@ -37,16 +114,140 @@ class SelectedDirectory:
de la souris lors du clic.
"""
def __init__(self, entity: Entity, position: Vec2):
def __init__(self, entity: Entity, mouse_position: Vec2):
self.entity = entity
self.position = position
self.mouse_position = mouse_position
def __initialize(world: World):
"""
Prépare le monde pour le lancement de la scène.
Cette fonction fait apparaitre tous les dossiers et lance la boucle de jeu.
"""
assets = world[Assets]
# Ajout du fond
world.new_entity().set(Sprite(assets.get_texture("background")))
# Ajout des dossiers et des noms
directory_texture = assets.get_texture("directory")
for y in range(LINES):
for x in range(COLUMNS):
# Récupération du nom et de la position
position = POSITIONS.pop()
name = NAMES.pop()
# Création de l'entité du dossier
entity = world.new_entity()
entity.set(
Sprite(directory_texture, position, 1, origin=Vec2(0.5)),
DirectoryPosition(x, y),
Directory(),
)
if name == "Defender":
entity.set(DefenderDirectory())
entity[Sprite].texture = assets.get_texture("defender_directory")
# Création de l'entité du nom
world.new_entity().set(
Sprite(directory_texture, position + Vec2(0, 75)),
Text(name, 40, order=1, origin=Vec2(0.5)),
DirectoryName(entity),
)
def __control_directories(world: World):
"""
Ce système gère les déplacements de dossiers fais par l'utilisateur.
"""
# Si aucuns dossier n'est séléctioné, on attend que l'utilisateur clique sur un dossier, si
# le dossier cliqué est en train de être fouillé ou que le dossier est bloqué, on ignore
if SelectedDirectory not in world:
entities = world.query(
Clicked, Directory, without=(SearchingDirectory, BlockedDirectory)
)
if len(entities) > 0:
world.set(SelectedDirectory(entities.pop(), Vec2(world[MousePosition])))
else:
return
selected = world[SelectedDirectory]
# Si le boutton de la souris a été relaché entre temps, on supprime le dossier selectionné.
if "button_1" not in world[Held]:
del world[SelectedDirectory]
return
# Ensuite on vérifie de combien la souris a été déplacé depuis la selection du dossier,
# si cette valeur est en dessous d'un certain seuil, on ne fais rien
mouse_delta = world[MousePosition] - selected.mouse_position
if mouse_delta.length < 40:
return
# On récupère le mouvement voulu, pour cela on compare la valeur absolue du déplacement
# de la souris sur l'axe des x et de la souris sur l'axe des y pour savoir lequel
# est le plus grand, puis on en deduit le mouvement voulu.
if abs(mouse_delta.x) >= abs(mouse_delta.y):
movement = Vec2(mouse_delta.x / abs(mouse_delta.x), 0)
else:
movement = Vec2(0, mouse_delta.y / abs(mouse_delta.y))
# On vérifie que le mouvement ne fait pas sortir le dossier de la grille.
new_position = selected.entity[DirectoryPosition] + movement
if (
new_position.x < 0
or new_position.x >= COLUMNS
or new_position.y < 0
or new_position.y >= LINES
):
return
# On trouve le dossier vers lequel on souhaite se diriger, si le dossier
# est en train de être fouillé ou que le dossier est bloqué, on ne fait rien
for entity in world.query(
Directory, without=(SearchingDirectory, BlockedDirectory)
):
if entity[DirectoryPosition] == new_position:
other_directory = entity
break
else:
return
# On inverse la position des deux dossiers
selected_directory = selected.entity
other_directory[DirectoryPosition], selected_directory[DirectoryPosition] = (
selected_directory[DirectoryPosition],
other_directory[DirectoryPosition],
)
# On joue un son de déplacement
world.new_entity().set(Sound(world[Assets].get_sound("move_directory")))
# On supprime le dossier selectionné
del world[SelectedDirectory]
def __update_graphics(world: World):
"""
Met à jour tous ce qui est relatif au graphismes de la scène.
"""
# On met à jour la position des dossiers
for entity in world.query(Directory, DirectoryPosition):
entity.set(smooth.Target(entity[DirectoryPosition].screen_position()))
# On met à jour la position des noms des dossiers
for entity in world.query(DirectoryName):
entity[smooth.Target] = entity[DirectoryName].entity[smooth.Target] + Vec2(
0, 75
)
SCENE = plugin_assets.loading_scene(
Scene(
[__initialize],
[__control_directories, __update_graphics],
[],
[],
[],
),
)
+ smooth.PLUGIN,
"story/directory_search",
)