129 lines
5.7 KiB
Markdown
129 lines
5.7 KiB
Markdown
<!-- file: docs/architecture/004-INPUT_AND_CONTROLS.md -->
|
|
<!-- version: 8 -->
|
|
|
|
# Abstraction des entrées et contrôles
|
|
|
|
## Règle générale
|
|
|
|
Le gameplay manipule des actions logiques et non des périphériques physiques. Une action comme `Primary`, `Left` ou `Pause` peut donc provenir d'un clavier, d'une souris, d'un écran tactile ou d'un gamepad sans modifier les règles du jeu.
|
|
|
|
## Desktop
|
|
|
|
Entrées possibles :
|
|
|
|
- clavier : flèches, WASD, espace, touches de fonction ;
|
|
- souris : clic principal/secondaire, position, mouvement relatif, molette ;
|
|
- gamepad et joystick ;
|
|
- trackpad lorsqu'il est présenté comme pointeur ou geste exploitable.
|
|
|
|
## Android
|
|
|
|
Schémas de contrôle envisagés :
|
|
|
|
- boutons virtuels ;
|
|
- tap simple ;
|
|
- swipe horizontal ou vertical ;
|
|
- drag direct ;
|
|
- joystick virtuel ;
|
|
- touch relatif sans joystick visible ;
|
|
- multitouch ;
|
|
- accéléromètre, gyroscope et orientation lorsqu'un jeu le justifie ;
|
|
- vibration/haptique comme retour, derrière un service plateforme.
|
|
|
|
## Web
|
|
|
|
Le navigateur peut combiner clavier, souris et tactile. Le mapping doit produire les mêmes actions logiques que les autres plateformes.
|
|
|
|
## État normalisé
|
|
|
|
Une représentation de type suivant peut être introduite lorsque nécessaire :
|
|
|
|
```rust
|
|
pub struct InputState {
|
|
pub move_x: f32,
|
|
pub move_y: f32,
|
|
pub primary: bool,
|
|
pub secondary: bool,
|
|
pub pause: bool,
|
|
}
|
|
```
|
|
|
|
Cette structure n'est pas imposée comme API définitive à la baseline ; elle illustre le contrat recherché.
|
|
|
|
## Orientation d'écran
|
|
|
|
Portrait convient particulièrement aux jeux one-button, merge, puzzle, idle, stacking et climber. Paysage convient mieux aux shooters, runners latéraux, survivor-like, tower defense et jeux utilisant deux zones de contrôle.
|
|
|
|
## Pointeur primaire normalisé
|
|
|
|
Le moteur V1 expose un `PointerState` indépendant de la plateforme :
|
|
|
|
- `active` indique qu'un pointeur primaire est maintenu ;
|
|
- `x` et `y` sont normalisés dans `[0.0, 1.0]` ;
|
|
- la plateforme borne les coordonnées avant de les transmettre au gameplay.
|
|
|
|
SDL3 fournit cette abstraction sur Android avec les événements `FingerDown`, `FingerMotion`, `FingerUp` et `FingerCanceled`.
|
|
|
|
La baseline `0.1.0-0-pre.8` mappe également un doigt actif vers `GameAction::Primary`. Cette association est volontairement minimale et pourra être remplacée par des zones tactiles ou boutons virtuels par jeu.
|
|
|
|
Le gameplay ne dépend d'aucun type Android, Java ou SDL3.
|
|
|
|
## Impulsion Primary et état maintenu
|
|
|
|
À partir de `0.1.0-0-pre.10`, `GameAction::Primary` représente une impulsion de déclenchement pour souris/tactile :
|
|
|
|
- `MouseButtonDown` gauche produit une impulsion `Primary` ;
|
|
- `FingerDown` produit une impulsion `Primary` ;
|
|
- les mouvements mettent à jour `PointerState` sans répéter `Primary` ;
|
|
- `MouseButtonUp`, `FingerUp` et `FingerCanceled` désactivent le pointeur.
|
|
|
|
Cette séparation empêche un contact maintenu de produire un succès par frame.
|
|
|
|
## Directions clavier et tactile
|
|
|
|
Les flèches clavier produisent `Left`, `Right`, `Up` et `Down`.
|
|
|
|
Snake utilise désormais un geste directionnel et non la position absolue du tap.
|
|
|
|
Pour souris et tactile :
|
|
|
|
- `Down` mémorise l'origine normalisée ;
|
|
- les mouvements mettent à jour le pointeur sans produire de direction ;
|
|
- `Up` compare l'origine et la position finale ;
|
|
- le déplacement doit dépasser un seuil normalisé minimal ;
|
|
- l'axe dominant détermine `Left`, `Right`, `Up` ou `Down` ;
|
|
- un simple tap ou un micro-mouvement ne produit aucune direction ;
|
|
- `Canceled` annule le geste.
|
|
|
|
Reflex conserve son impulsion `Primary` sur `Down` et reste donc indépendant de la reconnaissance du swipe.
|
|
|
|
## Baseline Snake portable `0.3.0`
|
|
|
|
La crate `game-snake-poc` consomme uniquement le contrat générique `engine-v1-common` pour son gameplay. Elle ne dépend pas de `engine-v1-platform-api`, de SDL3, du DOM ou d'un type de périphérique concret.
|
|
|
|
Le contrat d'entrée Snake retenu pour le premier POC Web est volontairement minimal :
|
|
|
|
- `Left`, `Right`, `Up` et `Down` pilotent la direction ;
|
|
- le rejet d'un demi-tour opposé reste une règle du gameplay Snake ;
|
|
- `Primary`, `Secondary`, `Pause` et le pointeur normalisé ne sont pas requis par le gameplay Snake actuel ;
|
|
- le host traduit clavier, swipe ou boutons virtuels vers les mêmes actions directionnelles ;
|
|
- le rendu reste exposé par `EngineGame::scene` sous forme d'`EngineScene`, sans dépendance au Canvas ou à SDL3.
|
|
|
|
Le futur adapter WASM de `0-pre.3` doit donc adapter ce contrat existant plutôt que créer un second modèle d'entrée ou de rendu propre au Web. Les besoins de provenance, monétisation ou autres services plateforme appartiennent au host/launcher et ne justifient pas une dépendance plateforme inutilisée dans la crate de gameplay.
|
|
|
|
## Requête de sortie
|
|
|
|
La plateforme ne décide plus directement de terminer un jeu. Elle traduit l'événement physique en `QuitRequest` :
|
|
|
|
- fermeture de fenêtre → `QuitSource::WindowClose` ;
|
|
- `Escape` Desktop → `QuitSource::Escape` ;
|
|
- Back Android → `QuitSource::PlatformBack`.
|
|
|
|
`EngineGame::quit_requested` retourne un `QuitDecision`. Le comportement par défaut est `QuitDecision::Exit`.
|
|
|
|
Un jeu peut retourner `QuitDecision::Continue` après avoir modifié son état afin de mettre la partie en pause, demander confirmation, revenir à un écran précédent, préparer un Hall of Fame, sauvegarder ou commencer une action avant une sortie ultérieure.
|
|
|
|
Sur Android, `SDL_ANDROID_TRAP_BACK_BUTTON=1` reste activé. Le runtime reconnaît le Back via `Keycode::AcBack` ou `Scancode::AcBack`.
|
|
|
|
Le contrôle `X` SDL spécifique Android de `0-pre.11.fix.4` est supprimé : le contrôle système Back est la frontière plateforme de référence. Une future UI de confirmation ou navigation appartient au jeu ou à une couche UI moteur.
|