IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Gestion des axes d'un joystick et du clavier


Sujet :

SDL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Gestion des axes d'un joystick et du clavier
    Bonjour à tous,

    J'ai cherché partout sur internet et je n'ai pas trouvé de solution à mon problème:

    Je programme actuellement un petit jeu en 2D avec la SDLJava et Java.
    Jusqu'à peu de temps je n'utilisais que le clavier et cela marchait parfaitement de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    while(!finJeu){
        	animerEnvironnement();
        	animerPersonnages();
        	verifierTouches();
        	afficherEnvironnement(ecran);
        	ecran.flip();
    }
    Pour simplifier, je ne vous ai pas mis la gestion des frames et les choses inutiles.
    J'ai des objets Personnage qui contiennent entre autres choses 4 booléens pour les 4 directions : haut droite bas gauche.
    animerPersonnage() déplace les personnages en fonction de ces booléens.
    Dans verifierTouches() j'appelle la méthode SDLEvent.pollEvent(), je regarde ensuite le type d'evenement :
    SDL_KEYDOWN fera passer le booleen du personnage correspond a true et SDL_KEYUP à false;
    Cela marche bien meme avec plusieurs joueurs sur le meme clavier.

    J'ai voulu ensuite faire marche ma manette PS2 (avec adaptateur USB).
    Avec SDL_JOYBUTTONUP et SDL_JOYBUTTONDOWN, ça marche de la meme maniere qu'avec le clavier et il n'y a pas de soucis.
    Mais la jouabilité n'est pas top en utilisant le pad multidirectionnelles ou les boutons. Je suis donc passé aux manches (sur manette PS2 y'en a 2 d'ailleurs). Les choses se sont compliqués mais j'ai finalement réussi à en tirer un minimum en utilisant les fonctions getWhich, getAxis et getValue.
    Mais le problème est que le déplacement meme légèrement de l'axe génère plein d'évènement successif. Le déplacement de l'axe a droite génère plein d'évènement avec pour "Axis" 0 (0 est l'axe horizontal) et "Value" différentes valeurs allant progressivement de 0 à 37767 (échelle des valeurs de l'axe de la manette).
    Ce qui ralentit très nettement ma boucle puisque avant j'avais 1 evenement pour une pression de touche au clavier et là le nombre d'evenement pour un meme déplacement est multiplié par 10 avec l'axe du manche.
    Ce qui donne au final l'impression de trainer le personnage, on bouge le manche et avec un decallage d'1 seconde (+ ou -) il se deplace car la file d'evenement est gorgée de SDL_JOYAXISMOTION qui ne sont pas tous utiles.

    J'ai alors essayé de mettre la fonction verifierTouches() dans un thread java.
    Et le problème s'inverse : je n'ai plus de probleme de trainée du personnage car le thread traite en continu les events qui arrive (je n'ai testé qu'avec une seul manette sachant que mon jeu a vocation à être jouer par plusieurs joueurs sur le meme PC et pas tous sur le claviers bien sur, j'espere que ça ne laissera pas à désirer avec le nombre de manettes) mais je ne récupère plus les events clavier, seule la manette marche. Pourtant mon thread ne fait qu'appeler la méthode du programme principal mais apparement le pollEvent() n'a plus la main sur le clavier.

    D'une manière ou d'une autre, j'aimerais que les 2 marchent et du mieux possible. J'en ai marre de me prendre la tête.

    Si une âme charitable passe ici et lit tout ça , ça sera déjà pas mal, merci.

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Yoann45
    Je programme actuellement un petit jeu en 2D avec la SDLJava et Java.
    Et pourquoi pas !

    Jusqu'à peu de temps je n'utilisais que le clavier et cela marchait parfaitement de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    while(!finJeu){
        	animerEnvironnement();
        	animerPersonnages();
        	verifierTouches();
        	afficherEnvironnement(ecran);
        	ecran.flip();
    }
    Pourrait-on voir le code de verifierTouches ?

    Dans verifierTouches() j'appelle la méthode SDLEvent.pollEvent(), je regarde ensuite le type d'evenement :
    SDL_KEYDOWN fera passer le booleen du personnage correspond a true et SDL_KEYUP à false;
    Cela marche bien meme avec plusieurs joueurs sur le meme clavier.
    En effet, c'est une bonne solution.

    J'ai voulu ensuite faire marche ma manette PS2 (avec adaptateur USB).
    Avec SDL_JOYBUTTONUP et SDL_JOYBUTTONDOWN, ça marche de la meme maniere qu'avec le clavier et il n'y a pas de soucis.
    Mais la jouabilité n'est pas top en utilisant le pad multidirectionnelles ou les boutons. Je suis donc passé aux manches (sur manette PS2 y'en a 2 d'ailleurs). Les choses se sont compliqués mais j'ai finalement réussi à en tirer un minimum en utilisant les fonctions getWhich, getAxis et getValue.
    Mais le problème est que le déplacement meme légèrement de l'axe génère plein d'évènement successif. Le déplacement de l'axe a droite génère plein d'évènement avec pour "Axis" 0 (0 est l'axe horizontal) et "Value" différentes valeurs allant progressivement de 0 à 37767 (échelle des valeurs de l'axe de la manette).
    Ce qui ralentit très nettement ma boucle puisque avant j'avais 1 evenement pour une pression de touche au clavier et là le nombre d'evenement pour un meme déplacement est multiplié par 10 avec l'axe du manche.
    Ce qui donne au final l'impression de trainer le personnage, on bouge le manche et avec un decallage d'1 seconde (+ ou -) il se deplace car la file d'evenement est gorgée de SDL_JOYAXISMOTION qui ne sont pas tous utiles.
    Même s'il y a 10 messages, cela ne devrait pas ralentir autant ton programme. Le code de la boucle m'intéresse

    J'ai alors essayé de mettre la fonction verifierTouches() dans un thread java.
    Et le problème s'inverse : je n'ai plus de probleme de trainée du personnage car le thread traite en continu les events qui arrive (je n'ai testé qu'avec une seul manette sachant que mon jeu a vocation à être jouer par plusieurs joueurs sur le meme PC et pas tous sur le claviers bien sur, j'espere que ça ne laissera pas à désirer avec le nombre de manettes) mais je ne récupère plus les events clavier, seule la manette marche. Pourtant mon thread ne fait qu'appeler la méthode du programme principal mais apparement le pollEvent() n'a plus la main sur le clavier.
    Je pense que tu as un problème de codage. Il n'y a pas de raison direct pour que le programme ne donne plus les événements clavier au 2ème thread.

    D'une manière ou d'une autre, j'aimerais que les 2 marchent et du mieux possible. J'en ai marre de me prendre la tête.

    Si une âme charitable passe ici et lit tout ça , ça sera déjà pas mal, merci.
    C'est fait, pour résumer :

    - Un code minimal exposant le problème serait le mieux
    - Sinon juste le code de la vérification des touches.

    Jc

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Après d'autres tests, j'ai l'impression que le problème ne se pose plus en changeant ma boucle principale comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    while(!finJeu){
        	animerEnvironnement();
        	animerPersonnages();
    	SDLEvent e = SDLEvent.pollEvent();
    	while(e!=null){
    		if (e!=null) verifierTouches(e); /* verifierTouches prend desormais un paramètre. */
    		e = SDLEvent.pollEvent();
    	}    	
    /*verifierTouches();*/
        	afficherEnvironnement(ecran);
        	ecran.flip();
    }
    Voilà néanmoins ma fonction vérifierTouches() d'origine. Sinon pour la version avec Thread j'utilise un simple Thread de java avec pour fonction run() la meme fonction que verifierTouches(). Si le problème revient avec plus de periphériques d'entrée, je repasserait. Merci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    public void verifierTouches(){
        		SDLEvent e = null;
    	    	try{
    	    		e = SDLEvent.pollEvent();
    	    	}catch(Exception ee){
    	    		System.out.println(ee);
    	    	}
    		if (e!=null){
    			if (e.getType()==SDLEvent.SDL_KEYDOWN){
    				SDLKeyboardEvent e2 = (SDLKeyboardEvent)e;
    				String s = e.getKeyName(e2.getSym());				
    				if (lesTouchesJoueur1.containsValue(s)) {
    					if (lesTouchesJoueur1.get("UP").equals(s)) persoJoueur1.action("GO","UP");
    					if (lesTouchesJoueur1.get("RIGHT").equals(s)) persoJoueur1.action("GO","RIGHT");
    					if (lesTouchesJoueur1.get("DOWN").equals(s)) persoJoueur1.action("GO","DOWN");
    					if (lesTouchesJoueur1.get("LEFT").equals(s)) persoJoueur1.action("GO","LEFT");
    				}
    			}
    			if (e.getType()==SDLEvent.SDL_JOYBUTTONDOWN){
    				SDLJoyButtonEvent e2 = (SDLJoyButtonEvent)e;
    		    		if (e2.getWhich()==0) {
    					if (e2.getButton()==0) persoJoueur1.action("GO","UP");
    					if (e2.getButton()==1) persoJoueur1.action("GO","RIGHT");
    					if (e2.getButton()==2) persoJoueur1.action("GO","DOWN");
    					if (e2.getButton()==3) persoJoueur1.action("GO","LEFT");
    				}
    			}
    			if (e.getType()==SDLEvent.SDL_KEYUP){
    				SDLKeyboardEvent e2 = (SDLKeyboardEvent)e;
    		    		String s = e.getKeyName(e2.getSym());
    				if (lesTouchesJoueur1.containsValue(s)) {
    					if (lesTouchesJoueur1.get("UP").equals(s)) persoJoueur1.action("STOP","UP");
    					if (lesTouchesJoueur1.get("RIGHT").equals(s)) persoJoueur1.action("STOP","RIGHT");
    					if (lesTouchesJoueur1.get("DOWN").equals(s)) persoJoueur1.action("STOP","DOWN");
    					if (lesTouchesJoueur1.get("LEFT").equals(s)) persoJoueur1.action("STOP","LEFT");
    				}
    			}
    			if (e.getType()==SDLEvent.SDL_JOYBUTTONUP){
    				SDLJoyButtonEvent e2 = (SDLJoyButtonEvent)e;
    				if (e2.getWhich()==0) {
    					if (e2.getButton()==9) finJeu=true;
    					if (e2.getButton()==0) persoJoueur1.action("STOP","UP");
    					if (e2.getButton()==1) persoJoueur1.action("STOP","RIGHT");
    					if (e2.getButton()==2) persoJoueur1.action("STOP","DOWN");
    					if (e2.getButton()==3) persoJoueur1.action("STOP","LEFT");
    				}
    			}
    			if (e.getType()==SDLEvent.SDL_JOYAXISMOTION){
    				SDLJoyAxisEvent e2 = (SDLJoyAxisEvent)e;
    				if (e2.getWhich()==0) {
    					if (e2.getAxis() == 1 && e2.getValue() > -5000) persoJoueur1.action("STOP","UP");
    					if (e2.getAxis() == 0 && e2.getValue() < 5000) persoJoueur1.action("STOP","RIGHT");
    					if (e2.getAxis() == 1 && e2.getValue() < 5000) persoJoueur1.action("STOP","DOWN");
    					if (e2.getAxis() == 0 && e2.getValue() > -5000) persoJoueur1.action("STOP","LEFT");
    					if (!persoJoueur1.isMoving("UP")) if (e2.getAxis() == 1 && e2.getValue() < -5000) persoJoueur1.action("GO","UP");
    					if (!persoJoueur1.isMoving("RIGHT")) if (e2.getAxis() == 0 && e2.getValue() > 5000) persoJoueur1.action("GO","RIGHT");
    					if (!persoJoueur1.isMoving("DOWN")) if (e2.getAxis() == 1 && e2.getValue() > 5000) persoJoueur1.action("GO","DOWN");
    					if (!persoJoueur1.isMoving("LEFT")) if (e2.getAxis() == 0 && e2.getValue() < -5000) persoJoueur1.action("GO","LEFT");
    				}
    			}	
    		}    	
        }

  4. #4
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Euh, le est-il vraiment utile étant donné que tu rentres dans ton while uniquement si e != null... ?
    Mindiell
    "Souvent, femme barrit" - Elephant man

Discussions similaires

  1. [JpGraph] Graphe double - Gestion des axes
    Par bm dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 18/07/2014, 09h30
  2. Problème gestion des handles axes
    Par sjunod dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 13/07/2010, 13h42
  3. [JFreeChart] Gestion données axe des ordonnées
    Par franfr57 dans le forum 2D
    Réponses: 1
    Dernier message: 11/07/2008, 14h30
  4. gestion des légendes des axes avec imagesc
    Par patrick7413 dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 10/07/2008, 19h48
  5. [débutant] gestion des axes d'un graphique
    Par 20100. dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 28/01/2008, 23h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo