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 :

KeyListener pour un jeu en Swing


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2011
    Messages : 8
    Par défaut KeyListener pour un jeu en Swing
    Bonsoir,

    Alors voilà je suis en train de réaliser un Bomberman en swing, tout fonctionne bien sauf pour une chose:

    Le gameplay !

    En effet, actuellement, le perso se déplace avec les touches directionnelles, ainsi je maintiens la touche enfoncé et pas de problèmes j'effectue le déplacement.

    Mais, pour poser une bombe, j'utilise la touche espace !

    Et là où c'est vraiment très pénible, c'est lorsque j'appuie sur cette touche alors que j'avais une touche directionnelle enfoncé en même temps, je suis contrains de relâcher ma touche directionnelle puis de la presser de nouveau pour pouvoir continuer mon déplacement.

    En fait la pile d'événements reste bloquée pour la touche de déplacement tant que je ne la relâche pas.

    Pour résumer: Si je me déplace dans une direction avec (VK_RIGHT ou VK_UP, etc...) en maintenant la touche enfoncé et que en même temps je pose une bombe avec VK_SPACE par exemple, les événements de la touche directionnelle pressée se stop.

    Y a t-il une solution ou bien la gestion des events clavier en awt/swing est t'elle aussi limité, ce qui voudrait dire au final qu'il n'est pas possible de développer un petit jeux 2d avec une gameplay un minimum potable en Java2D/Swing?

    Merci pour votre aide, parce que là je désespère

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Comment procèdes tu pour tes listener.

    Une façon simple pour les directions de faire est de setter un flag lors du keyPressed et de le remettre à false lors du keyReleased. Et donc d'ignorer les évènements se passant entre les deux en fait.


    Est-ce ce que tu fais?

  3. #3
    Membre Expert Avatar de Nico02
    Homme Profil pro
    Developpeur Java/JEE
    Inscrit en
    Février 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Developpeur Java/JEE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 728
    Par défaut
    Voici un petit bout de code que j'ai réalilser, il utilise l'idée de sinok.

    Chaque touche est associé à un boolean. Tu mets ce booléen à vrai dans le keyPressed() et a faux dans le keyReleased(). Ensuite moi j'utilise une fonction externe (correspondant à un taux de rafraîchissement) pour exécuter toutes les actions pour lesquels le booléen est à vrai.

    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 class KeyHandler implements KeyListener{
     
    /** Map permettant de gérer si une touche clavier est active ou non */
    	private Map<Integer,Boolean> isActiveKey;
     
     
    public void keyPressed(KeyEvent e) {
     
     
    	isActiveKey.put(e.getKeyCode(), true); 
     
    }
     
    public void keyReleased(KeyEvent e) {	
     
    	isActiveKey.put(e.getKeyCode(), false);
    }
     
    public void tick() {
    		Set<Integer> cle = isActiveKey.keySet();
    		Iterator<Integer> iter = cle.iterator(); 
    		while(iter.hasNext())
    		{
    			int c = (Integer) iter.next();
    			if(isActiveKey.get(c))
    				// <------------- Tu fais tes actions
    		}
    }
     
    }
    Ce code n'est pas complet et tu devras faire attention par exemple à la gestion de la concurrence (on ne peut pas aller à droite et à gauche en même temps par exemple), mais il devrait t'aider

    Bon courage

  4. #4
    Membre Expert Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Par défaut
    Pour compléter les précédentes réponses :
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
     
    public class KeyBoard extends JPanel implements KeyListener{
     
        private boolean left,right,up,down,space;
     
        public KeyBoard() {
     
            this.addKeyListener(this);
            this.setFocusable(true);
     
            this.left=false;
            this.right=false;
            this.up=false;
            this.down=false;
            this.space=false;
     
            Timer timer = new Timer(1000,new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    System.out.println(showState());
                }
            });
            timer.start();
        }
     
     
        public void keyTyped(KeyEvent e) {}
     
        public void keyPressed(KeyEvent e) {
     
            switch(e.getKeyCode()){
                case 37 : left = true ; break;
                case 39 : right = true ; break;
                case 38 : up = true ; break;
                case 40 : down = true ; break;
                case 32 : space = true ; break;
            }
        }
     
        public void keyReleased(KeyEvent e) {
            switch(e.getKeyCode()){
                case 37 : left = false ; break;
                case 39 : right = false ; break;
                case 38 : up = false ; break;
                case 40 : down = false ; break;
                case 32 : space = false ; break;
            }
        }
     
        public String showState() {
            return "KeyBoard{" + "left=" + left + "  right=" + right + "  up=" + up + "  down=" + down + "  space=" + space + '}';
        }
     
     
     
        public static void main(String[] args) {
        	JFrame frame=new JFrame();
            frame.setContentPane(new KeyBoard());
            frame.setSize(200,200);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    Ici, on regarde l'état des touches toutes les secondes. Dans ton jeux, ça sera toutes les 50ms ou un truc dans le genre.
    Dans le code ci-dessus, il faut rajouter l'aspect concurrentiel entre droite/gauche et haut/bas. Et garder le choix du joueur en mémoire ( s'il appuie pendant 2ms et qu'il relâche, tu n'auras pas le temps d'analyser son geste si tu regarde l'état toutes les 50 ms ).

    Bonne continuation

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2011
    Messages : 8
    Par défaut
    Bonjour, et merci à vous pour vos réponses

    Comme je le disais, lorsque j'effectue un déplacement, avec les touches directionnelles, donc en maintenant au moins une touche enfoncé, le déplacement du personnage s'effectue. A ce moment là, si j'appuis sur la touche espace par exemple pour effectuer une action en même temps que le déplacement (simultanée), les nouveaux évènements arrivant pour touche directionnelle pressé sont bloqué/plus détecté !

    Donc je suis contraint de relâcher la touche directionnelle puis de la presser de nouveau après avoir appuyer sur espace, afin de continuer le déplacement en cours !

    Donc aucuns systèmes de booléen ne fonctionne pour gérer ce problème. Cela est t-il une limitation de la gestion des évènements de la plateforme java ???

    Concernant le solution de Ivelios, de créer un Timer/Thread, c'est la solution auquel j'avais pensé et je pense la seul qu'il me reste.

    Mais le gestion des évènements par un thread n'est t-elle pas une implémentation un peu trop lourde ?

    Effectivement, pour avoir un gameplay un minimum réactif, je vais pas attendre tout les 100ms (ce que demande déjà pas mal de ressource processeur pour un seul thread) de gérer l'action de l'utilisateur, car niveau réactivité c'est vraiment pas ce qu'il y a de mieux.

    Si vous avez une autre idée pour résoudre le problème parce que là vraiment je bloque.

  6. #6
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Voici un exemple propre sur la façon de gérer les inputs clavier:

    http://zetcode.com/tutorials/javagam...movingsprites/

  7. #7
    Membre Expert Avatar de Nico02
    Homme Profil pro
    Developpeur Java/JEE
    Inscrit en
    Février 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Developpeur Java/JEE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 728
    Par défaut
    Citation Envoyé par vieks Voir le message

    Donc je suis contraint de relâcher la touche directionnelle puis de la presser de nouveau après avoir appuyer sur espace, afin de continuer le déplacement en cours !

    Donc aucuns systèmes de booléen ne fonctionne pour gérer ce problème. Cela est t-il une limitation de la gestion des évènements de la plateforme java ???
    Ça fonctionne très bien, j'ai réalisé plusieurs jeux avec ce système

    A chaque intervalle de temps tu regardes quels booléens sont à vrai et tu fais les actions associés.

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

Discussions similaires

  1. [c++]Architecture des classes pour un jeu
    Par Pegasus32 dans le forum C++
    Réponses: 23
    Dernier message: 16/02/2005, 14h07
  2. Menus en OpenGL pour un jeu?
    Par shifty.net dans le forum OpenGL
    Réponses: 7
    Dernier message: 02/07/2004, 12h38
  3. Réponses: 6
    Dernier message: 30/06/2004, 08h16
  4. [Threads]Comment les organiser pour un jeu du serpent ?
    Par Pill_S dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 11/05/2004, 15h22
  5. Quel style de DirectX pour un jeu 2D ?
    Par delire8 dans le forum DirectX
    Réponses: 34
    Dernier message: 31/07/2003, 00h47

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