Spielprogrammierung mit Java
HomeAufgabenDruckenJava-Online

Tastatur-Events

Viele Spiele verwenden die Tastatur zum Steuern der Spielfiguren. In den nachfolgenden Beispielen beschreiben wir zwei Möglichkeiten der Tastensteuerung:

GGKeyListener hat zwei Callbackmethoden keyPressed() und keyReleased(). Die Information, welche Taste gedrückt wurde, liefern die Methoden getKeyCode() oder getKeyChar().

Beispiel 1: Verwendung des GGKeyListeners

Der Frosch kann mit den Cursortasten UP, DOWN, LEFT bzw. RIGHT bewegt werden. Ziel ist es, möglichst schnell alle Fliegen zu fressen.

Die Methode getKeyCode() aus der Klasse java.awt.Event.KeyEvent gibt den KeyCode der gedrückten Taste zurück. In einer switch-Struktur folgen die Anweisungen, die nach Drücken einer der Cursortasten erfolgen sollen.

 

 

 

// JGameEx17.java

import ch.aplu.jgamegrid.*;
import java.awt.Color;
import java.awt.event.KeyEvent;

public class JGameEx17 extends GameGrid
{
  public JGameEx17()
  {
    super(10, 10, 60, Color.red, false);
    Frog frog = new Frog();
    addActor(frog, new Location(0, 0));
    for (int = 0; i < 10; i++)
      addActor(new Fly(), getRandomEmptyLocation());
    addKeyListener(frog);
    show();
    doRun();
  }

  public static void main(String[] args)
  {
    new JGameEx17();
  }
}

// ------------------ class Frog ---------------------------
class Frog extends Actor implements GGKeyListener
{
  public Frog()
  {
    super(true"sprites/frog1.gif");
  }

  public boolean keyPressed(KeyEvent evt)
  {
    switch (evt.getKeyCode())
    {
      case KeyEvent.VK_UP:
        setDirection(270);
        break;
      case KeyEvent.VK_RIGHT:
        setDirection(0);
        break;
      case KeyEvent.VK_LEFT:
        setDirection(180);
        break;
      case KeyEvent.VK_DOWN:
        setDirection(90);  
        break;
    }
     move();
     tryToEat();
    
    return true;
  }

  public boolean keyReleased(KeyEvent evt)
  {
    return true;
  }

  public void tryToEat()
  {
    Actor actor = gameGrid.getOneActorAt(getLocation(), Fly.class);
    if (actor != null)
       actor.hide();
  }
}

// --------------------- class Fly ---------------------------
class Fly extends Actor
{

  public Fly()
  {
    super("sprites/fly.gif");
  }
}

Programmcode für lokale Bearbeitung downloaden: JGameEx17.zip

Erklärungen zum Programmcode:
doRun() Wenn diese Methode im Konstruktor aufgerufen wird, bewirkt es dasselbe, wie wenn die Schaltfläche Run im Navigationsbalken gedrückt wurde: das Simulationszyklus startet
class Frog extends Actor implements GGKeyListener Der GGKeyListener wird in der Regel beim Objekt, der bewegt werden soll, implementiert
getKeyCode() Gibt den numerischen Code der gedrückten Taste zurück
KeyEvent.VK_LEFT An Stelle dieses symbolischen Bezeichnes könnte der numerische Code der Cursortaste LEFT stehen (39). Man verwendet aber zum besseren Verständnis die Bezeichner VK_LEFT, VK_UP, VK_DOWN und VK_RIGHT
setDirection(270)
move()
Beim Drücken einer Cursortaste dreht sich der Frosch in die entsprechende Richtung und bewegt sich um eine Zelle vorwärts. Da der Frosch als drehbar deklariert wurde (new Actor (true"sprites/frog1.gif")), dreht sich auch das Bild in die entsprechende Richtung
tryToEat() Testet, ob sich an der aktuellen Position eine Fliege befindet und eliminiert sie

 

Beispiel 2: Verwenden des GGKeyListeners
Der Frosch friss Fliegen und verändert seine Form. Nach jeder gefressenen Fliege wird er dicker.

