2017-05-31 103 views
0

我正在編寫一個小遊戲。到目前爲止,我有一名球員,可以在玩家之後進入2D印刷世界。這裏有一個小的previewKeyListener事件的短延遲

現在我的球員動作的代碼如下所示:

的KeyListener類

public void keyPressed(KeyEvent e) { 
    int key = e.getKeyCode(); 
    for(int i = 0; i < handler.object.size(); i++){ 
     GameObject tempObject = handler.object.get(i); 

     if(tempObject.getId() == ID.Player){ 
      if(key == KeyEvent.VK_D) tempObject.setVelX(5); 
      if(key == KeyEvent.VK_A) tempObject.setVelX(-5); 
      if(key == KeyEvent.VK_SPACE && Var.jump == true) { 
       tempObject.setVelY(-10); 
       Var.jump = false; 
      } 
     } 
    } 
public void keyReleased(KeyEvent e) { 
    int key = e.getKeyCode(); 

    for(int i = 0; i < handler.object.size(); i++){ 
     GameObject tempObject = handler.object.get(i); 

     if(tempObject.getId() == ID.Player){ 
      if(key == KeyEvent.VK_D) tempObject.setVelX(0); 
      if(key == KeyEvent.VK_A) tempObject.setVelX(0); 
     } 
    } 

Player類

public void tick() { 
    if (Var.falling == true) { 
     velY += Var.gravity; 
     if (velY > 10) { 
      velY = 10; 
     } 
    } 
    x += velX; 
    y += velY; 

這些代碼都只是類的部分。

問題

當我移動到右側或左側與A或d,然後點擊其它鍵(從a到d /從d到a)在一定的方式,我的字符靜止了很短的時間,然後在短暫的延遲之後移動。見here

+0

你能具體談談什麼是「以某種方式」是什麼?理想情況下,如果你能解決這個問題,那麼Keydowns和Keyups的確切順序。這可能有助於在程序中記錄這些信息。 – slim

回答

0

很難說確切的問題是什麼不知道keyups和keydowns的精確序列,但它看起來好像你的程序很容易受到重疊KEYUP /的keydown序列 - 例如:

A down -> velocity = -5 
D down -> velocity = +5 
A up -> velocity = 0 // but you want it to still be +5 

添加記錄到您的遊戲代碼以幫助調試這些情況。

有許多的方式來處理這個問題,但一個辦法是保持目前向下鍵的運行計數:

public void keyPressed(KeyEvent e) { 
    heldKeys++; 
    ... other code ... 
} 

public void keyReleased(KeyEvent e) { 
    heldKeys--; 
    ... other code ... 
    if(heldKeys == 0) { 
      velocity = 0; 
    } 
} 

這是輕量級的,但鈍。更精確的方法可能是讓每個按鍵的狀態的記錄:

public void keyPressed(KeyEvent e) { 
    int key = e.getKeyCode(); 
    heldKeys.set(key, true); 
} 

...做什麼在keyStates的基礎上,你的遊戲狀態更新。

根據你想要獲得效率的狂熱程度,keyStates可能是HashSet(Integer, Boolean)或更專門化你自己創作的東西。


但是!有關自動重複鍵盤的討論,請參閱How to know when a user has really released a key in Java?

1
  1. 用戶按下d,其觸發對keyPressed的呼叫時,它調用tempObject.setVelX(5)
  2. 用戶版本A,觸發keyReleased的呼叫,呼叫tempObject.setVelX(0)。這會暫停角色的動作。
  3. 用戶仍然按住d,所以在短暫的延遲後,該鍵的自動重複觸發另一個呼叫keyPressed,這會導致tempObject.setVelX(5)再次調用,從而導致再次開始移動的字符。

你不應該叫tempObject.setVelX(0)除非沒有運動鍵被按下

你如何判斷?您需要定義跟蹤它們的實例字段。例如:

private boolean leftPressed; 
private boolean rightPressed; 

// ... 

public void keyPressed(KeyEvent e) { 
    //... 

    if (key == KeyEvent.VK_D) { 
     rightPressed = true; 
     tempObject.setVelX(5); 
    } 
    if (key == KeyEvent.VK_A) { 
     leftPressed = true; 
     tempObject.setVelX(-5); 
    } 

    //... 
} 

public void keyReleased(KeyEvent e) { 
    //... 

    if (key == KeyEvent.VK_D) { 
     rightPressed = false; 
     if (!leftPressed) { 
      tempObject.setVelX(0); 
     } 
    } 
    if (key == KeyEvent.VK_A) { 
     leftPressed = false; 
     if (!rightPressed) { 
      tempObject.setVelX(0); 
     } 
    } 

    //... 
} 

一些旁註:

  • gameObject會比tempObject一個更好的變量名。
  • 你永遠不要寫「booleanVariable == true」。相反,只需編寫booleanVariable。這避免了通過寫一個「=」而不是兩個來意外分配的可能性。例如:
 
    if (Var.falling) { 

更簡單地說:從你的代碼中刪除的== true每次發生。

0

感謝大家回答我並幫助我。我修好了它。

最好的問候, 馬克西