
Slick2d, leçon 12 :: Contrôle avec un Joystick
05 October 2014 09:38 Slick2d - Leçons 10-19Dans les deux tutoriels précédent nous avons séparer le code en plusieurs classes. En particulier nous avons introduit la classe PlayerController, qui permet de prendre en charge la gestion des évènements claviers pour déplacer le joueur. Aujourd'hui nous allons ajouter la possibilité d'utiliser un joystick.
Préparation
Pour utilisé un joystick il nous faut un joystick. Et ici je vous propose d'utilisé le seul produit de Microsoft que je respecte, le joystick de XBox 360, son seul défaut c'est sa croix. Je n'attend qu'une seule chose qu'une version avec câble du joystick de la XBox One sortent et soit compatible PC ! Et pour ceux qui comme moi préfère le pingouin, sachez que le contrôleur de la XBox360 est compatible avec la plupart des distributions Linux.
Code
Comme nous avons vu dans la leçon 11, notre classe PlayerController implémente l'interface KeyListener. Pour permettre la gestion des entrées de notre joystick il suffit d'ajouter l'implémentation de l'interface ControllerListener et définir les implémentations :
public class PlayerController implements KeyListener, ControllerListener {
// [..] gestion du clavier (leçon 11)
@Override
public void controllerLeftPressed(int controller) { }
@Override
public void controllerLeftReleased(int controller) { }
@Override
public void controllerRightPressed(int controller) { }
@Override
public void controllerRightReleased(int controller) { }
@Override
public void controllerUpPressed(int controller) { }
@Override
public void controllerUpReleased(int controller) { }
@Override
public void controllerDownPressed(int controller) { }
@Override
public void controllerDownReleased(int controller) { }
@Override
public void controllerButtonPressed(int controller, int button) { }
@Override
public void controllerButtonReleased(int controller, int button) { }
}
On comprend vite l'utilité de chaque méthode, il suffit de les implémenter pour notre besoin.
@Override
public void controllerLeftPressed(int controller) {
this.player.setDirection(1);
this.player.setMoving(true);
}
@Override
public void controllerLeftReleased(int controller) {
this.player.setMoving(false);
}
@Override
public void controllerRightPressed(int controller) {
this.player.setDirection(3);
this.player.setMoving(true);
}
@Override
public void controllerRightReleased(int controller) {
this.player.setMoving(false);
}
@Override
public void controllerUpPressed(int controller) {
this.player.setDirection(0);
this.player.setMoving(true);
}
@Override
public void controllerUpReleased(int controller) {
this.player.setMoving(false);
}
@Override
public void controllerDownPressed(int controller) {
this.player.setDirection(2);
this.player.setMoving(true);
}
@Override
public void controllerDownReleased(int controller) {
this.player.setMoving(false);
}
Notre contrôleur est prêt il suffit de le définir dans la méthode init() de la classe Game :
private PlayerController controller = new PlayerController(this.player);
@Override
public void init(GameContainer container) throws SlickException {
// initialisation carte, joueur et music, (cf leçon 7 & leçon 10)
container.getInput().addKeyListener(controller);
container.getInput().addControllerListener(controller);
}
Et normalement tous marche bien, sans jeux de mot.
Code :: Amélioration
Mais ce n'est pas l'idéal, quand on change de direction on arrête parfois le déplacement alors que ce n’était pas notre intention. C'est du au fait que l'ont ne décompose pas les entrée sur la croix. Par exemple si on appuie sur la touche haut, puis sur la droite puis on relâche la touche haut, le personnage s’arrête. Pour cela lors de la relâche d'une direction il faut s'assurer que c'est la direction actuelle avant de s'arrêter.
@Override
public void controllerLeftReleased(int controller) {
if (this.player.getDirection() == 1) {
this.player.setMoving(false);
}
}
@Override
public void controllerRightReleased(int controller) {
if (this.player.getDirection() == 3) {
this.player.setMoving(false);
}
}
@Override
public void controllerUpReleased(int controller) {
if (this.player.getDirection() == 0) {
this.player.setMoving(false);
}
}
@Override
public void controllerDownReleased(int controller) {
if (this.player.getDirection() == 2) {
this.player.setMoving(false);
}
}
Pour aller plus loin
Dans un prochain article nous verrons comment ajouter un contrôle analogique et se déplacer en diagonale.
Ressource.
- Repo git : GitHub