Wenn man einen Tastendruck als Ereignis erfasst, muss man einen GGKeyListener registrieren, der die Tastatur überwacht. GGKeyListener hat zwei Callbackmethoden: keyPressed() und keyReleased(), die in der Klasse BigFrog implemetiert werden müssen. Falls true zurückgegeben wird, erhalten andere KeyListeners keine Notifikation mehr (man spricht davon, dass der Event "konsumiert" wird). Hier spielt dies keine Rolle, da nur ein KeyListener vorhanden ist.

 

// JGameEx18.java

import ch.aplu.jgamegrid.*;
import java.awt.Color;
import java.awt.event.KeyEvent;

public class JGameEx18 extends GameGrid
{
  public JGameEx18()
  {
    super(10, 10, 60, Color.red, false);
    BigFrog frog = new BigFrog();
    addActor(frog, new Location(0, 0));
    for (int = 0; i < 6; i++)
      addActor(new Fly(), getRandomEmptyLocation());
    playSoundGGSound.DUMMY);
    addKeyListener(frog);
    show();
    doRun();
  }

  public static void main(String[] args)
  {
    new JGameEx18();
  }
}

// --------------------- class BigFrog --------------------------
class BigFrog extends Actor implements GGKeyListener
{
  private int nbEatedFlies = 0;

  public BigFrog()
  {
    super(true"sprites/frog.gif"7);
  }

  public boolean keyPressed(KeyEvent evt)
  {
    switch (evt.getKeyCode())
    {
      case KeyEvent.VK_UP:
        setDirection(270);
        move();
        tryToEat();
        break;
      case KeyEvent.VK_RIGHT:
        setDirection(0);
        move();
        tryToEat();
        break;
      case KeyEvent.VK_LEFT:
        setDirection(180);
        move();
        tryToEat();
        break;
      case KeyEvent.VK_DOWN:
        setDirection(90);
        move();
        tryToEat();
        break;
    }
    return true;
  }

  public boolean keyReleased(KeyEvent evt)
  {
    return true;
  }

  private void tryToEat()
  {
    Actor actor = gameGrid.getOneActorAt(getLocation(), Fly.class);
    if (actor != null)
    {
      actor.hide();
      nbEatedFlies++;
      show(nbEatedFlies);
      gameGrid.playSound(GGSound.FROG);
    }
  }
}

// --------------------- class Fly ---------------------------
class Fly extends Actor
{
  public Fly()
  {
    super("sprites/fly.gif");
  }
}

Programmcode für lokale Bearbeitung downloaden: JGameEx18.zip

Erklärungen zum Programmcode:
addKeyListener(frog) Der KeyListener der Klasse Frog wird registriert
Actor frog = new Actor(true, "sprites/frog.gif", 7) Bei der Deklaration vom Actor Frog, kann die Anzahl Sprites, die zum Actor gehören, angegeben werden. Die Sprit-Bilder müssen als frog_0.gif, frog_1.gif, ..., frog_6.gif gespeichert werden
nbEatedFlies++
frog.show(nbEatedFlies)

Die Anzahl der gefressenen Fliegen wird gezählt, da damit die Dicke des Frosches (d.h. spriteId) festgelegt wird. Mit show() wird das entprechende Sprite angezeigt

playSound(GGSound.DUMMY) Das Soundsystem wird initialisiert. Lässt man diese Zeile weg, wird der erste Sound mit einer kleinen Verzögerung abgespielt
playSound(GGSound.FROG) Die wav-Datei FROG wird abgespielt

 

Beispiel 3: Verwenden von GGKeyListener

Der rote Ball kann mit den Cursortasten DOWN, UP, LEFT und RIGHT durch das labyrith bewegt werden. Die Bewegung darf nur auf den weissen Feldern erfolgen.

 

 

 

// JGameEx19.java

import ch.aplu.jgamegrid.*;
import java.awt.Color;
import java.awt.event.KeyEvent;

public class JGameEx19 extends GameGrid
{
  private Ball ball;

  public JGameEx19()
  {
    super(15, 15, 40, Color.red, "sprites/mazeGrid.gif"false);
    ball = new Ball();
    addActor(ball, new Location(0, 1));
    addKeyListener(ball);
    show();
    doRun();
  }

  public static void main(String[] args)
  {
    new JGameEx19();
  }
}

// --------------------
class Ball extends Actor implements GGKeyListener
{
  public Ball()
  {
    super("sprites/ball.gif");
  }

