# Java "Multi"KeyListener



## Developer_X (7. Aug 2009)

hi, ich habe folgendes Problem:

```
public void keyPressed(KeyEvent arg0) 
	{		
		if(arg0.getKeyCode()==KeyEvent.VK_UP)
		{
		}
		else if(arg0.getKeyCode()==KeyEvent.VK_DOWN)
		{
		}
		else if(arg0.getKeyCode()==KeyEvent.VK_LEFT)
		{
		}
		else if(arg0.getKeyCode()==KeyEvent.VK_RIGHT)
		{
		}
	}
```
mit dieser Methode, kann man checken ob:
*UP*,*DOWN*,*LEFT *oder *RIGHT *gedrückt wird, 

Es ist aber so: 
wenn man *LEFT *gedrückt hält, dann *UP *drückt, 
wird das was bei *LEFT *geschieht ignoriert, und nur noch das was bei *UP *passiert gemacht, wie aber, kann man das machen, dass er beide methoden tut, auch wenn eine zweite taste gedrückt wird?


----------



## sparrow (7. Aug 2009)

Was heißt denn "else if"?


----------



## icarus2 (7. Aug 2009)

Ich würde ja eine solche Methode empfehlen:

up, down, left, right sind alles boolsche Membervariablen zu instanzieren (wenn du möchtest kannst du sie auf false setzen, wobei das natürlich automatisch passiert bei Membervariablen).


Wenn die Taste gedrückt wurde:
[Java]
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_UP){
			up = true;
		}

		if(e.getKeyCode() == KeyEvent.VK_DOWN){
			down = true;
		}

		if(e.getKeyCode() == KeyEvent.VK_LEFT){
			left = true;
		}

		if(e.getKeyCode() == KeyEvent.VK_RIGHT){
			right = true;
		}


	}
[/Java]

Wenn die Taste losgelassen wurde:
[Java]
	@Override
	public void keyReleased(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_UP){
			up = false;
		}

		if(e.getKeyCode() == KeyEvent.VK_DOWN){
			down = false;
		}

		if(e.getKeyCode() == KeyEvent.VK_LEFT){
			left = false;
		}

		if(e.getKeyCode() == KeyEvent.VK_RIGHT){
			right = false;
		}

	}
[/Java]

Und dann so überprüfen (ich habe die Methode zur Überprüfung checkKeys() genannt... stammt aus dem Tutorial von Quaxli  ):
[Java]
	public void checkKeys(){


		if(up){
			setSpeedY(-MAX_SPEED_Y);

		}

		if(down){

			setSpeedY(MAX_SPEED_Y);

		}
		if(left){

			setSpeedX(-MAX_SPEED_X);

		}
		if(right){

			setSpeedX(MAX_SPEED_Y);

		}

		if(!up && !down){
			setSpeedY(0);
		}

		if(!left && !right){
			setSpeedX(0);
		}

	}
[/Java]


*Edit:
In diesem Fall natürlich kein else if, da ja zwei Dinge gleichzeitig möglich sind... also erst überlegen und nicht blind proggen wie man sichs gewohnt ist ;-)

*Edit 2:
setSpeedX() und setSpeedY() sind natürlich frei gewählte Methodennamen, die wie ich vermute in keiner Standardbilbiothek vorhanden sind.


----------



## Spacerat (8. Aug 2009)

In den oft von mir erwähnten NeHe-Tutorials taucht irgendwo in Lesson21 etwas in dieser Art auf :
	
	
	
	





```
public class KeyManager
implements KeyListener
{
  private final boolean[] keys = new boolean[256];

  public void keyTyped(KeyEvent ke)
  {
    // not needed
  }

  public void keyPressed(KeyEvent ke)
  {
    int index = ke.getKeyCode();
    if(index >= 0 && index < 256) keys[index] = true;
  }

  public void keyReleased(KeyEvent ke)
  {
    int index = ke.getKeyCode();
    if(index >= 0 && index < 256) keys[index] = false;
  }

  public boolean isKeySet(int key)
  {
    return (key >= 0 && key < 256)? keys[key] : false;
  }
}
```
Die Methode "isKeySet()" kann nun von überall, wo der KeyManager verfügbar ist, mit einem KeyCode zwischen 0 und 255 aufgerufen werden (z.B. "isKeySet(KeyEvent.VK_LEFT)").


----------



## Developer_X (8. Aug 2009)

