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

AWT/Swing Java Discussion :

Problème de temps de latence avec KeyAdapter


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 16
    Par défaut Problème de temps de latence avec KeyAdapter
    Bonjour,

    j'essaye de faire déplacer un personnage sur une map de jeu, le soucis vient de la gesion du clavier.

    Lorsque j'appuie sur une de mes touches (haut, bas, gauche, droite), mon petit bonhomme se déplace bien selon le comportement que je lui ai attribué mais le déplacement sacade sur la deuxième image.

    Par exemple, si j'appuie sur "Bas", le personnage fait un pas vers le bas, puis il y a une demi-seconde d'arrêt, et ensuite tout se passe bien. De même pour chaque touche.

    Ce sont ces petits temps de latences après chaque appuie sur une touche que je n'explique pas... Mais surtout c'est très désagréable, ça empêche les déplacements d'être fluides.

    Quelqu'un a-t-il déjà eu ce type de problème ?
    Voila un extrait de mon code :

    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
    public void keyPressed(KeyEvent e)
    {
                switch(e.getKeyCode())
                {
                    case KeyEvent.VK_DOWN:
                        // Mon code pour la touche du bas
                        break;
     
                    case KeyEvent.VK_UP:
                        // Mon code pour la touche du haut
                        break;
     
                    // Code pour les autres touches
                }
                source.getGame().repaint();
    }

    Merci beaucoup !

  2. #2
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Ca doit être le temps d'exécuter "// Mon code pour la touche du bas", non?

  3. #3
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 16
    Par défaut
    Possible, je ne sais pas.
    Le code que j'execute est juste le démarrage d'une animation.

    Et surtout ce qui est bizarre, c'est que ça ne se produit qu'une seule fois par appuie de touche.

    C'est à dire si je maintiens la touche enfoncée, tout va bien se passer, le petit bonhomme va bien se déplacer et s'animer correctement, mais sur la première demi-seconde, il y aura un retard...

  4. #4
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Montre ton code exécuté

  5. #5
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 16
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    case KeyEvent.VK_DOWN:
                        source.getGame().getCharacter().walkDown(source.getGame().getMap());
                        source.getGame().getCharacter().enableDown(true);
                        break;

    Cette méthode dans une autre classe permet de tester les collisions, et de faire avancer notre bonhomme.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	public void walkDown(Map map)
    	{
    		// Test de collision avec le décors
    	    if (map.getGrille().canWalk(x, y+this.step))
    	    {
    	        y+=this.step;
    	    }
    	}
    La méthode enableDown permet d'executer ceci :

    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
     
    	public void run()
    	{
    	    try
    	    {
    	        while (true)
    	        {
    	            if (down)
    	            {
    	                this.animDown();
    	            }
    	            if (left)
    	            {
    	                this.animLeft();
    	            }
    	            if (up)
    	            {
    	                this.animUp();
    	            }
    	            if (right)
    	            {
    	                this.animRight();
    	            }
    	            sleep(100);
    	        }
    	    }
    	    catch(InterruptedException e)
    	    {
     
    	    }
    	}
    Ma classe Character est un Thread, ça permet de jouer les animations.

    Quand keyRelease s'execute, je fais un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    source.getGame().getCharacter().enableDown(false);
    pour stoper l'animation.

  6. #6
    Membre Expert Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Par défaut
    Citation Envoyé par marissa_mean
    Et surtout ce qui est bizarre, c'est que ça ne se produit qu'une seule fois par appuie de touche.

    C'est à dire si je maintiens la touche enfoncée, tout va bien se passer, le petit bonhomme va bien se déplacer et s'animer correctement, mais sur la première demi-seconde, il y aura un retard...
    Bonjour,
    ne serait-ce pas lié à l'"auto-repeat" ? Quand tu appuies sur une touche et que tu la maintiens enfoncée, il y a un délai initial ~ 1/2 s avant la prise en compte de la répétition. Sans ce délai, au lieu d'écrire 'a' par exemple, tu écrirais 'aa...' sans le vouloir.

  7. #7
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 16
    Par défaut
    Je n'y avais pas pensé !
    Oui ça m'a bien l'air d'être ce délai d'auto-repeat.

    Maintenant il ne reste plus qu'a trouver comment enlever ça.

    Merci beaucoup !

  8. #8
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Il faut écouter les évènements "key pressed" et "key released" (enfoncée, relâchée)...

  9. #9
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 16
    Par défaut
    Après avoir cherché un peu sur Internet, il semble que les évènements keyPressed et keyReleased sont envoyés par Windows, donc il n'y aura rien à faire pour éviter le délai de répétition de cette manière.

    Certains parlent de démarrer un Timer dans le KeyPressed et de l'arrêter dans le keyRelease mais je ne vois pas ce que ça va changer.

    Je pense que je vais tout simplement tenter une autre approche pour le déplacement de mon personnage.


    Si j'ai du résultat convenable je vous tiendrau au courant.

  10. #10
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 16
    Par défaut
    Mon problème est résolu, voici comment j'ai du procéder :

    Une classe Control (qui hérite de Thread et implémente KeyListener)
    Cette classe gère le déplacement du personnage sur la carte, c'est à dire ses coordonnées et les collisions avec le décors.

    Une classe Character (qui hérite de Thread)
    Cette classe gère l'animation du personnage et uniquement l'animation, c'est à dire les frames de déplacement.

    Pourquoi avoir utilisé deux Threads ?
    De cette façon je peux gérer indépendamment les deux taches, c'est à dire donner des cadences différentes au déplacement et à l'animation. Concrètement, ça se traduit par un sleep(100) dans l'animation et un sleep(30) dans le déplacement.

    Dans chaque méthode run() des classes, je teste si un booléen est vrai, auquel cas je lance l'animation et le déplacement. Les booléens sont activés/désactivés dans la classe Control dès qu'une touche est enfoncée/relachée.


    Merci à tous pour votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/05/2011, 11h28
  2. Réponses: 2
    Dernier message: 04/04/2011, 15h54
  3. Réponses: 4
    Dernier message: 09/06/2010, 17h44
  4. Réponses: 1
    Dernier message: 28/09/2009, 08h30
  5. Réponses: 0
    Dernier message: 04/08/2008, 17h05

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