2017-05-31 7 views
0

Ich programmiere ein kleines Spiel. Bisher habe ich einen Spieler, der sich in einer 2D-gedruckten Fliesenwelt dem Spieler folgend bewegen kann. Hier eine kleine preview.Kurze Verzögerung für KeyListener Ereignisse

Im Moment sieht mein Spieler Bewegung Code wie folgt:

KeyListener Klasse

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

Spielerklasse

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

Diese Codes nur Teile der Klassen sind.

Problem

Als ich nach rechts oder nach dem mit A oder D nach links bewegte und dann die andere Taste tippen (von a bis d/von d nach a) in einer bestimmten Art und Weise, mein Charakter steht für kurze Zeit still und bewegt sich dann nach dieser kurzen Verzögerung. Siehe here.

+0

Können Sie das konkretisieren, was „Ein gewisser Weise“ ist? Im Idealfall, wenn Sie es ausarbeiten können, die genaue Abfolge von Keydowns und Keyups. Es kann helfen, diese in Ihrem Programm zu protokollieren. – slim

Antwort

0

Es ist schwer zu sagen, was das genaue Problem ohne ist die genaue Abfolge von keyups und keydowns zu wissen, aber es sieht aus, als ob Ihr Programm ist anfällig keyup/keydown Sequenzen überlappende - zum Beispiel:

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

hinzufügen Loggen Sie sich in Ihren Spielcode ein, um diese Situationen zu beheben.

Es gibt eine Reihe von Möglichkeiten, dies zu umgehen, aber ein Weg ist, eine laufende Zählung zur Zeit-down Tasten zu halten:

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

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

Dies ist leicht, aber stumpf.

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

... tun, um Ihr Spielstatus-Updates auf der Grundlage das, was in keyStates: Ein verfeinerten Ansatz könnte eine Aufzeichnung des Zustandes jede Taste zu halten sein.

Je nachdem, wie fanatisch Sie über Effizienz erreichen wollen, keyStates könnte ein HashSet(Integer, Boolean) oder etwas mehr von Ihrer eigenen Schöpfung spezialisiert sein.


ABER! Eine Erläuterung zur automatischen Wiederholung über die Tastatur finden Sie unter How to know when a user has really released a key in Java?.

1
  1. Benutzer drückt D, die einen Aufruf an keyPressed auslöst, die tempObject.setVelX(5) nennt.
  2. Benutzerfreigaben Ein, der einen Anruf an keyReleased auslöst, der tempObject.setVelX(0) aufruft. Dies hält die Bewegung deines Charakters an.
  3. Benutzer hält noch immer D, so dass nach einer kurzen Verzögerung nach unten, Auslöser, die Taste des Wiederholrate einen weiteren Anruf zu keyPressed, die tempObject.setVelX(5) verursacht wieder aufgerufen werden, den Charakter verursacht wieder in Bewegung zu beginnen.

Sie sollten nicht anrufen tempObject.setVelX(0) es sei denn keine Bewegungstaste gedrückt wird.

Wie ermitteln Sie das? Sie müssen Instanzfelder definieren, die sie verfolgen. Zum Beispiel:

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

    //... 
} 

Einige Nebennoten:

  • gameObject wäre eine viel bessere Variablennamen als tempObject sein.
  • Sie sollten niemals "booleanVariable == true" schreiben. Schreiben Sie stattdessen booleanVariable. Dies vermeidet jede Möglichkeit einer zufälligen Zuweisung, indem ein '=' anstelle von zwei geschrieben wird. Zum Beispiel:
 
    if (Var.falling) { 

einfach gesagt: jedes Vorkommen von == true aus dem Code entfernen.

0

Danke an alle, die mir antworten und mir helfen. Ich habe es repariert.

Mit besten Grüßen, Maxi