Mode menteur #45
BIN
assets/krita/blue_directory.kra
Normal file
BIN
assets/krita/loupe.kra
Normal file
BIN
assets/sounds/click/click0.wav
Normal file
BIN
assets/sounds/click/click1.wav
Normal file
BIN
assets/sounds/click/click2.wav
Normal file
BIN
assets/sounds/lose_sound.wav
Normal file
BIN
assets/sounds/menu_click.wav
Normal file
BIN
assets/sounds/slide.wav
Normal file
BIN
assets/sounds/win_sound.wav
Normal file
BIN
assets/textures/animations/fade_desktop/0000.png
Normal file
Before Width: | Height: | Size: 342 KiB After Width: | Height: | Size: 342 KiB |
BIN
assets/textures/animations/fade_desktop/0001.png
Normal file
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 336 KiB |
BIN
assets/textures/animations/fade_desktop/0002.png
Normal file
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
BIN
assets/textures/animations/fade_desktop/0003.png
Normal file
Before Width: | Height: | Size: 324 KiB After Width: | Height: | Size: 324 KiB |
BIN
assets/textures/animations/fade_desktop/0004.png
Normal file
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 322 KiB |
BIN
assets/textures/animations/fade_desktop/0005.png
Normal file
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 318 KiB |
BIN
assets/textures/animations/fade_desktop/0006.png
Normal file
Before Width: | Height: | Size: 317 KiB After Width: | Height: | Size: 317 KiB |
BIN
assets/textures/animations/fade_desktop/0007.png
Normal file
Before Width: | Height: | Size: 309 KiB After Width: | Height: | Size: 309 KiB |
BIN
assets/textures/animations/fade_desktop/0008.png
Normal file
Before Width: | Height: | Size: 307 KiB After Width: | Height: | Size: 307 KiB |
BIN
assets/textures/animations/fade_desktop/0009.png
Normal file
Before Width: | Height: | Size: 301 KiB After Width: | Height: | Size: 301 KiB |
BIN
assets/textures/animations/fade_desktop/0010.png
Normal file
Before Width: | Height: | Size: 296 KiB After Width: | Height: | Size: 296 KiB |
BIN
assets/textures/animations/fade_desktop/0011.png
Normal file
Before Width: | Height: | Size: 292 KiB After Width: | Height: | Size: 292 KiB |
BIN
assets/textures/animations/fade_desktop/0012.png
Normal file
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 286 KiB |
BIN
assets/textures/animations/fade_desktop/0013.png
Normal file
Before Width: | Height: | Size: 282 KiB After Width: | Height: | Size: 282 KiB |
BIN
assets/textures/animations/fade_desktop/0014.png
Normal file
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 276 KiB |
BIN
assets/textures/animations/fade_desktop/0015.png
Normal file
Before Width: | Height: | Size: 272 KiB After Width: | Height: | Size: 272 KiB |
BIN
assets/textures/animations/fade_desktop/0016.png
Normal file
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 268 KiB |
BIN
assets/textures/animations/fade_desktop/0017.png
Normal file
Before Width: | Height: | Size: 265 KiB After Width: | Height: | Size: 265 KiB |
BIN
assets/textures/animations/fade_desktop/0018.png
Normal file
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 260 KiB |
BIN
assets/textures/animations/fade_desktop/0019.png
Normal file
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
BIN
assets/textures/animations/fade_desktop/0020.png
Normal file
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
BIN
assets/textures/animations/fade_desktop/0021.png
Normal file
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 246 KiB |
BIN
assets/textures/animations/fade_desktop/0022.png
Normal file
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 244 KiB |
BIN
assets/textures/animations/fade_desktop/0023.png
Normal file
Before Width: | Height: | Size: 240 KiB After Width: | Height: | Size: 240 KiB |
BIN
assets/textures/animations/fade_desktop/0024.png
Normal file
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 236 KiB |
BIN
assets/textures/animations/fade_desktop/0025.png
Normal file
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 232 KiB |
BIN
assets/textures/animations/fade_desktop/0026.png
Normal file
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 230 KiB |
BIN
assets/textures/animations/fade_desktop/0027.png
Normal file
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 226 KiB |
BIN
assets/textures/animations/fade_desktop/0028.png
Normal file
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 225 KiB |
BIN
assets/textures/animations/fade_desktop/0029.png
Normal file
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
BIN
assets/textures/animations/fade_desktop/0030.png
Normal file
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 216 KiB |
9
assets/textures/animations/fade_desktop/info.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"end_image": "dark_desktop.png",
|
||||||
|
"offset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"frame_count": 31,
|
||||||
|
"fps": 60
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
"end_image": "directory.png",
|
|
||||||
"offset": {
|
"offset": {
|
||||||
"x": -48,
|
"x": 8,
|
||||||
"y": -176
|
"y": -83
|
||||||
},
|
},
|
||||||
"frame_count": 268,
|
"frame_count": 268,
|
||||||
"fps": 60
|
"fps": 60
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"offset": {
|
||||||
|
"x": 8,
|
||||||
|
"y": -83
|
||||||
|
},
|
||||||
|
"frame_count": 268,
|
||||||
|
"fps": 60
|
||||||
|
}
|
BIN
assets/textures/attack_point.png
Normal file
Before Width: | Height: | Size: 6 KiB After Width: | Height: | Size: 6 KiB |
BIN
assets/textures/dark_desktop.png
Normal file
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 216 KiB |
BIN
assets/textures/user_directory.png
Normal file
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
@ -6,6 +6,7 @@ Un moteur de jeu inspiré de bevy.
|
||||||
import json
|
import json
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
from typing import Callable, Optional, Sequence, SupportsFloat, TypeVar, Union
|
from typing import Callable, Optional, Sequence, SupportsFloat, TypeVar, Union
|
||||||
from time import time
|
from time import time
|
||||||
import pygame
|
import pygame
|
||||||
|
@ -433,6 +434,7 @@ class Mouse:
|
||||||
self.pressed: set[int] = set()
|
self.pressed: set[int] = set()
|
||||||
self.released: set[int] = set()
|
self.released: set[int] = set()
|
||||||
self.position: Vec2 = Vec2(0.0, 0.0)
|
self.position: Vec2 = Vec2(0.0, 0.0)
|
||||||
|
self.delta: Vec2 = Vec2(0.0, 0.0)
|
||||||
|
|
||||||
def is_button_pressed(self, button: int) -> bool:
|
def is_button_pressed(self, button: int) -> bool:
|
||||||
"""
|
"""
|
||||||
|
@ -592,6 +594,12 @@ class Sound:
|
||||||
stop_on_remove: bool = False,
|
stop_on_remove: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
if os.path.isdir(f"assets/sounds/{name}"):
|
||||||
|
list_files = os.listdir(f"assets/sounds/{name}")
|
||||||
|
random_file = random.choice(list_files)
|
||||||
|
self.name = f"{name}/{random_file}"
|
||||||
|
|
||||||
self.volume = volume
|
self.volume = volume
|
||||||
self.loop = loop
|
self.loop = loop
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
|
@ -670,6 +678,7 @@ def start_game(
|
||||||
keyboard.released.clear()
|
keyboard.released.clear()
|
||||||
mouse.pressed.clear()
|
mouse.pressed.clear()
|
||||||
mouse.released.clear()
|
mouse.released.clear()
|
||||||
|
last_position = Vec2(mouse.position)
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
world[Game].stop()
|
world[Game].stop()
|
||||||
|
@ -697,6 +706,7 @@ def start_game(
|
||||||
((event.pos[0] - rect[0]) / rect[2]) * Display.WIDTH,
|
((event.pos[0] - rect[0]) / rect[2]) * Display.WIDTH,
|
||||||
((event.pos[1] - rect[1]) / rect[3]) * Display.HEIGHT,
|
((event.pos[1] - rect[1]) / rect[3]) * Display.HEIGHT,
|
||||||
)
|
)
|
||||||
|
mouse.delta = mouse.position - last_position
|
||||||
|
|
||||||
# On vérifie le survol des textures et textes
|
# On vérifie le survol des textures et textes
|
||||||
for entity in world.query(Position, Texture):
|
for entity in world.query(Position, Texture):
|
||||||
|
|
|
@ -4,7 +4,7 @@ Example de l'utilisation du moteur de jeu.
|
||||||
|
|
||||||
|
|
||||||
from engine import start_game
|
from engine import start_game
|
||||||
from scenes import classique, menteur, menu
|
from scenes import classique, menteur, menu, directory_search
|
||||||
|
|
||||||
|
|
||||||
start_game(
|
start_game(
|
||||||
|
@ -12,7 +12,9 @@ start_game(
|
||||||
"menu": menu.SCENE,
|
"menu": menu.SCENE,
|
||||||
"classique": classique.SCENE,
|
"classique": classique.SCENE,
|
||||||
"menteur": menteur.SCENE
|
"menteur": menteur.SCENE
|
||||||
|
"histoire": directory_search.SCENE,
|
||||||
},
|
},
|
||||||
"menu",
|
"menu",
|
||||||
title="Guess The Number",
|
title="Guess The Number",
|
||||||
)
|
)
|
||||||
|
# type: ignore
|
37
src/plugins/smooth.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
"""
|
||||||
|
Un plugin permettant de faire des déplacements fluides des entités.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from engine import Delta, Position, Scene, Vec2, World
|
||||||
|
|
||||||
|
|
||||||
|
class Target(Vec2):
|
||||||
|
"""
|
||||||
|
Composant donnant la position voulue de l'entité.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Speed(float):
|
||||||
|
"""
|
||||||
|
Composant donnant la vittesse de déplacement de l'entité.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def __update_positions(world: World):
|
||||||
|
"""
|
||||||
|
Met à jour la position des entités pour se rapprocher de la position voulue.
|
||||||
|
"""
|
||||||
|
for entity in world.query(Position, Target):
|
||||||
|
position = entity[Position]
|
||||||
|
target = entity[Target]
|
||||||
|
speed = entity[Speed] if Speed in entity else Speed(10)
|
||||||
|
entity[Position] = Position(
|
||||||
|
position + (target - position) * world[Delta] * speed
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
PLUGIN = Scene(
|
||||||
|
[],
|
||||||
|
[__update_positions],
|
||||||
|
[],
|
||||||
|
)
|
|
@ -2,7 +2,7 @@
|
||||||
Definit un plugin qui crée un texte avec les touches frappées
|
Definit un plugin qui crée un texte avec les touches frappées
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from engine import Keyboard, Scene, Text, World
|
from engine import Keyboard, Scene, Sound, Text, World
|
||||||
|
|
||||||
|
|
||||||
class Typing(str):
|
class Typing(str):
|
||||||
|
@ -20,10 +20,12 @@ def __update(world: World):
|
||||||
text = entity[Text]
|
text = entity[Text]
|
||||||
for key in keyboard.pressed:
|
for key in keyboard.pressed:
|
||||||
if key == "backspace":
|
if key == "backspace":
|
||||||
|
world.create_entity(Sound("click"))
|
||||||
text = text[:-1]
|
text = text[:-1]
|
||||||
if key.startswith("["): # pavé numerique
|
if key.startswith("["): # pavé numerique
|
||||||
key = key[1]
|
key = key[1]
|
||||||
if key in entity[Typing]:
|
if key in entity[Typing]:
|
||||||
|
world.create_entity(Sound("click"))
|
||||||
text += key
|
text += key
|
||||||
entity[Text] = Text(text)
|
entity[Text] = Text(text)
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,14 @@ from engine import (
|
||||||
Clickable,
|
Clickable,
|
||||||
Color,
|
Color,
|
||||||
Display,
|
Display,
|
||||||
|
Entity,
|
||||||
Game,
|
Game,
|
||||||
HoveredTexture,
|
HoveredTexture,
|
||||||
Keyboard,
|
Keyboard,
|
||||||
Order,
|
Order,
|
||||||
Position,
|
Position,
|
||||||
Scene,
|
Scene,
|
||||||
|
Sound,
|
||||||
Text,
|
Text,
|
||||||
TextSize,
|
TextSize,
|
||||||
Texture,
|
Texture,
|
||||||
|
@ -113,7 +115,7 @@ def __initialize_world(world: World):
|
||||||
Order(11),
|
Order(11),
|
||||||
Position(150, 150),
|
Position(150, 150),
|
||||||
Texture("classique/arrow.png"),
|
Texture("classique/arrow.png"),
|
||||||
Clickable(lambda world, _: world[Game].change_scene("menu")),
|
Clickable(on_menu_button),
|
||||||
HoveredTexture("classique/arrow_hover.png"),
|
HoveredTexture("classique/arrow_hover.png"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -123,12 +125,22 @@ def __initialize_world(world: World):
|
||||||
world[IsRunning] = IsRunning()
|
world[IsRunning] = IsRunning()
|
||||||
|
|
||||||
|
|
||||||
|
def on_menu_button(world: World, entity: Entity):
|
||||||
|
"""
|
||||||
|
Fonction qui s'execute quand on clique sur un bouton.
|
||||||
|
"""
|
||||||
|
world[Game].change_scene("menu")
|
||||||
|
entity[Sound] = Sound("click")
|
||||||
|
|
||||||
|
|
||||||
def _update(world: World):
|
def _update(world: World):
|
||||||
"""
|
"""
|
||||||
Verifie si le nombre donné est le meme que celui que l'on a choisi.
|
Verifie si le nombre donné est le meme que celui que l'on a choisi.
|
||||||
Boucle du jeu.
|
Boucle du jeu.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
world.create_entity(Sound("menu_click.wav"))
|
||||||
|
|
||||||
# si le jeu s'est arrete.
|
# si le jeu s'est arrete.
|
||||||
if IsRunning not in world:
|
if IsRunning not in world:
|
||||||
# on relance le jeu.
|
# on relance le jeu.
|
||||||
|
@ -169,6 +181,12 @@ def end_game(world: World, state: str):
|
||||||
"""
|
"""
|
||||||
del world[IsRunning] # le jeu est fini.
|
del world[IsRunning] # le jeu est fini.
|
||||||
|
|
||||||
|
# On joue le son
|
||||||
|
if state == "Gagné":
|
||||||
|
world.create_entity(Sound("win_sound.wav"))
|
||||||
|
else:
|
||||||
|
world.create_entity(Sound("lose_sound.wav"))
|
||||||
|
|
||||||
# On affiche le message de fin.
|
# On affiche le message de fin.
|
||||||
for entity_text in world.query(TextDialogue):
|
for entity_text in world.query(TextDialogue):
|
||||||
entity_text[Text] = Text(f"{state} !")
|
entity_text[Text] = Text(f"{state} !")
|
||||||
|
|
378
src/scenes/directory_search.py
Normal file
|
@ -0,0 +1,378 @@
|
||||||
|
"""
|
||||||
|
Scène du jeu dans lequel on se cache de Edmond dans les dossiers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
import random
|
||||||
|
from engine import (
|
||||||
|
Animation,
|
||||||
|
Centered,
|
||||||
|
Delta,
|
||||||
|
Display,
|
||||||
|
Entity,
|
||||||
|
Hovered,
|
||||||
|
Mouse,
|
||||||
|
Order,
|
||||||
|
Position,
|
||||||
|
Scene,
|
||||||
|
Sound,
|
||||||
|
Text,
|
||||||
|
TextSize,
|
||||||
|
Texture,
|
||||||
|
Vec2,
|
||||||
|
World,
|
||||||
|
)
|
||||||
|
from plugins import smooth
|
||||||
|
|
||||||
|
|
||||||
|
LINES = 3
|
||||||
|
COLUMNS = 5
|
||||||
|
SPACING = 200
|
||||||
|
|
||||||
|
|
||||||
|
class State(Enum):
|
||||||
|
"""
|
||||||
|
Etat de la scène.
|
||||||
|
"""
|
||||||
|
|
||||||
|
MOVING = 0
|
||||||
|
SEARCHING = 1
|
||||||
|
GAME_OVER = 2
|
||||||
|
|
||||||
|
|
||||||
|
class SelectedDirectory:
|
||||||
|
"""
|
||||||
|
Une ressource qui stoque le dossier selectionné pour le déplacement.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, entity: Entity, start_position: Vec2):
|
||||||
|
self.entity = entity
|
||||||
|
self.position = start_position
|
||||||
|
|
||||||
|
|
||||||
|
class AttackTimer(float):
|
||||||
|
"""
|
||||||
|
Ressource qui stoque un timer pour l'attaque.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class AttackSpeed(float):
|
||||||
|
"""
|
||||||
|
Ressource qui dit le temps de l'attaque.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class DirectoryPosition:
|
||||||
|
"""
|
||||||
|
La position d'un dossier dans la grille.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, x: int, y: int):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
|
def __eq__(self, value: object) -> bool:
|
||||||
|
if isinstance(value, DirectoryPosition):
|
||||||
|
return self.x == value.x and self.y == value.y
|
||||||
|
return False
|
||||||
|
|
||||||
|
def screen_position(self) -> Vec2:
|
||||||
|
"""
|
||||||
|
Calcule la position de l'entité sur l'ecran.
|
||||||
|
"""
|
||||||
|
size = Vec2(SPACING)
|
||||||
|
offset = -(size * Vec2(COLUMNS - 1, LINES - 1) / 2)
|
||||||
|
first_position = Vec2(Display.WIDTH / 2, Display.HEIGHT / 2) + offset
|
||||||
|
return first_position + Vec2(self.x, self.y) * size
|
||||||
|
|
||||||
|
|
||||||
|
class AttackPoint(DirectoryPosition):
|
||||||
|
"""
|
||||||
|
Composant qui marque un point d'attaque.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class DirectoryName:
|
||||||
|
"""
|
||||||
|
Composant qui marque une entité comme étant le nom d'un dossier.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, entity: Entity):
|
||||||
|
self.entity = entity
|
||||||
|
|
||||||
|
|
||||||
|
class UserDirectory:
|
||||||
|
"""
|
||||||
|
Composant qui marque le dossier que l'utilisateur doit protéger.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class GameStarted:
|
||||||
|
"""
|
||||||
|
Une ressource qui permet de savoir que le jeu commence.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def __change_folders_speeds(world: World, _e: Entity):
|
||||||
|
"""
|
||||||
|
Change les vitesses des dossiers.
|
||||||
|
"""
|
||||||
|
for entity in world.query(DirectoryPosition, smooth.Speed):
|
||||||
|
entity[smooth.Speed] = smooth.Speed(random.uniform(2.0, 2.5))
|
||||||
|
for entity in world.query(TextSize):
|
||||||
|
entity[TextSize] = TextSize(40)
|
||||||
|
|
||||||
|
|
||||||
|
def __remove_folders_speeds(world: World):
|
||||||
|
"""
|
||||||
|
Supprime les vitesses des dossiers.
|
||||||
|
"""
|
||||||
|
if GameStarted not in world and world[AttackTimer] >= 3.0:
|
||||||
|
for entity in world.query(DirectoryPosition, smooth.Speed):
|
||||||
|
del entity[smooth.Speed]
|
||||||
|
world[GameStarted] = GameStarted()
|
||||||
|
|
||||||
|
|
||||||
|
def __initialize_world(world: World):
|
||||||
|
"""
|
||||||
|
Initialise le monde de la scène.
|
||||||
|
"""
|
||||||
|
world[State] = State.MOVING
|
||||||
|
world[AttackTimer] = AttackTimer(0.0)
|
||||||
|
world[AttackSpeed] = AttackSpeed(5.0)
|
||||||
|
|
||||||
|
world.create_entity(
|
||||||
|
Position(),
|
||||||
|
Order(0),
|
||||||
|
Animation("fade_desktop", __change_folders_speeds),
|
||||||
|
)
|
||||||
|
|
||||||
|
names = [
|
||||||
|
"Classique",
|
||||||
|
"Menteur",
|
||||||
|
"Tricheur",
|
||||||
|
"Histoire",
|
||||||
|
"Je t'aime",
|
||||||
|
"Hello",
|
||||||
|
"Cheval",
|
||||||
|
"Defender",
|
||||||
|
"Dansons",
|
||||||
|
"Secrets",
|
||||||
|
"Edmond",
|
||||||
|
"Mon Amour",
|
||||||
|
"Melatonin",
|
||||||
|
"Films",
|
||||||
|
"Cinéma",
|
||||||
|
]
|
||||||
|
|
||||||
|
positions = [
|
||||||
|
Position(40 + (7 * 180) + 48, 35 + (5 * 166) + 38),
|
||||||
|
Position(40 + (5 * 180) + 48, 35 + (5 * 166) + 38),
|
||||||
|
Position(40 + (4 * 180) + 48, 35 + (4 * 166) + 38),
|
||||||
|
Position(40 + (3 * 180) + 48, 35 + (5 * 166) + 38),
|
||||||
|
Position(40 + (1 * 180) + 48, 35 + (5 * 166) + 38),
|
||||||
|
Position(40 + (6 * 180) + 48, 35 + (2 * 166) + 38),
|
||||||
|
Position(40 + (5 * 180) + 48, 35 + (3 * 166) + 38),
|
||||||
|
Position(40 + (4 * 180) + 48, 35 + (2 * 166) + 38),
|
||||||
|
Position(40 + (2 * 180) + 48, 35 + (4 * 166) + 38),
|
||||||
|
Position(40 + (1 * 180) + 48, 35 + (2 * 166) + 38),
|
||||||
|
Position(40 + (7 * 180) + 48, 35 + (1 * 166) + 38),
|
||||||
|
Position(40 + (5 * 180) + 48, 35 + (1 * 166) + 38),
|
||||||
|
Position(40 + (3 * 180) + 48, 35 + (0 * 166) + 38),
|
||||||
|
Position(40 + (2 * 180) + 48, 35 + (1 * 166) + 38),
|
||||||
|
Position(40 + (0 * 180) + 48, 35 + (1 * 166) + 38),
|
||||||
|
]
|
||||||
|
|
||||||
|
for y in range(LINES):
|
||||||
|
for x in range(COLUMNS):
|
||||||
|
position = DirectoryPosition(x, y)
|
||||||
|
entity = world.create_entity(
|
||||||
|
positions.pop(),
|
||||||
|
smooth.Speed(0),
|
||||||
|
Order(1),
|
||||||
|
Centered(),
|
||||||
|
Texture("directory.png"),
|
||||||
|
position,
|
||||||
|
)
|
||||||
|
|
||||||
|
if x == 2 and y == 1:
|
||||||
|
entity[UserDirectory] = UserDirectory()
|
||||||
|
entity[Texture] = Texture("user_directory.png")
|
||||||
|
|
||||||
|
world.create_entity(
|
||||||
|
Position(0, 0),
|
||||||
|
Order(1),
|
||||||
|
Centered(),
|
||||||
|
Text(names.pop()),
|
||||||
|
TextSize(0),
|
||||||
|
DirectoryName(entity),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def __attacks(world: World):
|
||||||
|
"""
|
||||||
|
Déclenche les attaques de Edmond.
|
||||||
|
"""
|
||||||
|
if world[State] == State.GAME_OVER:
|
||||||
|
return
|
||||||
|
world[AttackTimer] = AttackTimer(world[AttackTimer] + world[Delta])
|
||||||
|
timer = world[AttackTimer]
|
||||||
|
if timer >= world[AttackSpeed] and world[State] == State.MOVING:
|
||||||
|
world[State] = State.SEARCHING
|
||||||
|
for entity in world.query(AttackPoint):
|
||||||
|
position = entity[AttackPoint]
|
||||||
|
for directory_entity in world.query(DirectoryPosition):
|
||||||
|
if directory_entity[DirectoryPosition] == position:
|
||||||
|
if UserDirectory in directory_entity:
|
||||||
|
directory_entity[Animation] = Animation(
|
||||||
|
"search_directory_failed"
|
||||||
|
)
|
||||||
|
world[State] = State.GAME_OVER
|
||||||
|
else:
|
||||||
|
directory_entity[Animation] = Animation("search_directory")
|
||||||
|
del entity[AttackPoint]
|
||||||
|
del entity[Position]
|
||||||
|
del entity[Order]
|
||||||
|
del entity[Centered]
|
||||||
|
del entity[Texture]
|
||||||
|
elif timer >= world[AttackSpeed] + 4.5 and world[State] == State.SEARCHING:
|
||||||
|
world[State] = State.MOVING
|
||||||
|
for _ in range(10):
|
||||||
|
position = AttackPoint(
|
||||||
|
random.randint(0, COLUMNS - 1),
|
||||||
|
random.randint(0, LINES - 1),
|
||||||
|
)
|
||||||
|
world.create_entity(
|
||||||
|
position,
|
||||||
|
Position(position.screen_position()),
|
||||||
|
Order(50),
|
||||||
|
Centered(),
|
||||||
|
Texture("attack_point.png"),
|
||||||
|
)
|
||||||
|
world[AttackTimer] = AttackTimer(0.0)
|
||||||
|
world[AttackSpeed] = AttackSpeed(world[AttackSpeed] * 0.9)
|
||||||
|
|
||||||
|
|
||||||
|
def __move_directories(world: World):
|
||||||
|
"""
|
||||||
|
Permet de déplacer les dossiers avec la souris.
|
||||||
|
"""
|
||||||
|
# Si on n'est pas dans le bon state on annule
|
||||||
|
if GameStarted not in world or world[State] == State.GAME_OVER:
|
||||||
|
return
|
||||||
|
|
||||||
|
# On met à jour la séléction
|
||||||
|
mouse = world[Mouse]
|
||||||
|
for entity in world.query(Hovered, DirectoryPosition):
|
||||||
|
if Animation in entity:
|
||||||
|
continue
|
||||||
|
if mouse.is_button_pressed(1):
|
||||||
|
world[SelectedDirectory] = SelectedDirectory(entity, Vec2(mouse.position))
|
||||||
|
break
|
||||||
|
|
||||||
|
# Si un dossier est séléctionné
|
||||||
|
if SelectedDirectory in world:
|
||||||
|
selected_directory = world[SelectedDirectory]
|
||||||
|
selected_entity = selected_directory.entity
|
||||||
|
directory_position = selected_entity[DirectoryPosition]
|
||||||
|
|
||||||
|
# Vérification du relachement de la souris
|
||||||
|
if not mouse.is_button(1):
|
||||||
|
del world[SelectedDirectory]
|
||||||
|
return
|
||||||
|
|
||||||
|
# On calcule le déplacement de la souris
|
||||||
|
mouse_delta = mouse.position - selected_directory.position
|
||||||
|
|
||||||
|
# On annule si il y a pas eu de déplacement significatif de la souris
|
||||||
|
if mouse_delta.length < 40:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Récupération du mouvement voulu
|
||||||
|
if abs(mouse_delta.x) >= abs(mouse_delta.y):
|
||||||
|
movement = (int(mouse_delta.x / abs(mouse_delta.x)), 0)
|
||||||
|
else:
|
||||||
|
movement = (0, int(mouse_delta.y / abs(mouse_delta.y)))
|
||||||
|
|
||||||
|
# Récupération des mouvements possible du dossier
|
||||||
|
movements: list[tuple[int, int]] = []
|
||||||
|
if directory_position.x != 0:
|
||||||
|
movements.append((-1, 0))
|
||||||
|
if directory_position.x != COLUMNS - 1:
|
||||||
|
movements.append((1, 0))
|
||||||
|
if directory_position.y != 0:
|
||||||
|
movements.append((0, -1))
|
||||||
|
if directory_position.y != LINES - 1:
|
||||||
|
movements.append((0, 1))
|
||||||
|
if len(movements) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Si le mouvement n'est pas possible, on annule
|
||||||
|
if movement not in movements:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Si l'entité est animé on annule
|
||||||
|
if Animation in selected_entity:
|
||||||
|
return
|
||||||
|
|
||||||
|
# On trouve l'autre dossier
|
||||||
|
for entity in world.query(DirectoryPosition, without=(Animation,)):
|
||||||
|
if entity != selected_entity and entity[
|
||||||
|
DirectoryPosition
|
||||||
|
] == DirectoryPosition(
|
||||||
|
directory_position.x + movement[0],
|
||||||
|
directory_position.y + movement[1],
|
||||||
|
):
|
||||||
|
other_directory = entity
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
# On actualise la position de l'autre dossier
|
||||||
|
other_directory[DirectoryPosition].x -= movement[0]
|
||||||
|
other_directory[DirectoryPosition].y -= movement[1]
|
||||||
|
|
||||||
|
# On actualise la position du dossier
|
||||||
|
selected_entity[DirectoryPosition].x += movement[0]
|
||||||
|
selected_entity[DirectoryPosition].y += movement[1]
|
||||||
|
|
||||||
|
# On joue un son
|
||||||
|
world.create_entity(Sound("slide.wav"))
|
||||||
|
|
||||||
|
# On retire le dossier selectionné
|
||||||
|
del world[SelectedDirectory]
|
||||||
|
|
||||||
|
|
||||||
|
def __update_positions(world: World):
|
||||||
|
"""
|
||||||
|
Met à jour la position cible des dossiers.
|
||||||
|
"""
|
||||||
|
for entity in world.query(DirectoryPosition):
|
||||||
|
position = entity[DirectoryPosition]
|
||||||
|
entity[smooth.Target] = smooth.Target(position.screen_position())
|
||||||
|
entity[Order] = Order(position.y + 1)
|
||||||
|
|
||||||
|
|
||||||
|
def __update_directory_names(world: World):
|
||||||
|
"""
|
||||||
|
Met à jour la position des noms des dossiers.
|
||||||
|
"""
|
||||||
|
for entity in world.query(DirectoryName):
|
||||||
|
directory_entity = entity[DirectoryName].entity
|
||||||
|
entity[Position] = Position(directory_entity[Position] + Vec2(0, 75))
|
||||||
|
entity[Order] = directory_entity[Order]
|
||||||
|
|
||||||
|
|
||||||
|
SCENE = (
|
||||||
|
Scene(
|
||||||
|
[__initialize_world],
|
||||||
|
[__attacks, __move_directories, __update_positions, __remove_folders_speeds],
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
+ smooth.PLUGIN
|
||||||
|
+ Scene(
|
||||||
|
[],
|
||||||
|
[__update_directory_names],
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
)
|
|
@ -36,7 +36,7 @@ def on_click_butons(world: World, entity: Entity, name: str):
|
||||||
"""
|
"""
|
||||||
Fonction qui s'execute quand on clique sur un bouton.
|
Fonction qui s'execute quand on clique sur un bouton.
|
||||||
"""
|
"""
|
||||||
entity[Sound] = Sound("click.wav")
|
entity[Sound] = Sound("click")
|
||||||
world[Game].change_scene(name)
|
world[Game].change_scene(name)
|
||||||
|
|
||||||
|
|
||||||
|
|