2015-02-24 73 views
2

我正在製作一個簡單的Snake遊戲,除了Key Listener之外,一切似乎都正常。基於我所看到的一切,它被正確書寫。使用Key Listeners更改JFrame

遊戲顯示出來,但即使按下箭頭鍵,Snake也不會移動。

在此先感謝!

這是主要的:

public class SnakeFrame extends JFrame implements KeyListener{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private int direction; 
    private World w; 
    private WorldComponant wc; 
    GameLoopThread glt; 

    public SnakeFrame(){ 
     setSize(420,440); 
     setTitle("Snake"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Container c = getContentPane(); 
     c.setLayout(new BorderLayout()); 

     w = new World(); 
     wc = new WorldComponant(w); 
     glt = new GameLoopThread(wc); 
     direction = Direction.SOUTH; 

     c.add(wc); 
    } 

    public static void main(String[] args){ 
     SnakeFrame s = new SnakeFrame(); 
     s.setVisible(true); 
    } 

    public void keyPressed(KeyEvent e) { 
     switch(e.getKeyCode()){ 
     case (KeyEvent.VK_UP):{ 
      if(direction!=Direction.SOUTH){ 
       direction = Direction.NORTH; 
       wc.move(direction); 
      } 
      break; 
     } 
     case (KeyEvent.VK_DOWN):{ 
      if(direction!=Direction.NORTH){ 
       direction = Direction.SOUTH; 
       wc.move(direction); 
      } 
      break; 
     } 
     case (KeyEvent.VK_RIGHT):{ 
      if(direction!=Direction.WEST){ 
       direction = Direction.EAST; 
       wc.move(direction); 
      } 
      break; 
     } 
     case (KeyEvent.VK_LEFT):{ 
      if(direction!=Direction.EAST){ 
       direction = Direction.WEST; 
       wc.move(direction); 
      } 
      break; 
     } 
     } 
} 

    @Override 
    public void keyReleased(KeyEvent e) { 

    } 

    @Override 
    public void keyTyped(KeyEvent e) { 

    } 

} 

這是GameLoopThread:

public class GameLoopThread extends Thread{ 

    private WorldComponant sc; 

    public GameLoopThread(WorldComponant sc){ 
     this.sc = sc; 
    } 



    public void run(){ 
     while(true){ 
      sc.repaint(); 
      try{ 
       Thread.sleep(100); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

這是移動方法。它是世界級的內部,從WorldComponant也被稱爲:

public void move(int direction) { 
     Point head = snake.peekFirst(); 
     Point newPt = head; 
     switch(direction){ 
     case (Direction.NORTH):{ 
      newPt = new Point(head.x, head.y-1); 
      break; 
     } 
     case (Direction.SOUTH):{ 
      newPt = new Point(head.x, head.y+1); 
      break; 
     } 
     case (Direction.WEST):{ 
      newPt = new Point(head.x-1, head.y); 
      break; 
     } 
     case (Direction.EAST):{ 
      newPt = new Point(head.x+1, head.y); 
      break; 
     } 

     } 

     snake.remove(snake.peekLast()); 

     if(newPt.equals(food)){ 
      Point addPt = (Point) newPt.clone(); 

      switch(direction){ 
      case (Direction.NORTH):{ 
       newPt = new Point(head.x, head.y-1); 
       break; 
      } 
      case (Direction.SOUTH):{ 
       newPt = new Point(head.x, head.y+1); 
       break; 
      } 
      case (Direction.WEST):{ 
       newPt = new Point(head.x-1, head.y); 
       break; 
      } 
      case (Direction.EAST):{ 
       newPt = new Point(head.x+1, head.y); 
       break; 
      } 

      } 
      score++; 
      snake.add(addPt); 
      placeFood(); 

     } 
     else if(newPt.x < 0 || newPt.x > gridw - 1){ 
      generateDefaultSnake(); 
      JOptionPane.showMessageDialog(null, "YOU LOST! :(", "Loser!", JOptionPane.ERROR_MESSAGE); 
      return; 
     } 
     else if(newPt.y < 0 || newPt.y > gridh - 1){ 
      generateDefaultSnake(); 
      JOptionPane.showMessageDialog(null, "YOU LOST! :(", "Loser!", JOptionPane.ERROR_MESSAGE); 
      return; 
     } 
     else if(snake.contains(newPt)){ 
      generateDefaultSnake(); 
      JOptionPane.showMessageDialog(null, "YOU LOST! :(", "Loser!", JOptionPane.ERROR_MESSAGE); 
      return; 
     } 

     snake.add(newPt); 

    } 
+1

你曾經的實施KeyListener的添加到您的JFrame?另一方面,如果你的WorldComponant類需要成爲'JComponent'的子類,你應該考慮使用鍵綁定。 – TNT 2015-02-24 18:49:58

+1

請勿使用KeyListener!請參閱[使用鍵盤移動](https://tips4java.wordpress.com/2013/06/09/motion-using-the-keyboard/)以獲得使用「鍵綁定」的更好方法。 – camickr 2015-02-24 19:09:44

回答

0

KeyListerner是衆所周知的了麻煩,而是試圖直接添加到JFrame時,更是雪上加霜。 A JFrame在它與用戶之間具有JRootPane,contentPane和可能的glassPane,所有這些都可以竊取焦點並防止KeyListener接收關鍵事件。

一個更好的解決辦法是使用的鍵綁定API和註冊它根據自定義的contentPane

How to use key bindings更多細節