2016-04-30 10 views
0

Ich entwerfe ein klassisches Schlangenspiel, bei dem der Benutzer einen Schwierigkeitsgrad auswählt (über JRadioButtons) und die Schlange mit den Pfeiltasten steuert. Ich habe 2 JPanels: SetupPanel und SnakePanel, die zu einem JFrame, GameFrame hinzugefügt werden. Ich benutze einen Faden, um die Schlange zu bewegen.Fokus Problem mit mehreren JPanels & einem Thread

Im Moment versuche ich, Funktionalität zu den JRadioButtons hinzuzufügen, die Geschwindigkeit mit zunehmender Schwierigkeit schneller. Die Schlange funktioniert gut, bis ich eine neue Schwierigkeit (auf dem SetupPanel) auswähle. Dann setzt die Schlange die Bewegung im SnakePanel fort, aber Sie können die Schlange nicht mehr mit den Pfeiltasten bewegen.

Ich bin ziemlich sicher, dass dies ein Schwerpunktproblem ist, und habe Stunden damit verbracht, die Tutorials zu lesen, aber nichts scheint zu helfen.

public class GameFrame extends JFrame{ 

    this.add(new SetupPanel(), BorderLayout.NORTH); 

    SnakePanel snakePanel = new SnakePanel(); 
    this.add(snakePanel, BorderLayout.SOUTH); 

    setLocationRelativeTo(null); 

    setVisible(true); 
    snakePanel.requestFocusInWindow(); //without this my thread doesn't work 
} 




public class SetupPanel extends JPanel{ 

    JLabel statusLbl; 

    public SetupPanel(){ 

     super(); 
     //add all of the JRadioButtons 
     //add them to a button group 

    } 

private class LevelHandler implements ActionListener{ 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     if(e.getSource() == begButton){ 
      speed = 100000; 
     } 


     if(e.getSource() == intButton){ 
      speed = 400000; 
     } 


     if(e.getSource() == advButton){ 
       speed = 700000; 
      } 

      setFocusable(false); //Doesn't seem to make a difference 

     } 

    } 

} 

Dann, was ich bin sehr verwirrt über meine SnakePanel:

public class SnakePanel extends JPanel implements Runnable{ 
    public SnakePanel() { 

     setFocusable(true); //Focus on this panel or snake won't move 

     //I have also tried these lines to keep focus on this 
     //panel but it doesn't work either 
     //this.addFocusListener(new FocusAdapter() { 
     // public void focusLost(FocusEvent ev) { 
     // requestFocus(); 
     // } 
     // }); 

     //set what it will look like, size, etc... 

     this.addKeyListener(new Key()); 
     startMoving(); 
    } 


    private void startMoving(){ 
     running = true; 
     thread = new Thread(this, "snake movement"); 
     thread.start(); 
    } 

    @Override 
    public void run() { 
     while(running){ 
      move();  //things program does each time snake moves 
      repaint(); 
     } 
    } 

    //KeyListeners 

} 

Antwort

2

Ich bin mir ziemlich sicher, dass dies ein Schwerpunkt Problem ist

Ja. Der Fokus befindet sich jetzt auf dem Optionsfeld und nicht auf der Komponente, der Sie den KeyListener hinzugefügt haben.

und steuert die Schlange mit den Pfeiltasten.

Die bessere Lösung ist Key Bindings zu verwenden. Die Tastenbelegungen funktionieren auch dann, wenn eine Komponente den Fokus hat.

Weitere Informationen und Arbeitsbeispiele finden Sie unter Motion Using the Keyboard.

+0

ok Ich werde einen Blick –

1

Verwenden KeyBindings ...

this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "right"); 
    this.getActionMap().put("right", new AbstractAction() { 
     public void actionPerformed(ActionEvent e) { 
      //move certain direction 
     } 
    }); 

und wiederholen pro verschiedene Schlüssel