Entrée
commune pour les deux plateformes :
---> Introduction
---> Interaction utilisateur avec
Android/desktop
---> Texte
---> Clavier
---> Souris/tactile
---> Conclusion
Introduction
En voilà arrivé à ce stade, on va voir dans ce
tutoriel l’interaction de l’utilisateur avec l’app/jeu, sachant qu’on travaille
sur deux plateformes Android et Desktop, on va voir dans cette première partie la manipulation des entrées disponibles sous les deux plateformes et
comment Libgdx gère les différences entre ces deux-là, vous allez voir c’est
magnifique !! (Si c’est votre premier contact avec Libgdx veuillez voir ces
tutoriels ).
Interaction
utilisateur avec Android/desktop
Les utilisateurs de votre application/jeu que
vous allez développer vont surement interagir avec, et cela via des
périphériques, la gestion des interactions des utilisateurs va s'effectuer dans un seul code source bien qu'on travaille sur deux plateformes
différentes, donc le rôle de Libgdx est de gérer les différences entre les deux et ceci grâce à l’un des
modules qu’elle possède (voir modules Libgdx ici) et parmi ces différences :
Sous Desktop, on utilise la souris et
sous Android c’est le toucher tactile, donc sous Android il n’y a pas la
détection de mouvement de souris, seulement le glissement de la souris est
repérable. On plus sous Android on peut gérer le multi-touch (plusieurs
doigts à la foi) ce qui n’est pas possible sous Desktop puisque la souris
possède un seul curseur.
Sachant aussi que Libgdx ne fait pas de
différence entre les boutons de la souris, seul un bouton est considéré.
Concernant le clavier, c’est clair que pour le
desktop il est considéré, mais sous Android plusieurs appareils n’adoptent pas
le clavier. Pour gérer ça, Libgdx propose de manipuler un ensemble de touche
clavier unique pour toutes les appareils.
Sachant aussi que sous Android il existe un
ensemble de touches qui n’existent pas sous l’environnement Desktop tels
que : touche de retour, de menu, de recherche…
Bien sûr il y a plein d’autres différences que
Libgdx les gères en un code unifié valable pour les deux plateformes. En verra
plus de détail dans ce qui suit.
Entrer du texte
On va commencer par le plus simple, entrer du
texte sur une application sous Android ou Desktop.
La procédure de saisissement du texte
s’effectuera à travers une boite de dialogue.
Sous Desktop : Une boite de dialogue de type Swing sera ouverte.
Sous Android : Une boite de dialogue Standard sera ouverte.
Cela n’est possible que si on implémente
l’interface TextInputListener qui lui, possède deux méthodes :
Input() : Cette méthode est appelée lorsque
l’utilisateur aura entré une chaine de caractère et appuyé sur OK
Canceled() : Cette méthode est appelée lorsque
l’utilisateur aura fermé la boite de dialogue (sous Desktop) ou appuyé sur le
bouton retour (sous Android).
* Voici à quoi ça ressemble en code source :
public class AuditeurTexte implements TextInputListener {
@Override
public void input (String text) {
}
@Override
public void canceled () {
}
}
* Maintenant pour faire apparaitre la boite de
dialogue il faut d’abord instancier la classe AuditeurTexte
AuditeurTexte ecouteur = new
AuditeurTexte();
Puis, l’indiquer à Libgdx :
Gdx.input.getTextInput(ecouteur, "Titre de la boite", "valeur texte
initial");
Pour récapituler un peu les choses je vais vous présenter un code
source d’une petite application qui vous demande de saisir du texte puis vous
affiche un message.
Le code source est décomposé en 3 parties comme nous l’avons déjà
expliqué dans un tutoriel précédant.
* La partie logique contiendra :
package my.works.TutorielBlog;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.TextInputListener;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import
com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class ManipulationEntree implements ApplicationListener {
private SpriteBatch batch ;
private BitmapFont font ;
private String texteInitial;
private String titreBoiteDialogue;
private String message;
private boolean afficher;
@Override
public void create() {
texteInitial = "Entrer votre nom complet";
titreBoiteDialogue = "Bienvenu";
afficher = false;
batch = new SpriteBatch();
font = new BitmapFont();
Gdx.input.getTextInput(new TextInputListener() {
@Override
public void input(String texteSaisi) {
message = "Bonjour Monsieur <"+texteSaisi+"> Bienvenu au
monde des developpeurs";
afficher =true;
}
@Override
public void canceled() {
message = "Au revoir Monsieur et
tant pis pour vous";
afficher =true;
}
}, titreBoiteDialogue, texteInitial);
}
@Override
public void dispose() {
}
@Override
public void pause() {
}
@Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
if(afficher)
{
batch.begin();
font.draw(batch, message, 10, 200);
batch.end();
}
}
@Override
public void resize(int arg0, int arg1) {
}
@Override
public void resume() {
}
}
* La partie Desktop : elle contient le code lanceur de
l’application sous Desktop
package my.works.TutorielBlog;
import com.badlogic.gdx.backends.jogl.JoglApplication;
public class Lanceur {
public static void main(String[] args) {
new JoglApplication (new ManipulationEntree(),"La manipulation des entrées",480,320,false);
}
}
* La partie Android : elle contient le code lanceur de
l’application sous Android
package my.works.LibgdxTutorielAndroid;
import my.works.TutorielBlog.ManipulationEntree;
import com.badlogic.gdx.backends.android.AndroidApplication;
import android.os.Bundle;
public class main extends AndroidApplication {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
initialize(new ManipulationEntree(), false);
}
}
La partie logique se trouve dans le projet desktop avec le lanceur
de l’application, contrairement au lanceur Android qui se trouve dans un projet
appart. Nous avons déjà parlé de ça en détail dans un tutoriel précédant.
* Voici le résultat sur desktop :
Si vous appuyez sur OK :
Si vous appuyez sur Annuler :
* Maintenant voici le résultat sous Android :
Remarque : cette application n’est fonctionnelle que sur le mode
paysage contentez-vous de ça pour l’instant. Pour rendre l’émulateur sous le
mode paysage (car par défaut il est en mode portrait), il faut
faire :
Ctrl (qui se trouve à gauche) + F11
KEYPAD_7 : appuyer sur le numéro 7 tout en
assurant que la lampe des numéros est éteinte.
Si j’entre mon nom et j’appuie sur OK :
Si j’appuie sur la touche Retour :
Entrées avec Clavier
Comme nous l’avons dit un peu plus haut Libgdx
tente de réduire la différence entre les deux plateformes. Elle est
caractérisée par l’utilisation de ces deux mécanismes le polling (l’attente
active) et la gestion des évènements.
Le polling(l’attente active) :
Un évènement clavier déclenché par un utilisateur
(en appuyant ou en relâchant une touche du clavier) génère un code qui
identifie la clé (touche) concernée.
Android et Desktop ne possède pas les mêmes code
pour les touches du clavier, pour cela Libgdx offre sa propre table de code des
touches clavier, voir la classe Keys
de Libgdx. Le mécanisme de polling ou de l’attente active consiste à vérifier de
façon répété si une touche a été entrée. Le polling est un moyen rapide et
facile pour traiter les entrées des utilisateurs.
* Voici comment interroger une touche du
clavier :
boolean isAPressed = Gdx.input.isKeyPressed(Keys.A);
Gestion des évènements :
La table
de code toute seule, ne suffit pas pour gérer les touches appuyées
simultanément. Par exemple : pour écrire en majuscule il faut
appuyer sur le shift et la touche du caractère. Pour cela un écouteur
d’évènement est branché et qui non seulement détecte le code de la touche
appuyée/relâchée mais aussi son caractère qui va avec. C’est le mécanisme de
gestion des évènements, il permet d’avoir plus d’information sur une entrée
utilisateur.
* Pour la gestion des évènements il faut
implémenter l’interface InputProcessor et redéfinir toutes ses méthodes.
public class ProcesseurDentree implements InputProcessor {
//****** Les trois méthodes
de la gestion des évènements reliés au clavier *******//
@Override
public boolean keyDown(int codeCle) {
return false;
}
@Override
public boolean keyTyped(char caractere) {
return false;
}
@Override
public boolean keyUp(int codeCle) {
return false;
}
//**********************************************************************************//
//*** Méthodes qui assurent
la Gestion des évènements souris/écran tactile ***//
//on va les voir juste
après les évènements claviers
@Override
public boolean scrolled(int arg0) {
return false;
}
@Override
public boolean touchDown(int arg0, int arg1, int arg2, int arg3) {
return false;
}
@Override
public boolean touchDragged(int arg0, int arg1, int arg2) {
return false;
}
@Override
public boolean touchMoved(int arg0, int arg1) {
return false;
}
@Override
public boolean touchUp(int arg0, int arg1, int arg2, int arg3) {
return false;
}
}
On va s’intéresser aux trois premières
méthodes liées au clavier, on va voir les autres dans la partie Souris/tactile qui
vient juste après.
Ces trois premières méthodes permettent
d’écouter des évènements clavier.
- keyDown () : Appelé quand une touche a été appuyé, prend en paramètre le code de la clé appuyée.
- keyUp () : Appelé quand une touche a été relâché, prend en paramètre le code de la clé relâchée.
- keyTyped () : Appelée quand un caractère Unicode a été généré par une entrée du clavier, prend en paramètre le caractère généré.
* Une fois l’interface implémentée
et ces méthodes définies, on doit instancier la classe implémentant cette
interface, et l’indiquer à Libgdx :
ProcesseurDentree
monProcesseurEntree = new ProcesseurDentree ();
Gdx.input.setInputProcessor(monProcesseurEntree);
Une fois l’objet indiqué à Libgdx, chaque
évènement pourra être détecté.
Pour récapituler la gestion des évènements
clavier voici un code source d’une petite application, qui vous demande
d’insérer n’importe quel caractère, et une fois le caractère inséré elle l’affiche
ainsi que tous les codes des clés
générées.
Le code source est décomposé en 3 parties comme nous l’avons déjà
expliqué dans un tutoriel précédant.
* La partie logique contiendra :
ppackage my.works.TutorielBlog;
import java.util.Iterator;
import java.util.Stack;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import
com.badlogic.gdx.graphics.g2d.SpriteBatch;
import
com.badlogic.gdx.InputProcessor;
public class ManipulationEntree implements ApplicationListener {
private SpriteBatch batch ;
private BitmapFont fontmessage1 ;
private BitmapFont fontmessage2 ;
private BitmapFont fontcaractere ;
private BitmapFont fontCode1 ;
private BitmapFont fontCode2 ;
private String message1;
private String message2;
private String caractereAffiche;
private String codeCle1;
private String codeCle2;
private Stack<Integer> pile;
private boolean afficherCode1,afficherCode2;
@Override
public void create() {
// Initialisation des
données
batch = new SpriteBatch();
fontmessage1 = new BitmapFont(); // Image contient: police
du 1er msg
fontmessage2 = new BitmapFont(); // Image contient: police
du 2eme msg
fontcaractere = new BitmapFont(); // Image contient: police
du caractère
fontCode1 = new BitmapFont(); // Image contient: police
du code généré
fontCode2 = new BitmapFont(); // Image contient: police
du code généré
message1 = "Entrez un caratere SVP"; // 1er message
message2 = "Codes des cles apuyees"; // 2eme message
caractereAffiche = "---";
pile = new Stack<Integer>();//Une pile pour gérer l'action appuyer/relâcher
afficherCode1 = false; // Permettre
l'affichage code 1
afficherCode2 = false; // Permettre
l'affichage code 2
}
@Override
public void dispose() {
}
@Override
public void pause() {
}
@Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Gdx.input.setInputProcessor(new InputProcessor() {
//*** Méthodes assurent la
Gestion des évènements pour souris/écran tactile **//
//********** Voir la partie
souris/écran du tutoriel **********//
@Override
public boolean touchUp(int a, int arg1, int arg2, int arg3) {
return false;
}
@Override
public boolean touchMoved(int arg0, int arg1) {
return false;
}
@Override
public boolean touchDragged(int arg0, int arg1, int arg2) {
return false;
}
@Override
public boolean touchDown(int arg0, int arg1, int arg2, int arg3) {
return false;
}
@Override
public boolean scrolled(int arg0) {
return false;
}
//*********************************************************************************//
//****** Les trois méthodes
de la gestion des évènements reliés au clavier *******//
// Appelée à chaque fois qu'on relâche une clé du
clavier
@Override
public boolean keyUp(int codeCle) {
System.out.println("chekpnt "+pile.size());
if(pile.size() >= 2) // le contenu de la pile
> 2 éléments i.e.
{ //
deux touches sont maintenues simultanément
afficherCode2 = true;
codeCle2=Integer.toString(codeCle);
// Récupérer le code
} // de la clé appuyée en String
else
{
afficherCode1 =true ;
codeCle1=Integer.toString(codeCle);
// Récupérer le code
} // de la clé appuyée en String
pile.pop(); // Dépiler
return false;
}
@Override
// Appelée à chaque fois
qu'un caractère est généré
public boolean keyTyped(char caractere) {
caractereAffiche =Character.toString(caractere); //récupérer le caractère
//et le convertir en String
return false;
}
// Appelée à chaque fois
qu'on appuie sur une clé du clavier
// Si on maintient une clé,
cette méthode sera appelé en permanence
@Override
public boolean keyDown(int codeCle) {
if(pile.empty()) // re-initialise à chaque fois que la pile se vide
{ // une
pile vide signifie qu'aucune touche n'est
// appuyée
afficherCode1=false;
afficherCode2=false;
}
if(!pile.contains(codeCle)) // cette condition gérer le
cas
// d'une touche enfoncée
pile.push(codeCle); // empiler
return false;
}
});
batch.begin();
fontmessage1.draw(batch, message1, 10, 300); // dessiner 1er msg
fontmessage2.draw(batch, message2, 10, 200);
// dessiner 1er msg
fontcaractere.draw(batch, caractereAffiche, 10, 150); // dessiner caractère généré
if(afficherCode1)
fontCode1.draw(batch,codeCle1, 200, 200);
// afficher code de la 1er
clé appuyée
if(afficherCode2)
fontCode2.draw(batch,codeCle2, 200 + 30, 200); // afficher code de la 2eme
clé appuyée
batch.end();
}
@Override
public void resize(int arg0, int arg1) {
}
@Override
public void resume() {
}
}
* La partie Desktop : elle contient le code lanceur de
l’application sous Desktop
package my.works.TutorielBlog;
import
com.badlogic.gdx.backends.jogl.JoglApplication;
public class Lanceur {
public static void main(String[] args) {
new JoglApplication (new ManipulationEntree(),"La manipulation des entrées",480,320,false);
}
}
* La partie Android : elle contient le code lanceur de
l’application sous Android
package my.works.LibgdxTutorielAndroid;
import my.works.TutorielBlog.ManipulationEntree;
import com.badlogic.gdx.backends.android.AndroidApplication;
import android.os.Bundle;
public class main extends AndroidApplication {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
initialize(new ManipulationEntree(), false);
}
}
La partie logique se trouve dans le projet desktop avec le lanceur
de l’application, contrairement au lanceur Android qui se trouve dans un projet
appart. Nous avons déjà parlé de ça en détail dans un tutoriel précédant.
* Voici le résultat sous desktop :
Si je tape h minuscule :
Si je veux écrire C (majuscule) :
Le code de la clé shift = 59 et de la clé c = 31
* Maintenant le résultat sous Android (sous
l’émulateur) :
Remarque : cette application n’est fonctionnelle que sur le mode
paysage contentez-vous de ça pour l’instant. Pour rendre l’émulateur sous le
mode paysage (car par défaut il est en mode portrait), il faut
faire :
Ctrl (qui se trouve à gauche) + F11
KEYPAD_7 : appuyer sur le numéro 7 tout en
assurant que la lampe des numéros est éteinte.
On appuie sur la lettre h et obtient :
Par exemple si j’appuie sur le bouton menu :
Entrées avec
Souris/Ecran tactile
On a cité un peu plus haut quelques différences
entre les deux plateformes au niveau de la souris (pour Desktop) et le toucher
tactile (pour Android). Pour réduire l’écart entre Android et Desktop Libgdx
utilise les mêmes mécanismes vus pour le clavier : le polling (ou
l’attente active) et la gestion des évènements.
le polling (l’attente active) :
Le polling sous Libgdx fournis un ensemble de
méthodes qui permettent de vérifier l’état actuel du périphérique
d’entrée par exemple si l’écran est
touché par un ou plusieurs doigts concernant Android ou si on a effectué un
clic avec la souris concernant Desktop.
Mécanisme de polling ou de l’attente active
consiste à vérifier de façon répété si une entrée avec Souris/Ecran
tactile a été effectuée. Le polling est un moyen rapide et facile pour
traiter les entrées des utilisateurs.
* Voici comment vérifier si un ou plusieurs
doigts est sur l’écran tactile (Sous Android).
boolean estTouche = Gdx.input.isTouched();
Sous Desktop : estTouche est à vrai si on clique sur l’écran.
* Pour obtenir les coordonnées d’un clic avec
la souris / doigt sur l’écran :
float X = Gdx.input.getX();
float Y = Gdx.input.getY();
* On peut aussi obtenir la distance qui sépare
un premier clic et un deuxième :
float deltaX = Gdx.input.getDeltaX();
float deltaY = Gdx.input.getDeltaY();
* Maintenant pour gérer le multi-touch
sous Android
boolean premierDoigt = Gdx.input.isTouched(0);
boolean deuxiemeDoigt = Gdx.input.isTouched(1);
boolean troisiemeDoigt = Gdx.input.isTouched(2);
C’est évident que le toucher multiple n’est
considéré que par Android, Libgdx gère cela par l’attribution d’un pointeur à
chaque doigt qui touche l’écran tactile i.e. si un doigt touche l’écran tactile
il obtient le plus petit indice disponible parmi [ 0, 1, 2 ]. Un l’indice se libère
quand le doigt qu’il le point se lève de l’écran. Voici comment se passent les
choses :
Premier doigt touche l’écran ----> il obtient l’indice
0
Deuxième doigt touche l’écran ----> il obtient l’indice
1
Troisième doigt touche l’écran ----> il obtient l’indice
2
Troisième doigt quitte (se lève de) l’écran
----> l’indice 2 se libère.
Deuxième doigt quitte (se lève de) l’écran
----> l’indice 1 se libère.
Un nouveau doigt touche l’écran ----> il obtient l’indice 1 (Le plus
petit indice libre).
* Pour savoir si l’écran a été toucher puis
relâché par l’un des trois doigts :
boolean touche = Gdx.input.justTouched();
* Pour obtenir les coordonnées des doigts posés
sur l’écran
int premierDoigtX = Gdx.input.getX();
int premierDoigtY = Gdx.input.getY();
int deuxiemeDoigtX = Gdx.input.getX(1);
int deuxiemeDoigtY = Gdx.input.getY(1);
int troisiemeDoigtX = Gdx.input.getX(2);
int troisiemeDoigtY = Gdx.input.getY(2);
Vous avez surement remarquez que par défaut l’indice
de pointeur est 0, c’est l’indice qui pointe la souris sous Desktop.
* On peut aussi obtenir la distance qui sépare
la première position d’un doigt et une deuxième
float premierDoigtDeltaX
= Gdx.input.getDeltaX();
float premierDoigtDeltaY
= Gdx.input.getDeltaY();
float deuxiemeDoigtDeltaX
= Gdx.input.getDeltaX(1);
float deuxiemeDoigtDeltaY
= Gdx.input.getDeltaY(1);
float troisiemeDoigtDeltaX =
Gdx.input.getDeltaX(2);
float troisiemeDoigtDeltaY = Gdx.input.getDeltaY(2);
* Pour savoir quelle est le bouton de la souris
que l’utilisateur vient de cliquer :
boolean boutonGauche = Gdx.input.isButtonPressed(Input.Buttons.LEFT);
boolean boutonDroit = Gdx.input.isButtonPressed(Input.Buttons.RIGHT);
boolean boutonMilieu = Gdx.input.isButtonPressed(Input.Buttons.MIDDLE);
Gestion des évènements :
Le mécanisme de gestion des évènements permet
d’avoir plus d’information sur une entrée utilisateur. Il fournit un moyen de
mettre en œuvre des interactions avec l’interface utilisateur qui sont
difficiles de mettre en œuvre en utilisant seulement le polling.
* Pour la gestion des évènements il faut
implémenter l’interface InputProcessor et redéfinir toutes ses méthodes.
public class ProcesseurDentree implements InputProcessor {
//****** Les trois méthodes
de la gestion des évènements reliés au clavier *******//
//
Vu précédemment
@Override
public boolean keyDown(int codeCle) {
return false;
}
@Override
public boolean keyTyped(char caractere) {
return false;
}
@Override
public boolean keyUp(int codeCle) {
return false;
}
//**********************************************************************************//
//*** Méthodes qui assurent
la Gestion des évènements pour souris/écran tactile **//
@Override
public boolean scrolled(int arg0) {
return false;
}
@Override
public boolean touchDown(int arg0, int arg1, int arg2, int arg3) {
return false;
}
@Override
public boolean touchDragged(int arg0, int arg1, int arg2) {
return false;
}
@Override
public boolean touchMoved(int arg0, int arg1) {
return false;
}
@Override
public boolean touchUp(int arg0, int arg1, int arg2, int arg3) {
return false;
}
}
Voici les méthodes assurant la
gestion des évènements souris/écran tactile
- TouchDown () : Appelée quand un doigt se pose sur l'écran (Android) / un bouton la souris a été pressé (desktop). Elle nous informe sur les coordonnées ainsi que l'indice de pointeur et le bouton de la souris. Sachant que pour Android seul le bouton droit est considéré.
- touchUp(): Appelée quand un doigt a été levée de l'écran( Android) / un bouton de la souris a été relâché (Desktop). Elle nous informe sur les coordonnées, l'indice de pointeur(Android) et le bouton de la souris(Desktop)
- touchDragged () : Appelée quand un doigt glisse sur l'écran tactile (Android) / déplacer la souris tout en pressant sur un bouton de la souris (Desktop). Nous informe les coordonnées et l'indice de pointeur, mais pour savoir quel est le bouton de la souris concerné il faut utiliser le polling.
- touchMoved () : appelée lorsque la souris est déplacée sur l'écran sans que l’un de ses boutons soit cliqué. Cette méthode n’est appelée que sur l’environnement Desktop, elle ne sera jamais appelée en Android car l’écran tactile ne possède pas de curseur comme est le cas de la souris.
- scrolled () : appelée lorsque la roulette de la souris est tournée. Nous informe sur le sens qu’est tournée la roulette de la souris. Elle n’est jamais appelée sous Android.
* Une fois l’interface implémentée
et ces méthodes définies, on doit instancier la classe implémentant cette
interface, et l’indiquer à Libgdx.
ProcesseurDentree
monProcesseurEntree = new ProcesseurDentree ();
Gdx.input.setInputProcessor(monProcesseurEntree);
Une fois l’objet indiqué à Libgdx chaque
évènement pourra être détecté.
Pour récapituler un peu les choses je vous
propose ce code source qui implémente une petite application qui vous permettra
de voir encore plus le fonctionnement des gestions des évènements et du polling.
Le code source est décomposé en 3 parties comme nous l’avons déjà
expliqué dans un tutoriel précédant.
* La partie logique contiendra :
package my.works.TutorielBlog;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.InputProcessor;
import
com.badlogic.gdx.graphics.Color;
import
com.badlogic.gdx.graphics.GL10;
import
com.badlogic.gdx.graphics.g2d.BitmapFont;
import
com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class ManipulationEntree implements ApplicationListener {
public static int longueur = 320;
public static int largeur = 480 ;
public static int deltaTemps = 3;
private SpriteBatch batch;
private BitmapFont fontTexte ;
private BitmapFont fontCadre ;
private String message1;
private String message2;
private String message3;
private String message4;
private String msgActionDesktop;
private String msgActionAndroid;
private String coordonneesDesktop;
private String coordonneesAndroid;
private String android ;
private String desktop ;
private String cadre1;
private String cadre2;
private float tempsEcouler ;
private boolean afficheMsg ;
private boolean afficheContenu ;
@Override
public void create() {
batch = new SpriteBatch();
fontTexte= new BitmapFont();
fontCadre= new BitmapFont();
message1 ="Ceci est une
application qui vous aidra a mieux voir";
message2 ="la gestion des
evenements de la souris sous Desktop";
message3 ="et ecran tactile sous
Android.";
message4 ="cliquer/toucher
l'ecran pour commencer !";
msgActionDesktop = "Action : -----";
msgActionAndroid = "Action : -----";
afficheContenu = false ;
afficheMsg = true;
android = "Plateforme
Android";
desktop = "Plateforme
Desktop";
cadre1 = "|";
cadre2 = "_";
}
@Override
public void dispose() {
}
@Override
public void pause() {
}
//**************** Méthode
qui dessine le cadre ************************//
public void dessinerCadre()
{
int distance = 0;
for(int i =0 ; i <= 18 ; i++)
{
fontCadre.setColor(Color.GREEN);
fontCadre.draw(batch, cadre1, largeur /2 , distance);
distance +=20 ;
}
distance = 0;
for(int i = 0; i<= 25 ; i++)
{
fontCadre.setColor(Color.GREEN);
fontCadre.draw(batch, cadre2, distance , longueur - 50);
distance +=20 ;
}
}
//***********************************************************************//
@Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Gdx.input.setInputProcessor(new InputProcessor() {
@Override
public boolean touchUp(int x, int y, int pointeur, int bouton) {
tempsEcouler = 0 ; // Initialiser le temps
depuis
// la dernier entrée
if(bouton == Buttons.LEFT)
msgActionDesktop = "relache bouton G";
if(bouton == Buttons.RIGHT)
msgActionDesktop = "relache bouton D";
if(bouton == Buttons.MIDDLE)
msgActionDesktop = "relache bouton M";
if(pointeur == 0)
msgActionAndroid = "premier doigt
leve";
if(pointeur == 1)
msgActionAndroid = "deuxieme doigt leve";
if(pointeur == 2)
msgActionAndroid = "troisieme doigt leve";
// Recuperer coordonnées et les convertir en String
coordonneesDesktop ="x="+ Integer.toString(x) +" y="+ Integer.toString(y);
coordonneesAndroid ="x="+ Integer.toString(x) +" y="+ Integer.toString(y);
coordonneesAndroid = "coordonnees : "+coordonneesAndroid ;
coordonneesDesktop = "coordonnees : "+coordonneesDesktop;
return false;
}
@Override
public boolean touchMoved(int x, int y) {
// Cette méthode n'est jamais appelée sous Android
tempsEcouler = 0 ;
msgActionDesktop = "Action : mouvement du curseur";
// Récupérer les coordonnées et les convertir en
String
coordonneesDesktop ="x="+ Integer.toString(x) +" y="+ Integer.toString(y);
coordonneesDesktop = "coordonnees : "+coordonneesDesktop;
return false;
}
@Override
public boolean touchDragged(int x, int y, int pointeur) {
tempsEcouler = 0 ; // Initialiser le temps depuis
// la dernier entree
// Cette méthode ne nous informe pas sur le bouton de
// la souris il faut utiliser le polling
if(Gdx.input.isButtonPressed(Buttons.LEFT))
msgActionDesktop = "Action : Glissement avec bouton G";
if(Gdx.input.isButtonPressed(Buttons.RIGHT))
msgActionDesktop = "Action : Glissement avec bouton D";
if(Gdx.input.isButtonPressed(Buttons.MIDDLE))
msgActionDesktop = "Action : Glissement avec bouton M";
if(pointeur == 0) // si c'est le premier doigt
msgActionAndroid = "Action : Glissement du 1er doigt";
if(pointeur == 1) // si c'est le deuxième doigt
msgActionAndroid = "Action : Glissement du 2eme doigt";
if(pointeur == 2) // si c'est le troisième doigt
msgActionAndroid = "Action : Glissement du 3eme doigt";
// Récupérer coordonnées et les convertir en String
coordonneesDesktop ="x="+ Integer.toString(x) +" y="+ Integer.toString(y);
coordonneesAndroid ="x="+ Integer.toString(x) +" y="+ Integer.toString(y);
coordonneesAndroid = "coordonnees : "+coordonneesAndroid ;
coordonneesDesktop = "coordonnees : "+coordonneesDesktop;
return false;
}
@Override
public boolean touchDown(int x, int y, int pointeur, int bouton) {
tempsEcouler = 0 ; // Initialiser le temps depuis
// la dernier entrée
// Cette méthode nous informe sur le bouton de la
souris
// Ce n’est pas la peine d'utiliser le polling
if(bouton ==Buttons.LEFT)
msgActionDesktop = "Action : clic bouton
gauche souris";
if(bouton ==Buttons.RIGHT)
msgActionDesktop = "Action : clic bouton
droit souris ";
if(bouton ==Buttons.MIDDLE)
msgActionDesktop = "Action : clic bouton
milieu souris";
// Pour distinguer quel doit a
effectué l'action
if(pointeur == 0)
msgActionAndroid = "premier doigt
pose";
if(pointeur == 1)
msgActionAndroid = "deuxieme doigt pose";
if(pointeur == 2)
msgActionAndroid = "troisieme doigt pose";
// Récupérer coordonnées et les convertir en String
coordonneesDesktop ="x="+ Integer.toString(x) +" y="+ Integer.toString(y);
coordonneesAndroid ="x="+ Integer.toString(x) +" y="+ Integer.toString(y);
coordonneesAndroid = "coordonnees : "+coordonneesAndroid ;
coordonneesDesktop = "coordonnees : "+coordonneesDesktop;
return false;
}
@Override
public boolean scrolled(int direction) {
if(direction == 1) // roule vers le bas
msgActionDesktop = "roulette vers bas";
if(direction == -1)// roule vers le haut
msgActionDesktop = "roulette vers haut";
return false;
}
//*********************Entrée
clavier********************************************//
// On est obligé de les redéfinir
puisqu’on a implémenté l’interface
@Override
public boolean keyUp(int arg0) {
return false;
}
@Override
public boolean keyTyped(char arg0) {
return false;
}
@Override
public boolean keyDown(int arg0) {
return false;
}
//*******************************************************************************//
});
if(Gdx.input.justTouched()) // si cliquer/toucher puis relâcher
{
afficheMsg = false; // Masquer la 1er page
afficheContenu = true; // Afficher la 2eme page
}
batch.begin();
if(afficheMsg) // 1ere page
{
fontTexte.draw(batch, message1, 80, 300); //insérer du texte
fontTexte.draw(batch, message2, 80, 280);
fontTexte.draw(batch, message3, 80, 260);
fontTexte.draw(batch, message4, 80, 240);
}
if(afficheContenu) // 2eme page
{
tempsEcouler += Gdx.graphics.getDeltaTime();
// Compter le temps depuis
la dernière entrée
if(tempsEcouler > deltaTemps) // Aucune entrée n'a été
{ // éffectuée durant un temps
// delta
msgActionDesktop = "Action : -----"; // aucune action
msgActionAndroid = "Action : -----"; // aucune action
coordonneesAndroid = " ";
coordonneesDesktop = " ";
}
dessinerCadre();
// Partie Android
// insertion titre + action +coordonnées
fontTexte.draw(batch,android, 50,longueur-25);
fontTexte.draw(batch,msgActionAndroid,10,longueur-70);
fontTexte.draw(batch,coordonneesAndroid,10, longueur-90);
// Parite Desktop
// insertion titre + action +coordonnées
fontTexte.draw(batch,desktop,largeur/2 +50,longueur-25);
fontTexte.draw(batch,msgActionDesktop,largeur/2 +10,longueur-70);
fontTexte.draw(batch,coordonneesDesktop,largeur/2+10,longueur-90);
}
batch.end();
}
@Override
public void resize(int arg0, int arg1) {
}
@Override
public void resume() {
}
}
* La partie Desktop : elle contient le code lanceur de
l’application sous Desktop
package my.works.TutorielBlog;
import
com.badlogic.gdx.backends.jogl.JoglApplication;
public class Lanceur {
public static void main(String[] args) {
new JoglApplication (new ManipulationEntree(),"La manipulation des entrées",480,320,false);
}
}
* La partie Android : elle contient le code lanceur de
l’application sous Android
package my.works.LibgdxTutorielAndroid;
import my.works.TutorielBlog.ManipulationEntree;
import com.badlogic.gdx.backends.android.AndroidApplication;
import android.os.Bundle;
public class main extends AndroidApplication {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
initialize(new ManipulationEntree(), false);
}
}
La partie logique se trouve dans le projet desktop avec le lanceur
de l’application, contrairement au lanceur Android qui se trouve dans un projet
appart. Nous avons déjà parlé de ça en détail dans un tutoriel précédant.
* Voici le résultat sur desktop :
Cliquer sur l’écran et vous
obtiendrai :
Glisser le curseur de votre souris sur
l’écran et vous obtiendrai :
Faite seulement bouger le curseur
de la souris et vous obtiendrai :
Bien sûr, il y en a d’autres actions
qui peuvent être détecté je vous laisse le soin de les tester
* Maintenant le résultat sous
Android (sous l’émulateur) :
Remarque : cette application n’est fonctionnelle que sur le mode
paysage contentez-vous de ça pour l’instant. Pour rendre l’émulateur sous le
mode paysage (car par défaut il est en mode portrait), il faut faire :
Ctrl (qui se trouve à gauche) + F11
KEYPAD_7 : appuyer sur le numéro 7 toute
en assurant que la lampe des numéros est éteinte.
On touche l’écran et obtient :
Si on fait une action, par exemple glisser un
doigt on aura :
Bien sûr, il y en a d’autres actions je vous
laisse le soin de les découvrir.
Conclusion
Nous avons vu dans ce tutoriel les
entrées disponibles pour les deux plateformes et que Libgdx doit les gérer en tenant compte des différences qui
existent entre eux. Dans un prochain tutoriel on va voir les entrées propre a
Android tel que acétomètre. Si vous avez des remarques ou des questions
n’hésitez pas à les poster en commentaire. Merci pour votre lecture.
Salut,
RépondreSupprimerTrès bien tes Tuto. Depuis six mois je passe pas mal de temps sur libgdx et c'est le premier site que je vois en français.
Tu récapitule bien ce qu'il faut savoir pour commencer, c'est propre et clair. Merci à toi.
En ce moment je suis sur la partie Box2D de libgdx. LibGdx est vraiment très bien.
à plus
Salut Kurlip,
RépondreSupprimerc'est vrai qu'on trouve pas de tuto de Libgdx sur le net ce qui m'a poussé a en faire un , et je suis au début du chemin.
Bonne continuation a toi aussi. en fait,tu a raison Libgdx est magnifique !
bonjour monsieur,
RépondreSupprimermerci pour ce tutoriel il m'a vraiment expliquer des grands concepts et j'aimerais bien que vous nous donnez des booking que vous avez essayez et que vous sont utiles.