  public boolean keyPressed(KeyEvent evt)
  {
    Location next = null;
    switch (evt.getKeyCode())
    {
      case KeyEvent.VK_UP:
        next = getLocation().getNeighbourLocation(Location.NORTH);
        setDirection(Location.NORTH);
        break;
      case KeyEvent.VK_RIGHT:
        next = getLocation().getNeighbourLocation(Location.EAST);
        setDirection(Location.EAST);
        break;
      case KeyEvent.VK_LEFT:
        next = getLocation().getNeighbourLocation(Location.WEST);
        setDirection(Location.WEST);
        break;
      case KeyEvent.VK_DOWN:
        next = getLocation().getNeighbourLocation(Location.SOUTH);
        setDirection(Location.SOUTH);
        break;
    }
    if (next != null && canMove(next))
      setLocation(next);
    return true;
  }

  public boolean keyReleased(KeyEvent evt)
  {
    return false;
  }

  private boolean canMove(Location location)
  {
    Color c = gameGrid.getBg().getColor(location);
    if (c.equals(Color.black))
      return false;
    else
      return true;
  }
}

Erklärungen zum Programmcode:
implements GGKeyListener Implementiert GGKeyListener
sprites/mazeGrid.gif In diesem Beispiel ist das Labyrinth als Hintergrundbild gespeichert. Unter dem Menüpunkt Gitter- games/Labyrinth finden Sie ein "richtiges Labyrinth-Spiel" bei dem der Hintergrund bei jedem Spieldurch ganz neu und zufällig gezeichnet wird
next = ball.getLocation().getNeighbourLocation(Location.NORTH)
ball.setDirection(Location.NORTH);
Beim Drücken der Taste UP wird unter next die benachbarte Zelle richtung nord gespeichert und die Richtung auf Nord gesetzt
Color c = getBackground().getColor(location) Gibt die Hintergrundfarbe der aktuellen Zelle zurück
if (c.equals(Color.black))
      return false
Wenn die Hintergrundfarbe schwarz ist, gibt die Methode canMove() false zurück

 

Beispiel 4: Pollen (ständiges Prüfen, ob Taste gedrückt)

Man verwendet die Methode isKeyPressed(), die true liefert, wenn eine bestimmte Taste gedrückt wurde. Die verschiedenen KeyCodes sind in der Klasse KeyEvent definiert. Ein Tastenklick kann beim Pollen verpasst werden, wenn das Pollen nicht genügend oft durchgeführt wird.

Der Fisch schwimmt hin und her. Mit den Cursortasten UP und DOWN kann seine vertikale Position verändert werden.

 

 

 

// JGameEx20.java

import ch.aplu.jgamegrid.*;
import java.awt.Color;
import java.awt.event.KeyEvent;

public class JGameEx20 extends GameGrid
{
  public JGameEx20()
  {
    super(101060Color.red, "sprites/reef.gif");
    CoralFish nemo = new CoralFish();
    addActor(nemo, new Location(00));
    show();
  }

  public static void main(String[] args)
  {
    new JGameEx20();
  }
}

//--------------- class CoralFish ------------------------------
class CoralFish extends Actor
{
  public CoralFish()
  {
    super("sprites/nemo.gif");
  }

  public void act()
  {
    move();
    if (gameGrid.isKeyPressed(KeyEvent.VK_UP) && getY() > 0)
      setY(getY() - 1);
    if (gameGrid.isKeyPressed(KeyEvent.VK_DOWN) && getY() < 9)
      setY(getY() + 1);
    if (getX() == 0 || getX() == 9)
    {
      turn(180);
      setHorzMirror(isHorzMirror() ? false : true);
    }
  }
}

Erklärungen zum Programmcode:
isKeyPressed(KeyEvent.VK_UP Gibt true zurück, wenn die Taste CursorUP gedrückt ist
isKeyPressed(KeyEvent.VK_DOWN Gibt true zurück, wenn die Taste CursorDOWN gedrückt ist

Verwendet man die standardmässige Simulationsperiode, so wird act() nur alle 200 Millisekunden aufgerufen. Klickt man nur kurz auf die Cursortasten, so ist das Risiko gross, dass dieses Erreignis verpasst wird. Erhöht man die Simulationsperiode, so ist das Risiko gross, dass ein Tastendruck den Fisch um mehrere Zeilen verschiebt.