# Spielsteuerung / AWT-Keyevents



## xaggi (24. Jun 2005)

Tag zusammen,

wir sollen ein Spiel in Java programmieren. Dabei müssen wir einen Schläger bewegen, dies soll eigentlich mittels der Pfeiltasten der Tastatur geschehen.

Das ganze soll so Funktionieren, dass die Klasse, die die Keyevents verarbeitet eine Funktion anbietet, die true oder false zurückgibt, je nachdem ob eine Pfeiltaste gehalten wird oder nicht.

Momentan steuere ich das Spiel über Control und Alt, da ich hier einfach über InputEvent.isAltDown bzw. isControlDown abfragen kann, ob die Taste gehalten wird.

Bei den Pfeiltasten gibt es eine solche Funktion aber ja nicht, und ein dauerdruck der taste löst ja abwechselnd gedrückt- und losgelassen-events aus.

Kann mir jemand sagen, wie ich trotzdem herausfinden kann, ob eine taste noch gehalten wird, oder losgelassen wurde?


----------



## Wildcard (24. Jun 2005)

benutz Key-Pressed und Key-Released.
Wenn eine Taste gedrückt wurde machst du was, wenn sie losgelassen wurde hörst du damit wieder auf...  :wink:


----------



## xaggi (25. Jun 2005)

Ja, das ist ja grade mein Problem.

Bei keypressed und keyreleased werden eben elementare keyevents ausgegeben, das heißt, ich krieg ständig keypressed und released im wechsel, wenn ich eine taste gedrückt halte.
Deshalb suche ich nach einer möglichkeit, das zu unterbinden und nur den gedrückt und losgelassen status abzufragen, wie mit isAltDown etc. möglich.


----------



## Beni (25. Jun 2005)

Da setzt du am besten einen Thread ein.

Um es in Pseudocode auszudrücken:

```
class X extends Runnable{
  boolean left = false;

  public X(){
    new Thread( this ).start();
  }

  public void keyPressed( KeyEvent e ){
    if( e.getKeyCode() == KeyEvent.VK_ARROW_LEFT )   // oder  wie das Ding heisst
       left = true;
  }

  run(){
    while( true ){
      // Diese Schleife wird alle ~25 Millisekunden durchlaufen.

      if( left ){
         // hier, wenn die Taste gedrückt ist
      }
      else{ 
         // hier, wenn die Taste nicht gedrückt ist.
      }
      Thread.sleep( 25 );
    }
  }
}
```


----------



## xaggi (25. Jun 2005)

Da ist aber ja dann left immer true.
Wie soll ich denn da abfragen, ob die Taste nicht gedrückt ist?
Das ist ja das Problem. Wenn ich left=false setze bei keyreleased, dann ist es vollkommen zufällig, ob ich ein true oder ein false kriege.


----------



## Beni (25. Jun 2005)

Du setzt beim keyReleased left=false.

Der Thread schaut einfach alle paar Millisekunden, ob die Taste noch gedrückt ist (falls dir Thread nichts sagt, guck mal in einem Buch nach).
Es ist nicht zufällig, was "left" ist: es ist true wenn der Benutzer die Taste gerade gedrückt hält, und sonst false.



> Bei den Pfeiltasten gibt es eine solche Funktion aber ja nicht, und ein dauerdruck der taste löst ja abwechselnd gedrückt- und losgelassen-events aus.


Korrigiert mich, wenn ich falsch bin. Aber da werden nur dauernd press-Events losgeschickt, realease-Events werden wirklich nur dann verschickt, wenn die Taste losgelassen wird.


----------



## Guest (25. Jun 2005)

> Korrigiert mich, wenn ich falsch bin. Aber da werden nur dauernd press-Events losgeschickt, realease-Events werden wirklich nur dann verschickt, wenn die Taste losgelassen wird.

Leider bist du falsch. Genau das ist mein Problem.


----------



## Beni (25. Jun 2005)

Für folgenden Code aus:

```
public class Test{
   public static void main( String[] args ){
       JPanel panel = new JPanel();
       panel.setFocusable( true );
       
       panel.addKeyListener( new KeyAdapter(){
           @Override
           public void keyPressed( KeyEvent e ) {
               System.out.println( "pressed: "  + e.getKeyChar() );
           }
           @Override
           public void keyReleased( KeyEvent e ) {
               System.out.println( "released: "  + e.getKeyChar() );
           }
       });
       
       JFrame frame = new JFrame();
       frame.add( panel );
       frame.setBounds( 20, 20, 500, 500 );
       frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
       frame.setVisible( true );
   }
}
```

Ich bekomme diese Ausgabe, wenn ich die Taste "6" gedrückt halte:


> pressed: 6
> pressed: 6
> pressed: 6
> pressed: 6
> ...


Es werden nur press-Events verschickt.
Dass das Verhalten auf zwei verschiedenen PC's anders ist, glaube ich ehrlich gesagt nicht ???:L


----------



## Guest (25. Jun 2005)

/workspace/test$ java Test
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6
pressed: 6
released: 6


----------



## xaggi (25. Jun 2005)

Das war ich.

Habs getestet, mit deinem Code (allerdings musste ich die @overridess auskommentieren).

Getestet mit:
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) Client VM (build 1.5.0_03-b07, mixed mode, sharing)
unter kubuntu GNU/Linux 2.6.10-5-386


----------



## Roar (25. Jun 2005)

liegt vielleicht an deinem window manager, dass der das so (für mich ziemlich unverständlich) regelt und die mouseevents so weiterleitet.


----------



## Beni (25. Jun 2005)

Hmpf, da hies es dochmal "Platformunabhängig"...

Wie wäre es, auf das keyReleased mit Verspätung zu reagieren. Also  wenn eine Taste losgelassen wird, muss erst z.b. 20 Millisekunden vergehen, bis der "left"-boolean auf false geschalten wird. Wenn zwischenzeitlich wieder keyPressed aufgerufen wird, muss man das loslassen natürlich streichen.


----------



## xaggi (25. Jun 2005)

Hmm, das ist alles sehr unschön und unsicher. Also wenn es dafür keine "richtige" Möglichkeit gibt, die dann auch auf allen Systemen funktioniert, dann bleib ich lieber bei der Steuerung mit Alt und Control (das Spiel ist immerhin Klausurzulassungskriterium, sollte also schon fehlerfrei funktionieren )


----------



## dublo (13. Nov 2006)

Tut mir Leid so einen alten Thread wiederzubeleben, aber ich habe genau das selbe Problem und bis jetzt konnte ich keine Antwort finden.

Weiß denn niemand, woran das liegen könnte? Ich benutzt auch Linux, glaube aber dass das Problem auch vorhin in Windows aufgetreten ist...
Das werde ich auf jeden Fall überprüfen.


----------

