Spielprogrammierung mit Java
HomeAufgabenDruckenJava-Online

Maus-Events

Die Maus-Events werden mit Hilfe des Interfaces CardListener registriert. Im Interface CardLister sind folgende Callbackmethoden deklariert:

  • atTarget()
  • leftPressed()
  • leftReleased()
  • leftClicked()
  • leftDoubleClicked()
 
  • rightPressed()
  • rightReleased()
  • rightClicked()
  • rightDoubleClicked()

Zur Vereinfachung der Programmierung geben diese Callbackmethoden eine Referenz auf die entsprechende Karte zurück. Um die Maus für eine bestimmte Hand zu aktivieren, ist der Aufruf der Methode hand.setTouchEnabled(true) erforderlich.
Beim RowLayot, ColumnLayou und FanLayot wird mit einem linken Mausklick die gewählte Karten in den Vordergrund gebracht und die Hand so dargestellt, dass alle Karten erkennbar sind.

1. Karten mit Mausklick in den Vordergrund bringen

Beispiel 1: Mit dem linken Mausklick auf den sichtbaren Teil einer Karte wird die Karte in den Vordergrund verschoben und die Hand neu dargestellt.

 

 

Programmcode downloaden (CardGameEx5.zip)

Programmcode:

// CardGameEx5.java

import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;

public class CardGameEx5 extends CardGame
{
  public enum Suit
  {
    KREUZ, KARO, HERZ, PIK
  }

  public enum Rank
  {
    ASS, KOENIG, DAME, BUBE, ZEHN, NEUN, ACHT, SIEBEN, SECHS
  }

  private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");

  public CardGameEx5()
  {
    super(600, 600, 30);
    setStatusText("Click on a card ");
    Hand hand = deck.dealingOut(1, 12, true)[0];
    RowLayout rowLayout = new RowLayout(new Location(300, 200), 500);
    hand.setView(thisrowLayout);
    hand.sort(Hand.SortType.RANKPRIORITY, true);
    hand.draw();
    hand.setTouchEnabled(true);
  }

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

Erklärungen zum unten stehenden Programmcode:
hand.setTouchEnabled(true) Aktiviert die Mausevents einer Hand. Beim linken Mausklick auf eine Karte, wird diese Karte in den Vordergrund verschoben

 

2. Karten mit Mausklick von einer Hand in die andere verschieben

Beispiel 2: Mit einem linken Doppelklick kann eine beliebige Karte aus einer Hand zur anderen Hand verschoben werden.

Mit den Callbackmethoden leftDoubleClicked() und atTarget() lassen sich Kartentransaktionen sehr konfortabel programmieren. Die Callbackmetode leftDoubleClicked() ist so implementiert, dass die betrefende Karte in die andere Hand verschoben wird. Dabei wird auch die Methode leftClicked() beim einfachen Klick auf eine Karte automatisch aufgerufen und bringt die gewählte Karte in den Vordergrund.

Die Callbackmethode atTarget() wird aufgerufen, wenn eine Karte am Zielort ankommt. In der Regel wird diese Methode verwendet, um die Karten einer Hand zu sortieren und neu darzustellen.

 

 

 

Programmcode downloaden (CardGameEx6.zip)

Programmcode:

// CardGameEx6.java

import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;

public class CardGameEx6 extends CardGame
{
  public enum Suit
  {
    KREUZ, KARO, HERZ, PIK
  }

  public enum Rank
  {
    ASS, KOENIG, DAME, BUBE, ZEHN, NEUN, ACHT, SIEBEN, SECHS
  }
  private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
  private final int nbPlayers = 2;
  private final int nbCards = 7;
  private Hand[] hands;
  private final Location upperLocation = new Location(300, 150);
  private final Location bottomLocation = new Location(300, 450);

  public CardGameEx6()
  {
    super(600, 600, 30);
    addStatusBar(30);
    setStatusText("Left click to set on top, doubleclick to move ");
    hands = deck.dealingOut(nbPlayers, nbCards);
    hands[0].setTargetArea(new TargetArea(upperLocation));
    hands[1].setTargetArea(new TargetArea(bottomLocation));

    CardAdapter cardAdapter = new CardAdapter()
    {
      public void atTarget(Card card, Location targetLocation)
      {
        showHands();
        hands[0].sort(Hand.SortType.SUITPRIORITY, true);
        hands[1].sort(Hand.SortType.SUITPRIORITY, true);
      }

      public void leftDoubleClicked(Card card)
      {
        if (card.isInHand(hands[0]))
        {
          card.transfer(hands[1], true);
          setStatusText("Moved " + card);
          return;
        }
        if (card.isInHand(hands[1]))
        {
          card.transfer(hands[0], true);
          setStatusText("Moved " + card);
        }
      }
    };

    hands[0].addCardListener(cardAdapter);
    hands[1].addCardListener(cardAdapter);
    hands[0].setTouchEnabled(true);
    hands[1].setTouchEnabled(true);
    showHands();
  }