also, ums kurz zu machen, ich habe folgende booleans:

```
boolean forward;
boolean backward
boolean leftward;
boolean rightward;
```
Ich habe mir hier aus diesem Thread einige Antworts möglichkeiten rausgepickt, und ausprobiert, klappt aber nicht, wieso? Es werden immer noch nicht beide gleichzeitig verwendet

```
public void keyPressed(KeyEvent arg0) 
	{		
        if(arg0.getKeyCode() == KeyEvent.VK_UP)
        {
            forward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_DOWN)
        {
            backward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_LEFT)
        {
            leftward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            rightward = true;
        }
        
		doMoves();
	}
	public void keyReleased(KeyEvent arg0) 
	{	
		if(arg0.getKeyCode() == KeyEvent.VK_UP)
		{
            forward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_DOWN)
        {
            backward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_LEFT)
        {
            leftward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            rightward = false;
        }

	}
	public void doMoves()
	{
		if(forward)
		{
			iz--;
			z=z-0.1f;
			rot--;rot--;
			
			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
			
			ball.rotX(Math.toRadians(rot));
			ball.setTranslation(new Vector3f(x,y,z-10));
			Ball.setTransform(ball);
		}
		else if(backward)
		{
			iz++;
			z=z+0.1f;
			rot++;rot++;

			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
			
			ball.rotX(Math.toRadians(rot));
			ball.setTranslation(new Vector3f(x,y,z-10));
			Ball.setTransform(ball);
		}
		else if(leftward)
		{
			ix--;
			x=x-0.1f;
			
			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
			
			ball.setTranslation(new Vector3f(x,y,z-10));
			Ball.setTransform(ball);
		}
		else if(rightward)
		{
			ix++;
			x=x+0.1f;
			
			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
			
			ball.setTranslation(new Vector3f(x,y,z-10));
			Ball.setTransform(ball);
		}
	}
	public void keyTyped(KeyEvent arg0)
	{		
	}
```

Was mache ich falsch?


----------



## icarus2 (8. Aug 2009)

Zur Namengebung der Variablen: Ich würde up, down, left und right vorziehen. Denn in welche Richtung geht den forward, nach oben, links, rechts? Aber vielleicht passt es ja sogar, weiss ja nicht genau wie die Bewegungen aussehen.

Nimm die 'else if' in der Methode doMoves() raus. Also nur if, if, if. Wenn sonst die erste Bedingung erfüllt ist igrnoriert die JVM den Rest und die anderen 'ifs' werden gar nie ausgeführt.

Da ich aber die Methode doMoves() in einer KeyListener-Methode sehr sehr merkwürdig finde würde ich dir anraten mal den Anfang von Quaxlis Tutorial zu lesen. Oder auch viele andere Tutorials zeigen dir wie eine GameLoop funktioniert. Aber das von Quaxli ist am besten: Click me


----------



## sparrow (8. Aug 2009)

Außerdem wiederholt sich in deiner doMoves()-Methode unglaublich viel Code. Jede Bedingung macht fast das Selbe, außer die ersten beiden Zeilen?


----------



## Developer_X (8. Aug 2009)

danke euch beiden, mein Programm ist schon sehr weiter modifiziert, ich habe aber immer noch ein Problem:
1.Also wenn ich vorwärts gedrückt halte,ok geht.
2.Also wenn ich vorwärts gedrückt halte, dann rechts drücke, bewegt er sich nach vorne und rechts, aber, wenn ich rechts loslasse, geht gar nichts mehr, erst wenn ich vorwärst auch loslasse gehts.

warum?
Wie kann ichs ändern?

@icarus
Es ist bei mir ein 3DSpiel, also mit Java3D, in dem man sich vorwärts bewegt, soviel nur dazu.

@sparrow
wie du siehst, habe ich ja das programm weitermodifiziert, ist nichts mehr zu erkennen.

so ist der Code momentan:

```
public void keyPressed(KeyEvent arg0) 
	{		
        if(arg0.getKeyCode() == KeyEvent.VK_UP)
        {
            forward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_DOWN)
        {
            backward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_LEFT)
        {
            leftward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            rightward = true;
        }
        
		doMoves();
	}
	public void keyReleased(KeyEvent arg0) 
	{	
		if(arg0.getKeyCode() == KeyEvent.VK_UP)
		{
            forward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_DOWN)
        {
            backward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_LEFT)
        {
            leftward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            rightward = false;
        }

	}
	public void doMoves()
	{
		if(forward)
		{
			checkFor();		
		}
		if(backward)
		{
			checkBack();			
		}
		if(leftward)
		{
			checkLeft();			
		}
		if(rightward)
		{
			checkRight();			
		}
	}
```


