2017-05-31 11 views
0

私は少しゲームをプログラミングしています。これまでのところ、私はプレイヤーの後に2D印刷されたタイルの世界を動かすことができるプレーヤーを持っています。ここでは小さいpreviewです。KeyListenerイベントの短い遅延

今の私のプレーヤーの動きのコードは次のようになります。

の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); 
     } 
    } 

プレーヤークラス

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

これらのコードは、クラスのほんの一部です。

問題

私は右または特定の方法でAまたはDで放置し、その後(にDからのD /への)他のキーをタップに移動しています、私の性格短時間静止した後、この短い遅延の後に移動する。 hereを参照してください。

+0

あなたは、「特定の方法は、」何であるかについて、より具体的なことはできますか?理想的には、あなたがそれを試すことができれば、キーダウンとキーアップの正確なシーケンス。これはあなたのプログラムにこれらを記録するのに役立ちます。 – 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で何に基づいて、あなたのゲームの状態の更新を行います。

効率性についてどの程度光栄に思っているのかによって、keyStatesHashSet(Integer, Boolean)または独自の作成に特化したものになる可能性があります。


BUT!キーボードからの自動リピートについては、How to know when a user has really released a key in Java?を参照してください。

1
  1. ユーザーtempObject.setVelX(5)を呼び出しkeyPressedへの呼び出しをトリガDを押します。
  2. は、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); 
     } 
    } 

    //... 
} 

いくつかのサイドノート:

  • gameObjecttempObjectよりもはるかに優れ変数名になります。
  • "booleanVariable == true"と記述しないでください。代わりに、ブール値と書いてください。これにより、2つの代わりに1つの '='を書くことによって、偶発的な割り当ての可能性を回避します。例えば:
 
    if (Var.falling) { 

はもっと簡単に言えば:あなたのコードから== trueのすべての発生を削除します。

0

誰もが私に答えてくれてありがとう。それを私が直した。

よろしく、 マキシ

関連する問題