  private void showHands()
  {
    RowLayout rowLayout = new RowLayout(bottomLocation, 350);
    hands[0].setView(thisrowLayout);
    hands[0].draw();
    RowLayout rowLayout1 = new RowLayout(upperLocation, 350);
    hands[1].setView(thisrowLayout1);
    hands[1].draw();
  }

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

Erklärungen zum Programmcode:
hand.addCardListener(new CardAdapter())
Wenn nur wenige Callbackmethoden des CardListeners benötigt werden, ist es einfacher den CardAdapter zu verwenden
leftDoubleClicked(Card card)
Callbackmethode des CardListeners, die beim Doppelklick mit der linken Maustaste aufgerufen wird
card.isInHand(hands[0])

Gibt true zurück, wenn sich eine Karte in der hands[0] befindet

card.transfer(hands[1], true)
Verschiebt eine Karte zu der hands[1]. Der Parameter true bewirkt, dass die Hände neu dargestellt werden

atTarget(Card card, Location targetLocation)

Diese Callbackmethode wird aufgerufen, wenn eine Karte am Zielort angekommen ist

hands[0].sort(Hand.SortType.SUITPRIORITY, true)

Zeigt die Hand nach Farbe sortiert an

 

3. Kartenstapel durchblättern

Beispiel 3: Mit der Methode shift() kann ein Kartenstapel durchgeblättert werden. Der Parameter true bewirkt ein Vorwärtsblättern, false ein Rückwärtsblättern

 

Programmcode downloaden (CardGameEx7.zip)

 

 

 

Programmcode:

// CardGameEx7.java

import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;

public class CardGameEx7 extends CardGame
{
  public enum Suit
  {
    KREUZ, KARO, HERZ, PIK
  }

  public enum Rank
  {
    ASS, KOENIG, DAME, BUBE, ZEHN, NEUN, ACHT, SIEBEN, SECHS
  }
  private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
  private Hand hand;

  public CardGameEx7()
  {
    super(600, 600, 30);
    setStatusText("Click on a card ");
    hand = deck.dealingOut(0, 0, false)[0];  // Ordered
    StackLayout stackLayout = new StackLayout(new Location(300, 200));
    hand.setView(thisstackLayout);
    hand.draw();

    hand.addCardListener(new CardAdapter()
    {
      public void leftPressed(Card card)
      {
        Card top = hand.shift(truetrue);  // Shift forward
        setStatusText("On top: " + top);
      }
    });
    hand.setTouchEnabled(true);
  }

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

Erklärungen zum Programmcode:
hand = deck.dealingOut(0, 0, false)[0]
Karten im Stack sind geordnet. Alle Karten befinden sich in der Hand
shift(true, true)

Geht den Kartenstappel durch. Der erste Parameter true bedeutet forwärts blättern, der zweiter Parameter true bewirkt, dass die Hand neu dargestellt wird

 

4. Karten mit Mausklick von einem Stapel zum anderen bewegen

Beispiel 4: Der Stapel rechts ist zu Beginn leer. Mit Mausklick können die Karten vom Stapel links zum Stapel rechts bewegt werden und umgekehrt. Die Kartenstapel sich geordnet, am linken Stapel liegen die Karten umgekehrt, auf der rechten Stapel sind sie aufgedeckt.

Programmcode downloaden (CardGameEx8.zip)

 

Programmcode:

// CardGameEx8.java

import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;

public class CardGameEx8 extends CardGame
{
  public enum Suit
  {
    KREUZ, KARO, HERZ, PIK
  }

  public enum Rank
  {
    ASS, KOENIG, DAME, BUBE, ZEHN, NEUN, ACHT, SIEBEN, SECHS
  }
  private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
  private Hand[] hands;
  private final Location left = new Location(150, 300);
  private final Location right = new Location(450, 300);

