Spielprogrammierung mit Java
HomeAufgabenDruckenJava-Online

Mouse Events II (mit GGMouseTouchListener)


Im Unterschied zu den Methoden des GGMouseListeners (mouse.getX(), mouse.getY()), welche die Gitterkoordinaten des Mausklicks zurück geben, geben die Methoden des GGMouseTouchListeners den Actor zurück, zu welchen das mit Maus berührte Sprite gehört. Dies ist insbesondere dann vorteilhaft, wenn mit kleineren Gitterzellen oder mit Fenstern mit Pixel-Auflösung gearbeitet wird.
Der GGMouseTouchListener wird mit addMouseTouchListener() im GameGrid registriert. Dabei werden die Events angegeben an denen man interessiert ist. In unseren Beispielen lPress und lRelease.

Es ist oft sinnvoll sowohl den GGMouseListener als auch den GGMouseTouchListener zu implementieren. GGMouseTouchListener für das "Fassen" und Loslassen der zu bewegenden Figuren und den GGMouseListener für die Bewegung mit gedrückten Maustaste. Wenn wir lDrag des GGTouchListeners verwenden, kann es bei einer schnellen Mausbewegung vorkommen, dass das Spritebild nicht mehr richtig mitbewegt wird, das die Maus den Actor nicht mehr berührt.

Beispiel 1: Im Fenster mit Pixel-Auflösung kann der Actor "Nemo" mit der Maus in einem beliebigen Punkt des Sprite-Bildes gefasst und kontinuierlich an eine neue Position verschoben werden.


 

// JGameEx22a.java

import ch.aplu.jgamegrid.*;
import java.awt.*;

