# Tastatursteuerung verbessern



## K-Man (17. Dez 2005)

Hallo zusammen.
Ich hab mal ein kleines Tetrisprogramm geschrieben. Leider ist die Tastatursteuerung etwas mühselig. Kann ich diese verbessern? Das Programm soll evtl schneller auf Tastaturereignisse reagieren...

Hier die Ereignisabfrage:

```
public void keyPressed(KeyEvent e)
		{
			if(board != null && !board.isPlayerWait())
			{
				if (e.getKeyCode() == KeyEvent.VK_RIGHT)
				{
					board.moveBrick(1, 0);
				}
				if (e.getKeyCode() == KeyEvent.VK_LEFT)
				{
					board.moveBrick(-1, 0);
				}
				if (e.getKeyCode() == KeyEvent.VK_DOWN)
				{
					board.moveBrick(0, 1);
				}
				if (e.getKeyCode() == KeyEvent.VK_UP)
				{
					board.rotateBrick();
				}
			}
		}
```


Und hier der Spielthread:

```
public void run()
	{
		while (!isInterrupted())
		{
			try
			{
				Thread.sleep(speed);
				if (moveBrick(0, 1))
				{
					playerWait = true;
					for (int i = 0, n = actualBrick.getBrick().length; i < n; i++)
					{
						field[(actualBrick.getBrick()[i].getRow())][actualBrick
									.getBrick()[i].getCol()].setFix(true);
					}
					actualBrick = (Brick) nextBrick.clone();
					nextBrick = getRandomBrick();
				}
				while (removeCompleteLines())
				{
					fireGameStateChangedEvent();
					Thread.sleep(500);
				}
				playerWait = false;
			}
			catch (InterruptedException e)
			{
				interrupt();
				e.printStackTrace();
			}
			catch (CloneNotSupportedException e)
			{
				e.printStackTrace();
			}
		}
	}
```

moveBrick bewegt den Stein in die entsprechende Richtung. Ich hab ne Abfrage isPlayerWait, damit der Spieler nicht einen Stein drücken kann, wenn gerade Reihen gelöscht werden. Kann ich es irgendwie anders lösen? Wenn ich es mit einem Listener mache, dann kommts doch auch auf das selbe raus.

Hier ist übrigens der Link zum Spiel, dann könnt ihr selber sehen, was ich meine: KTetris0.43a


----------



## PoiSoN (17. Dez 2005)

:?: Weiß gar nicht was du meinst, reagiert doch top?


----------



## K-Man (18. Dez 2005)

Für die ersten Levels reicht es, aber nach ein paar Levels reichts nicht mehr. Evtl soll er zwei Tastaturereignisse gleichzeitig behandeln bzw schnell hintereinander, so dass ich gleichzeitig einen Stein bewegen und rotieren kann. Geht des überhaupt?
Wenn es jemanden interessiert, der Quelltext zum Spiel ist im jar-Archive enthalten. Habe nämlich vor ein paar kleine Games und Apps zu schreiben (auch mal was größeres als Tetris) und diese auf meine Homepage zu veröffentlichen. Ziel ist eigentlich eine effektivere Programmierweise zu erlernen...und am besten geht das durch Übung


----------



## Soulfly (18. Dez 2005)

Dann kommst du nicht um booleans herum.


```
Achtung Pseudocode

boolean left;
boolean right;

if(keypressed.LEFT) left = true;
if(keypressed.RIGHT) right = true;

if(keyreleased.LEFT) left = false;
if(keyreleased.RIGHT) right = false;
```


----------



## K-Man (19. Dez 2005)

Wie meinst du das mit den boolean? Dass die move-Methode regelmäßig aufgerufen wird (also nicht nur alle sec) und überprüft, ob gerade eine taste gedrückt wurde...hmm mal ausprobieren...


----------



## Hansdampf (19. Dez 2005)

nimm das if(playerwait) raus und hau die gedrückten Tasten dafür in eine Liste, dann geht nix verloren


----------



## K-Man (19. Dez 2005)

Habs jetzt mit der Liste probiert. Aber an der Steuerung hat sich nichts geändert...


```
class KeyHandler extends KeyAdapter
	{
		public void keyPressed(KeyEvent e)
		{
			if(board != null)
			{
				keyEvents.add(e);
			}
		}
	}
```



```
class Test extends Thread
	{
		public void run()
		{
			while(!isInterrupted())
			{
				for(int i = 0, n = keyEvents.size(); i < n; i++)
				{
					KeyEvent o = keyEvents.get(i);
					
					if (o.getKeyCode() == KeyEvent.VK_RIGHT)
					{
						board.moveBrick(1, 0);
					}
					else if (o.getKeyCode() == KeyEvent.VK_LEFT)
					{
						board.moveBrick(-1, 0);
					}
					else if (o.getKeyCode() == KeyEvent.VK_DOWN)
					{
						board.moveBrick(0, 1);
					}
					else if (o.getKeyCode() == KeyEvent.VK_UP)
					{
						board.rotateBrick();
					}
					
					keyEvents.remove(o);
				}
				
				try
				{
					Thread.sleep(20);
				}
				catch (InterruptedException e)
				{
					interrupt();
				}
			}
		}
	}
```

Hab ich jetzt einen Gedankenfehler oder hab ich die Sache mit der Liste falsch verstanden?


----------



## Hansdampf (19. Dez 2005)

hm.
bei mir funktioniert die Steuerung gut.
Das Löschen aus der Liste würde ich anders machen:


```
for(int i = 0, i< keyEvents.size(); i++)
            {
               KeyEvent o = keyEvents.get(i);
               
               if (o.getKeyCode() == KeyEvent.VK_RIGHT)
               {
                  board.moveBrick(1, 0);
               }
               else if (o.getKeyCode() == KeyEvent.VK_LEFT)
               {
                  board.moveBrick(-1, 0);
               }
               else if (o.getKeyCode() == KeyEvent.VK_DOWN)
               {
                  board.moveBrick(0, 1);
               }
               else if (o.getKeyCode() == KeyEvent.VK_UP)
               {
                  board.rotateBrick();
               }
                           
            }
 keyEvents.clear();
```

bin mir nicht sicher, aber bei deiner Version zählst du den Index hoch, beim Löschen rutschen alle Indizes ab i aber eins runter, besser durchgehen und zum Schluss alle Löschen.


----------



## K-Man (19. Dez 2005)

Es funktioniert schon ganz gut, aber ich glaube, dass es an der Tastatur bzw. am Betriebsystem liegt. Die Steuerung geht einwandfrei, aber wenn man bei höheren Levels schneller reagieren muss, dann kommt das Betriebssystem mit den Tasten nicht mehr mit. Kann es daran liegen? Jedenfalls ist die Steuerung nicht so schnell wie beim Original... :cry:


----------

