Réagir aux actions du joueur #
Représenter les actions #
-
Créer le paquet
commun.enums
-
Dans
commun.enums
, créer l’enum suivantpublic enum Action { MONTER, DESCENDRE, ARRETER; }
-
Dans
commun.enums
, créer l’enum suivantpublic enum Position { GAUCHE, DROITE; }
-
S’assurer d’avoir l’arborescence suivante
Déclencher les événements selon les actions actives #
-
NOTE: Dans un jeu vidéo, si on appuie sur ↑ et ↓ en même temps, il faut mémoriser les deux actions. Si on relâche ↑ tout en gardant ↓ enfoncé, on s’attend à ce que l’action
↓
soit encore active. -
Dans
frontal.evenements
, créer la classe suivante:public class EvtActionJoueur extends Event { private Position position; private Action action; public EvtActionJoueur setPosition(Position position) { this.position = position; return this; } public EvtActionJoueur setAction(Action action) { this.action = action; return this; } }
-
Avec
registrar.registerEvent
, déclarer l’événement dans le frontalpublic class FrontalPong implements FrontendFx { @Override public void registerEvents(EventRegistrar registrar) { // ... // ajouter registrar.registerEvent(EvtActionJoueur.class); }
-
Créer le paquet
frontal.utils
-
Dans
frontal.utils
, créer la classe suivante:public class ActionsActives { private Position position; private Set<Action> actions = new HashSet<>(); public ActionsActives(Position position) { this.position = position; } public void activer(Action action) { actions.add(action); Ntro.newEvent(EvtActionJoueur.class) .setPosition(position) .setAction(action) .trigger(); } public void desactiver(Action action) { actions.remove(action); if(actions.isEmpty()) { Ntro.newEvent(EvtActionJoueur.class) .setPosition(position) .setAction(Action.ARRETER) .trigger(); } else { for(Action actionRestante : actions) { Ntro.newEvent(EvtActionJoueur.class) .setPosition(position) .setAction(actionRestante) .trigger(); } } } }
-
Dans
frontal.utils
, créer la classe suivante:public class ActionsActivesParPosition { private Map<Position, ActionsActives> actionsActives = new HashMap<>(); public ActionsActivesParPosition() { for(Position position : Position.values()) { actionsActives.put(position, new ActionsActives(position)); } } public void activer(Position position, Action action) { if(position != null && action != null) { actionsActives.get(position).activer(action); } } public void desactiver(Position position, Action action) { if(position != null && action != null) { actionsActives.get(position).desactiver(action); } } }
-
S’assurer d’avoir l’arborescence suivante
Capter les touches du clavier et traduire en actions actives #
-
Dans
partie.xml
, ajouter unfx:id
au conteneur principal<!-- ajouter le fx:id --> <VBox xmlns:fx="http://javafx.com/fxml" fx:controller="pong.frontal.vues.VuePartie" fx:id="conteneurVuePartie" styleClass="conteneur" id="vue-partie"> <!-- ... -->
-
Dans
VuePartie
, ajouter le code suivantpublic class VuePartie extends ViewFx { // ... @FXML private Pane conteneurVuePartie; // ... private ActionsActivesParPosition actionsActives = new ActionsActivesParPosition(); @Override public void initialize() { // ... Ntro.assertNotNull(conteneurVuePartie); // ... installerEvtActionJoueur(); } private void installerEvtActionJoueur() { conteneurVuePartie.addEventFilter(KeyEvent.KEY_PRESSED, evtFx -> { Position position = positionPourTouche(evtFx.getCode()); Action action = actionPourTouche(evtFx.getCode()); actionsActives.activer(position, action); }); conteneurVuePartie.addEventFilter(KeyEvent.KEY_RELEASED, evtFx -> { Position position = positionPourTouche(evtFx.getCode()); Action action = actionPourTouche(evtFx.getCode()); actionsActives.desactiver(position, action); }); } private Position positionPourTouche(KeyCode code) { Position position = null; if(code.equals(KeyCode.W) || code.equals(KeyCode.S)) { position = Position.GAUCHE; } else if(code.equals(KeyCode.UP) || code.equals(KeyCode.DOWN)) { position = Position.DROITE; } return position; } private Action actionPourTouche(KeyCode code) { Action action = null; if(code.equals(KeyCode.W) || code.equals(KeyCode.UP)) { action = Action.MONTER; } else if(code.equals(KeyCode.S) || code.equals(KeyCode.DOWN)) { action = Action.DESCENDRE; } return action; } // ...
Ajouter une tâche pour réagir aux événements EvtActionJoueur
#
-
Dans
AfficherPartie
, ajouter la tâche suivantepublic class AfficherPartie { public static void creerTaches(FrontendTasks tasks) { // ... tasks.taskGroup("AfficherPartie") .waitsFor("afficherVuePartie") .waitsFor(created(DonneesVuePartie.class)) .contains(subTasks -> { // ... reagirActionJoueur(subTasks); // ... }); } private static void reagirActionJoueur(FrontendTasks subTasks) { subTasks.task("reagirActionJoueur") .waitsFor(event(EvtActionJoueur.class)) .waitsFor(created(DonneesVuePartie.class)) .executes(inputs -> { DonneesVuePartie donneesVuePartie = inputs.get(created(DonneesVuePartie.class)); EvtActionJoueur evtActionJoueur = inputs.get(event(EvtActionJoueur.class)); evtActionJoueur.appliquerA(donneesVuePartie); }); } // ...
-
Utiliser Ctrl+.Eclipse: Ctrl+1 pour créer la méthode
EvtActionJoueur.appliquerA
-
Coder la méthode
EvtActionJoueur.appliquerA
public class EvtActionJoueur extends Event { // ... // ajouter public void appliquerA(DonneesVuePartie donneesVuePartie) { donneesVuePartie.appliquerActionJoueur(position, action); }
-
Utiliser Ctrl+.Eclipse: Ctrl+1 pour créer la méthode
DonneesVuePartie.appliquerActionJoueur
public class DonneesVuePartie implements ViewData { // ... public void appliquerActionJoueur(Position position, Action action) { mondePong2d.appliquerActionJoueur(position, action); } // ...
-
Utiliser Ctrl+.Eclipse: Ctrl+1 pour créer la méthode
MondePong2d.appliquerActionJoueur
, puis ajouter ce codepublic class MondePong2d extends World2dFx { // ... public void appliquerActionJoueur(Position position, Action action) { Palette2d palette = paletteParPosition(position); appliquerActionJoueur(palette, action); } private Palette2d paletteParPosition(Position position) { Palette2d palette; switch(position) { case GAUCHE: default: palette = paletteGauche; break; case DROITE: palette = paletteDroite; break; } return palette; } private void appliquerActionJoueur(Palette2d palette, Action action) { switch(action) { case MONTER: palette.monter(); break; case DESCENDRE: palette.descendre(); break; case ARRETER: default: palette.arreter(); } } // ...
-
Utiliser Ctrl+.Eclipse: Ctrl+1 pour créer les méthodes
Palettes2d.monter
,Palette2d.descendre
etPalette2d.arreter
; puis ajouter ce codepublic class Palette2d extends ObjetPong2d { private static final double VITESSE_PALETTE = 200; // ... public void monter() { setSpeedY(-VITESSE_PALETTE); } public void descendre() { setSpeedY(+VITESSE_PALETTE); } public void arreter() { setSpeedY(0); } }
Vérifier #
- Vérifier que ça fonctionne