public class JGameEx22a extends GameGrid 
  implements GGMouseTouchListenerGGMouseListener
{
  private Point hotSpot = null;
  private Actor nemo = new Actor("sprites/nemo.gif");
 
  public JGameEx22a()
  {
    super(300, 300, 1, false);
    setTitle("Drag Nemo!");
    nemo.addMouseTouchListener(thisGGMouse.lPress | GGMouse.lRelease);
    addMouseListener(thisGGMouse.lDrag);
    addActor(nemo, new Location(150, 150));
    show();
  }
  
  public boolean mouseEvent(GGMouse mouse)
  {
    if (hotSpot == null)
      return false;
    Location loc =
      new Location(mouse.getX() - hotSpot.x, mouse.getY() - hotSpot.y);
    nemo.setLocation(loc);
    refresh();
    return false;
  }

  public void mouseTouched(Actor actor, GGMouse mouse, Point spot)
  {
    switch (mouse.getEvent())
    {
      case GGMouse.lPress:
        hotSpot = spot;
        break;
      case GGMouse.lRelease:
        hotSpot = null;
        break;
    }
  }

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

Programmcode für lokale Bearbeitung downloaden: JGameEx22a.zip

Erklärungen zum Programmcode:

nemo.addMouseTouchListener(this, GGMouse.lPress |  GGMouse.lRelease)

Registriert beim Actor nemo den MouseTouchListener mit den Mausaktionen Drücken und loslassen der linken Maustaste. Da die Applikationsklasse einen GGMousTouchListener implementiert, wird ihre Referenz übergeben (this)

addMouseListener(this, GGMouse.lDrag)

Registriert den MouseListener mit der Mausaktion Bewegen mit gedrückter Maustaste
mouseTouched(Actor actor, GGMouse mouse, Point spot) Callbackmethode, die ein Event zurück gibt, wenn die Maus das Spritebild des Actor berührt
Location loc =
         new Location(mouse.getX() - hotSpot.x, mouse.getY() - hotSpot.y);
        actor.setLocation(loc);
Verschiebt den Actor an die neue Position

 

Beispiel 2: Manchmal ist es sinnvoll die Objekte kontinuierlich zu bewegen und dann schlussendlich in den Gitterzellen exakt zu positionieren. In Beispiel 2 sollen die zu Beginn zufällig verteilte Kugeln mit der Maus verschoben und exakt in einer Reihe angeordnet werden.

 

 

 


 

// JGameEx22b.java

import ch.aplu.jgamegrid.*;
import java.awt.*;

public class JGameEx22b extends GameGrid
  implements GGMouseTouchListener
{
  private Actor draggedPearl;

  public JGameEx22b()
  {
    super(8, 5, 80, Color.red, false);
    setTitle("Sort Pearls");
    for (int = 0; i < 8; i++)
    {
      Actor pearl = new Actor("sprites/pearl.png");
      addActor(pearl, getRandomEmptyLocation());
      pearl.addMouseTouchListener(thisGGMouse.lPress | GGMouse.lRelease | GGMouse.lDrag);
    }
    show();
    setSimulationPeriod(20);
    doRun();
  }

  public void mouseTouched(Actor actor, GGMouse mouse, Point spot)
  {
    switch (mouse.getEvent())
    {
      case GGMouse.lPress:
        draggedPearl = actor;
        break;
      case GGMouse.lRelease:
        if (draggedPearl != null)
        {
          draggedPearl.setLocationOffset(new Point(0, 0));
          draggedPearl = null;
        }
        break;
       case GGMouse.lDrag:
         if (draggedPearl != null)
         {
           Point mousePos = new Point(mouse.getX(), mouse.getY());
           draggedPearl.setPixelLocation(mousePos);
         }
        break;          
    }
  }

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

}

Programmcode für lokale Bearbeitung downloaden: JGameEx22b.zip

Erklärungen zum Programmcode:
addMouseTouchListener(this, GGMouse.lPress | GGMouse.lDrag | GGMouse.lRelease) Registriert den MouseListener mit den Mausaktionen Drücken der linken Maustaste, Verschieben mit gedrückter Maustaste und loslassen der linken Maustaste
case GGMouse.lPress:
        draggedPearl = actor
Die Methode lPress des GGMouseTouchlistener gibt den Actor zurück, der mit der linken Maustaste gedrück wurde. Die gewählte Perle wird als draggedPearl bezeichnet. Dieser Schritt ist wichtig, wenn man mehreren Perlen in die gleiche elle verschiebt. Dann kann man jeweils die oberse Perle wieder wegnehmen
if (draggedPearl != null) Nur wenn auf eine Perle geklickt wird, wird die gewünschte Aktion ausgeführt. Da ein Mausklick neben die Perlen keinen Actor zurückgibt, ist diese Abfrage vor der nächsten Aktion notwendig
Point mousePos =
     new Point(mouse.getX(), mouse.getY());
     draggedPearl.setPixelLocation(mousePos);
Folgt den Mauszeiger und verschiebt die gewählte Perle

case GGMouse.lRelease:
     draggedPearl.setLocationOffset(new Point(0, 0));
     draggedPearl = null;

Beim Loslassen der linken Maustaste wird die Perle in der Mitte der Zelle positioniert. Die Variable draggedPearl wird auf null gesetzt, damit eine neue Perle gewählt werden kann


Beispiel 3: Mit Mausklick können die Zündhölzer entfernt werden, wobei der Klick in einem beliebigen Teil des Zündholzes erfolgen kann.

Auch in diesem Beispiel wird mit Vorteil der GGMouseTouchListener verwendet. Nicht die Gitterzellen, sondern die Sprite-Bilder legen die interaktiven Stellen fest.

 
// JGameEx25.java

import ch.aplu.jgamegrid.*;
import java.awt.*;

public class JGameEx25 extends GameGrid implements GGMouseTouchListener
{

  private int nbMatches = 20;


  public JGameEx25()
  {
    super(600, 120, 1, false);
    setTitle("Remove matches");
    for (int = 0; i < nbMatches; i++)
    {
      Actor match = new Actor("sprites/match.gif");
      addActor(match, new Location(12 + 30 * i, 60));
      match.addMouseTouchListener(thisGGMouse.lPress);
    }
    show();
    doRun();   
  }

  public void mouseTouched(Actor actor, GGMouse mouse, Point pix)
  {
    actor.removeSelf();
    nbMatches--;
    setTitle("Remove matches. " + nbMatches + " matches remaining.");
  }

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

Programmcode für lokale Bearbeitung downloaden: JGameEx25.zip

Erklärungen zum Programmcode:

addActor(match, new Location(12 + 30 * i, 60))
match.addMouseTouchListener(this, GGMouse.lPress)

Positioniert die Zündhölzer in einem Pixelgrid.
Registriert bei jedem Zündholz den MouseTouchListener
void mouseTouched()
actor.removeSelf()
Callbackmethode des MouseTouchlisteners
Der mit Mausberührte Actor wird entfernt
nbMatches-- Anzahl der verbliebenen Zündhölzer wird in der Titelleiste angezeigt