2013-10-27 67 views
0

所以我試圖做一個Roguelike遊戲程序代等。但我遇到了字符處理的麻煩。 事情是當我想用鍵盤移動字符時,它只是改變它的座標 - 當然它應該這樣做,但我無法在屏幕上看到它。 我在這個網站上閱讀了一些答案,這對我有點幫助,但並沒有完全解決問題。
所以,我注意到知道我做錯了,這裏的一些代碼(希望這不是太長):JPanel沒有更新後KeyPressed

public class PanelTest extends JPanel implements KeyListener{ 


    private static final long serialVersionUID = 1L; 
    private Game game; 
    private int width, height; 
    private int tileSize; 

    public PanelTest(Game game, int tileSize) { 
     super(); 

     this.game = game; 
     this.tileSize = tileSize; 
     this.width = game.getMap().getWidth()*tileSize; 
     this.height = game.getMap().getHeight()*tileSize; 

     this.addKeyListener(this); 

     setPreferredSize(new Dimension(width, height)); 
     setRequestFocusEnabled(true); 
     requestFocus(); 
     setVisible(true); 

    } 

    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     for(int i=0; i < game.getMap().getWidth(); i++){ 
      for(int j=0; j < game.getMap().getHeight(); j++){ 
       g.setColor(game.getMap().getColor(i,j)); 
       g.fillRect(i*tileSize, j*tileSize, tileSize, tileSize); 
      } 
     } 
// print the correct coordinates 
     System.out.println(game.getPlayer().getX()+" "+game.getPlayer().getY()); 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     // TODO Auto-generated method stub 
     switch(e.getKeyCode()){ 
     case(KeyEvent.VK_Z) : game.getPlayer().moveUp();break; 
     case(KeyEvent.VK_S) : game.getPlayer().moveDown(); break; 
     case(KeyEvent.VK_Q) : game.getPlayer().moveLeft(); break; 
     case(KeyEvent.VK_D) : game.getPlayer().moveRight(); break; 
     } 
     revalidate(); 
     repaint(); 

    } 

    public void addNotify() { 
     super.addNotify(); 
     requestFocus(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    public static void main(String[] args){ 
     JFrame frame = new JFrame(); 
     frame.setBounds(0, 0, 400, 400); 

     Map map = MapFactory.createNewEmptyMap(); 
     RoomMaker rm = new RoomMaker(map.getWidth()/7,map); 
     TunnelMaker tm = new TunnelMaker(rm, map); 
     rm.carveOut(); 
     tm.carveOut(); 
     Room r = rm.getRandomRoom(); 
     Player p = new Player(map, r.getxCenter(),r.getyCenter()); 
     Game game = new Game(map,p); 

     frame.getContentPane().add(new PanelTest(game, 10)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 


} 

希望能對你有所幫助,謝謝!

回答

1

默認情況下,JPanel使用FlowLayout。

它看起來像你的代碼改變球員的位置,但你調用重新驗證(),這會導致調用佈局管理器代碼和組件的位置重新計算一次。

因此,對於有隨機移動的遊戲,您希望使用空佈局,並且不需要調用revalidate()和repaint(),因爲代碼不負責直接調用setLocation()方法。

有關使用keyListener的問題,另請參閱Motion Using the Keyboard

setRequestFocusEnabled(true); 
requestFocus(); 
setVisible(true); 

以上是不需要的。您設置爲true的兩個屬性默認爲true。除非組件顯示在可見的GUI上,否則不能請求關注組件,因此在此處添加代碼不會執行任何操作。另外,使用的正確方法是requestFocusInWindow(),而不是requestFocus()。

+0

謝謝,這幫助我更好地理解它是如何工作的。我也意識到我搞砸了我的角色運動,我沒有真正要求它在屏幕上移動..但無論如何,謝謝! – 4Mechanix