----------



## sparrow (8. Aug 2009)

Wie ist denn der Inhalt der checkXXX-Methoden?


----------



## icarus2 (8. Aug 2009)

Aso, ja bei 3D ist es etwas anderes mit den Richtungen. Das Grundkonzept einer GameLoop dürfte dabei aber das gleiche sein denke ich wie bei einem 2D Spiel.


----------



## Spacerat (8. Aug 2009)

???:L ...gibt es vllt. irgendwelche Probleme (bis auf den inzwischen korregierten Fehler in der "isKeySet()"-Methode) mit meinem KeyManager? Oder ist euch der schlicht zu einfach?
	
	
	
	





```
import static java.awt.event.KeyEvent.*;

public class MoveManager
{
  private final KeyManager km = new KeyManager();

  public void doMoves()
  {
    if(km.isKeySet(VK_UP)) {
      // move up
    }

    if(km.isKeySet(VK_DOWN)) {
      // move down
    }

    if(km.isKeySet(VK_LEFT)) {
      // move left
    }

    if(km.isKeySet(VK_RIGHT)) {
      // move right
    }

    if(km.isKeySet(VK_CONTROL)
    && km.isKeySet(VK_ALT)
    && km.isKeySet(VK_F)) {
      // toggle fullscreen
    }
    // usw. usw. usw.
  }
}
```
Das mit dem "toggle fullscreen" hat nun nichts mit Bewegung zu tun, es steht nur dort, um aufzuzeigen, was alles geht. Die Frage, welche Namen irgendwelche in der gesammten Anwendung verstreuten "booleans" bekommen erübrigt sich hier auch.
Der KeyManager ist zudem auch noch ein hervorragender Kandidat für ein Singleton.
@Developer_X: Deine Argumente bei der Namensgebung verstehe ich. Zumindest was "forward" und "backward" angeht. Aber "rightward" und "leftward"? Sagt man das so? Wie wär's mit "turnleft" und "turnright"?


----------



## Developer_X (8. Aug 2009)

´bei mir dreht man sich nicht "left" und "right"
das spiel soll "Black'n'White" heißen.
Hier der Code, ich glaube es geht nicht anders, (ach ja screenShots gibts auch):