  public CardGameEx8()
  {
    super(600, 600, 30);
    setStatusText("Click on a card to move it");
    hands = deck.dealingOut(1, 0, false);  // Ordered

    CardAdapter cardAdapter = new CardAdapter()
    {
      public void leftPressed(Card card)
      {
        Hand targetHand;
        card.setVerso(!card.isVerso());
        if (card.isInHand(hands[0]))
          targetHand = hands[1];
        else
          targetHand = hands[0];
        card.transfer(targetHand, true);
      }
    };

    StackLayout stackLayout1 = new StackLayout(left);
    hands[1].setView(thisstackLayout1);
    hands[1].draw();
    hands[1].setVerso(true);
    StackLayout stackLayout2 = new StackLayout(right);
    hands[0].setView(thisstackLayout2);
    hands[0].draw();

    //add listener to both hands:
    for (Hand hand : hands)
    {
      hand.addCardListener(cardAdapter);
      hand.setTouchEnabled(true);
    }
  }

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

Erklärungen zum Programmcode:
card.setVerso(!card.isVerso())
Kehrt eine Karte um

if (card.isInHand(hands[0]))
   targetHand = hands[1]
else
targetHand = hands[1]

Falls man mit der Maus auf einer Karte aus der hands[0] klick, wird hands[1] als Zielhand gesetzt und umgekehrt

 

5. Karten mit gedrückter Maustaste von einem Stapel zur Hand bewegen

Beispiel 5: Der CardListener kann mit dem GGMouseTouchListener aus JGameGrid kombiniert werden. Die Methoden des GGMouseTouchListeners (lPress, lDrag) geben zu einer mit Maus berührten Karte-Sprite einen CardActor zurück. Dieser ermöglicht es, Karten mit der gedrückten Maustaste zu verschieben.
In diesem Beispiel gibt es zwei Möglichkeiten die Karten manuell vom Talon zur Hand zu verschieben:

  • mit gedrückter Maustaste, die Karten wird am Zielort automatisch eingeordnet
  • mit einem linken Mausklick. Die Karte wird beim loslassen der Maustaste am Zielort eingeordnet

Programmcode downloaden (CardGameEx9.zip)

 

Programmcode:

// CadGameEx9.java

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

public class CardGameEx9 extends CardGame implements GGMouseTouchListener
{
  public enum Suit
  {
    KREUZ, KARO, HERZ, PIK
  }

  public enum Rank
  {
    ASS, KOENIG, DAME, BUBE, ZEHN, NEUN, ACHT, SIEBEN, SECHS
  }

  private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
  private Point hotspot = new Point(0, 0);
  private final Location talonLocation = new Location(300, 400);
  private Hand hand = new Hand(deck);
  private final Location handLocation = new Location(300, 120);
  private Card movingCard;

  public CardGameEx9()
  {
    super(600, 600);
    setStatusText("Drag cads from the stack to the hand");
    Hand[] hands = deck.dealingOut(1, 3);
    hand = hands[0];
    hands[0].setView(thisnew RowLayout(handLocation,350));
    hands[0].draw();
    hand.setTouchEnabled(true);

    final Hand talon = hands[1];
    talon.setView(thisnew StackLayout(talonLocation));
    talon.reverse(true);
    talon.addCardListener(new CardAdapter()
    {
      public void leftPressed(Card card)
      {
        talon.remove(card, true);
        movingCard = card.clone();
        add(movingCard);
      }
    });
    talon.setTouchEnabled(true);
  }

  private void add(Card card)
  {
    CardActor cardActor = card.getCardActor();
    addActor(cardActor, new Location(talonLocation));
    cardActor.addMouseTouchListener(this,
      GGMouse.lPress | GGMouse.lDrag | GGMouse.lRelease, false);
  }

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

      case GGMouse.lDrag:
        actor.setLocation(
          new Location(mouse.getX() - hotspot.x, mouse.getY() - hotspot.y));
        if (actor.getLocation().getDistanceTo(handLocation) < 100)
          putInHand(actor);
        break;

      case GGMouse.lRelease:
        putInHand(actor);
        break;
    }
  }

  private void putInHand(Actor actor)
  {
    actor.removeSelf();
    Card card = ((CardActor)actor).getCard();
    hand.insert(card, true);
    hand.sort(Hand.SortType.SUITPRIORITY, true);
  }

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

Erklärungen zum Programmcode:

movingCard = card.clone()
talon.remove(card, true)

Beim linken Mausklick auf eine Karte wird die Karte aus dem Talon entfernt. Damit wir sie danach für die Verschiebung weiter benutzen können, wird diese zur movingCard geklount
add(movingCard)

Wir deklarieren eine Methode add(), die der movingcard einen CardActor zuordnet an der Position i Talon

cardActor.addMouseTouchListener(this,
      GGMouse.lPress | GGMouse.lDrag | GGMouse.lRelease, false)
Dem CardActor wird ein TouchListener mit den Callbackmethoden lPress, lDrag und lRelease zugeordnet
case GGMouse.lDrag:
actor.setLocation(new Location(mouse.getX() - hotspot.x, mouse.getY() - hotspot.y))
Die Karte folgt den Mauszeiger