2013-01-09 3 views
1

en ce moment je fais un éditeur de niveau en Java. Le niveau est dans un JPanel. A l'intérieur de ce JPanel je mets les éléments du jeu (Héros, ennemi, arbre, mur ..) Pour chaque élément j'utilise le class.GameElement.JPanel dans un JPanel n'écoute pas KeyListener

public class GameElement extends JPanel 
{ 
protected int posX, posY; 
private Color color; 


public GameElement(int x, int y, Color color) 
{ 
    this.posX = x; 
    this.posY = y; 
    this.color = color; 

} 

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    g.setColor(color); 
    g.fillRect(0, 0, 50, 50); 
} 

} 

La classe GameElement est également un JPanel. Je veux que l'élément de jeu soit mobile en utilisant le KeyListener.

import java.awt.Color; 
import java.awt.event.*; 

public class Hero extends Entity implements KeyListener 
{ 
public Hero(int x, int y, Color color) 
{ 
    super(x, y, color); 


    this.setFocusable(true); 
    this.addKeyListener(this); 
} 

public void keyPressed(KeyEvent k) 
{ 
    if(k.getKeyCode() == KeyEvent.VK_UP) 
    { 
     this.move(0, -1); 
    } 
    else if(k.getKeyCode() == KeyEvent.VK_DOWN) 
    { 
     this.move(0, 1); 
    } 
    else if(k.getKeyCode() == KeyEvent.VK_LEFT) 
    { 
     this.move(-1, 0); 
    } 
    else if(k.getKeyCode() == KeyEvent.VK_RIGHT) 
    { 
     this.move(1, 0); 
     System.out.println("test"); 
    } 
} 

public void keyTyped(KeyEvent k) 
{ 

} 

public void keyReleased(KeyEvent k) 
{ 

} 
} 

Lorsque je lance l'éditeur de niveau. L'affichage du héros réussit sur mon écran mais il ne bouge pas quand j'appuie sur le bouton de la touche. Est-ce parce que je ne me concentre pas sur le bon JPanel?

+2

Pour un jeu, vous devez probablement enregistrer un écouteur de clés global, afin de vous assurer que vous recevez toujours l'événement key. Il y a quelques questions sur SO pour cela, par exemple: http://stackoverflow.com/questions/4780910/jpanel-keylistener – Ash

+1

http://stackoverflow.com/a/10603588/1360074 "KeyListener n'est pas conçu pour être écouté des événements de clavier pour Swing JComponents, utilisez KeyBindings à la place " –

+1

duplication possible de [Classe extension KeyListener ne répondant pas aux pressions de touches] (http://stackoverflow.com/questions/14221458/class-extending-keylistener-not-responding-to- appuyer sur les touches) –

Répondre

6

Ce n'est pas que vous vous concentrez sur le mauvais JPanel mais plutôt que JPanel n'est pas focalisable et ne peut donc pas interagir avec KeyEvents. C'est pourquoi dans Swing, il est préférable d'utiliser Key Bindings qui vous permet de mapper une Action à une KeyStroke même si un composant n'a pas de focus.

example

+0

+1 yup keybindings TOUJOURS –

1

Vous pouvez ajouter un AWTEventListener à la valeur par défaut Toolkit à écouter pour tous les événements clés, et non en fonction de l'élément a le focus (juste l'application doit avoir le focus):

AWTEventListener theListener = new AWTEventListener() { 
     @Override 
     public void eventDispatched(AWTEvent event) { 
      System.out.println(event); 
     } 
    }; 
    Toolkit toolkit = Toolkit.getDefaultToolkit(); 
    toolkit.addAWTEventListener(theListener, AWTEvent.KEY_EVENT_MASK); 

Modifier
AWTEvents sont le type d'événements à faible niveau, préfèrent utiliser ActionMap/InputMap (ou tout simplement registerKeyboardAction)