```
package Levels;

import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.swing.*;
import javax.vecmath.*;
import Library_3D.*;
import com.sun.j3d.utils.universe.*;

/**
 * 
 * @author Kevin Riehl
 *
 */
@SuppressWarnings("serial")
public class Level_1 extends JFrame implements KeyListener
{
	//Attribute
		//Dimension
	  	  Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
	      BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1000.0);
	      
	      SimpleUniverse u; 
	    //KeyListener
	      boolean forward,backward,leftward,rightward;
	      boolean speed_true = false;
	    //All
	      Transform3D ball = new Transform3D();
	      Transform3D view = new Transform3D();
	      TransformGroup Ball = new TransformGroup();
	      
	      float x,y,z;
	      float rot;
	      int ix,iy,iz = 0;
	      float speed = 0.5f;
	      
	public Level_1()
	{
		super("Black'n'White");
		setSize(d); 	
		setLayout(new BorderLayout());
		setUndecorated(true);
		getContentPane().setBackground(Color.black);
		
		BranchGroup scene = createtheScene();       
		GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
	    Canvas3D canvas = new Canvas3D(config);
	    add("Center", canvas);       
	    canvas.addKeyListener(this);
	    u = new SimpleUniverse(canvas);       
	    u.addBranchGraph(scene);
	        
		setVisible(true);
		
	}
	
	//Create the Scene
	public BranchGroup createtheScene()
	{
		BranchGroup X = new BranchGroup();
		
		Floor f = new Floor();
		X.addChild(f.getChild());
		
		ball = new Transform3D();
		ball.setTranslation(new Vector3f(x,y,z-5));
		Ball = new TransformGroup(ball);
		X.addChild(Ball);
		Ball.addChild(new SPHERE());
		Ball.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 

       return X;
	}

	public void keyPressed(KeyEvent arg0) 
	{		
        if(arg0.getKeyCode() == KeyEvent.VK_UP)
        {
            forward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_DOWN)
        {
            backward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_LEFT)
        {
            leftward = true;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            rightward = true;
        }
        
		doMoves();
	}
	public void keyReleased(KeyEvent arg0) 
	{	
		if(arg0.getKeyCode() == KeyEvent.VK_UP)
		{
            forward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_DOWN)
        {
            backward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_LEFT)
        {
            leftward = false;
        }
        
        if(arg0.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            rightward = false;
        }

	}
	public void doMoves()
	{
		if(forward)
		{
			checkFor();		
		}
		if(backward)
		{
			checkBack();			
		}
		if(leftward)
		{
			checkLeft();			
		}
		if(rightward)
		{
			checkRight();			
		}
	}
	public void keyTyped(KeyEvent arg0)
	{		
	}
	
	public void checkRight()
	{
		if(ix>=8)
		{
			;
		}
		else
		{
			ix++;
			x=x+0.1f;
			
			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
		
			ball.setTranslation(new Vector3f(x,y,z-5));
			Ball.setTransform(ball);
		}
	}
	public void checkLeft()
	{
		if(ix<=-8)
		{
			;
		}
		else
		{
			ix--;
			x=x-0.1f;
			
			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
		
			ball.setTranslation(new Vector3f(x,y,z-5));
			Ball.setTransform(ball);
		}
	}
	public void checkFor()
	{
		
			iz--;
			
			z=z-speed;
			rot--;rot--;
			System.out.println(iz);

			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
		
			ball.rotX(Math.toRadians(rot));
			ball.setTranslation(new Vector3f(x,y,z-5));
			Ball.setTransform(ball);
		
	}
	public void checkBack()
	{
		if(ix==0&&iz==-10)
		{			
			iz++;
			
			z=z-speed;
			System.out.println(iz);
			rot--;rot--;
	
			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
		
			ball.rotX(Math.toRadians(rot));
			ball.setTranslation(new Vector3f(x,y,z-5));
			Ball.setTransform(ball);
		}
		else
		{
			iz++;
			
			z=z+speed;
			rot++;rot++;

			view.setTranslation(new Vector3f(0,y,z));
			u.getViewingPlatform().getViewPlatformTransform().setTransform(view);
		
			ball.rotX(Math.toRadians(rot));
			ball.setTranslation(new Vector3f(x,y,z-5));
			Ball.setTransform(ball);
		}
	}
	
	public static void main(String[]args)
	{
		new Level_1();
	}
}
```

Also das mit "CheckLeft" usw...
Das werde ich beibehalten, da werden die Abfragen, der Position des Balles, ob man "left" oder "right" gehen darf, abgefragt, ich glaube da ist das problem eher nicht?

!Achtung!
Wer das ganze mal ausprobieren und spielen möchte, es ist nicht fertig, ich brauche erstmal die Basics des Spieles, der brauch sich nur bei mir zu melden, und ich geb demjenigen dann noch die fehlenden Klassen "Floor.java" und "SPHERE.java"

Developer_X

PS: 
ich hoffe ihr könnt mir weiterhelfen


----------



## Developer_X (8. Aug 2009)

Aber wie ich sehe, scheint ihr, 
besonders SpaceRat und du icarus
viel Erfahrung in Sachen SpieleProgrammierung zu haben,
vielleicht könnten wir mal zusammen ein little game programmieren, damit ich die Basics darin lerne, vielleicht,


----------



## Developer_X (8. Aug 2009)

wenigstens ne Idee was es sein könnte?


----------



## Spacerat (8. Aug 2009)

Developer_X hat gesagt.:
			
		

> bei mir dreht man sich nicht "left" und "right"


...sondern am Rad in den höheren Leveln... :lol:
...wie beim guten alten "Sat-1 Superball" aus Amiga-Zeiten, an welches mich dein Spiel gerade erinnert (Superball3D :lol. Mal sehen... gab's dafür nicht auch irgendwann mal den Quellcode? Wenn ja, hab' ich den noch rumflattern? Ich schau mal nach...


----------



## icarus2 (8. Aug 2009)

Am besten schaust dir mal par kleine Spiele an auf miniclip.de oder so, dann findest du sicher ne Idee wie du was ändern, erweitern oder was auch immer machen kannst.

Ich selber hab leider grad zu wenig Zeit um ein Projekt zu starten. Muss noch meine Maturaarbeit beenden und solche Dinge -.-


----------

