115 lines
4.6 KiB
Markdown
115 lines
4.6 KiB
Markdown
<!-- file: docs/architecture/004-INPUT_AND_CONTROLS.md -->
|
|
<!-- version: 7 -->
|
|
|
|
# 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.
|
|
|
|
## 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.
|