Zu Beginn des Spieles bauen die beiden Spieler eine Bluetooth-Verbindung auf. Der erste Computer (Bluetooth Server) wartet in einem blockierenden Zusatnd (Waiting as Server) bis am zweiten Computer (Bluetooth Client) der Bluetooth-Name des Servers eingegeben wurde. Der Client startet das Spiel. |
Das Spiel besteht aus 8 Kartenpaare. Die Rückseiten der Karten sind grau. Der aktive Spieler kehrt jeweils mit einem Mausklick zwei Karten um. Wenn sie gleich sind, erhält er 1 Punkt und kann noch einmal spielen, sonst kommt der zweite Spieler zu Zug. Wer am Schluss mehr Punkte hat, gewinnt. Das "Ein-Spieler"-Memory (Benutzer gegen Computer) finden Sie im Menü "Gitter-Games" - "Memory".
|
Programmcode:
// BtMemory.java import javax.swing.JOptionPane; import ch.aplu.bluetooth.BluetoothPeer; import ch.aplu.bluetooth.BtPeerListener; import ch.aplu.jgamegrid.*; import ch.aplu.util.Monitor; public class BtMemory extends GameGrid implements GGMouseListener, BtPeerListener, GGExitListener { private boolean isReady = true; private MemoryCard card1; private MemoryCard card2; private int pairs; private int enemyPairs; private BluetoothPeer bp; private boolean isMyMove; private int[] sit; // Game situation public BtMemory() { super(4, 4, 115, null, null, false); sit = new int[17]; sit[0] = -1; isMyMove = false; MemoryCard[] cards = new MemoryCard[16]; for (int i = 0; i < 16; i++) { if (i < 8) cards[i] = new MemoryCard(i); else cards[i] = new MemoryCard(i - 8); cards[i].show(1); addActor(cards[i], getRandomEmptyLocation()); int pos = cards[i].getY() * 4 + cards[i].getX(); sit[pos + 1] = cards[i].getId(); } show(); doRun(); connect(); addExitListener(this); addMouseListener(this, GGMouse.lPress); // Application thread used to flip back cards while (true) { Monitor.putSleep(); // Wait until there is something to do delay(1000); card1.show(1); // Flip cards back card2.show(1); isReady = true; setMouseEnabled(true); // Rearm mouse events } } private void makeSit(int[] sit) { removeAllActors(); for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { int id = sit[x + (y * 4) + 1]; MemoryCard card = new MemoryCard(id); card.show(1); addActor(card, new Location(x, y)); } } } public boolean mouseEvent(GGMouse mouse) { Location location = toLocation(mouse.getX(), mouse.getY()); MemoryCard card = (MemoryCard)getOneActorAt(location); if (card.getIdVisible() == 0 || !isMyMove) // Card already flipped or // not my turn ->no action return true; card.show(0); // Show picture int[] data = new int[1]; if (isReady) { card1 = card; sendCard(-4, card); isReady = false; } else { card2 = card; if (card1.getId() == card2.getId()) // Pair found, let them visible { sendCard(-2, card); bp.sendDataBlock(data); pairs++; setTitle("Your Points: " + pairs + " Opponent: " + enemyPairs + " Play!"); checkWinLose(); isReady = true; } else { isMyMove = false; sendCard(-3, card); bp.sendDataBlock(data); setTitle("Your Points: " + pairs + " Opponent: " + enemyPairs + " Wait!"); setMouseEnabled(false); // Disable mouse events until // application thread flipped back cards Monitor.wakeUp(); } } return true; } private void sendCard(int state, Actor card) { int[] data = new int[3]; data[0] = state; data[1] = card.getX(); data[2] = card.getY(); bp.sendDataBlock(data); } private void checkWinLose() { if (pairs + enemyPairs == 8) { if (pairs == enemyPairs) setTitle("Tie!"); if (pairs > enemyPairs) setTitle("You win!"); else setTitle("You lose!"); } } public void connect() { String serverName; String prompt = "Enter Bluetooth Name"; do { serverName = JOptionPane.showInputDialog(null, prompt, ""); if (serverName == null) System.exit(0); } while (serverName.trim().length() == 0); setTitle("Connecting to " + serverName); bp = new BluetoothPeer(serverName, "GGmemory", this, true); if (bp.isConnected()) { setTitle("Client connected, it is you to play"); bp.sendDataBlock(sit); isMyMove = true; // Client has first move } else setTitle("Waiting as server"); } public void notifyConnection(boolean connected) { System.out.println("Notify " + (connected ? "connected" : "connection lost")); if (connected) { setTitle("Server connected, wait to play"); } } public void receiveDataBlock(int[] data) { switch (data[0]) { case -1: makeSit(data); break; case -2: enemyPairs++; card1 = (MemoryCard)getOneActorAt(new Location(data[1], data[2])); card1.show(0); setTitle("Your Points: " + pairs + " Opponent: " + enemyPairs + " Wait!"); checkWinLose(); break; case -3: card2 = (MemoryCard)getOneActorAt(new Location(data[1], data[2])); card2.show(0); setMouseEnabled(false); // Disable mouse events until // application thread flipped back cards Monitor.wakeUp(); isMyMove = true; setTitle("Your Points: " + pairs + " Opponent: " + enemyPairs + " Play!"); break; case -4: System.out.println("received card info >.<"); card1 = (MemoryCard)getOneActorAt(new Location(data[1], data[2])); card1.show(0); refresh(); break; } } public boolean notifyExit() { bp.releaseConnection(); return true; } public static void main(String[] args) { new BtMemory(); } } //----------------class Memorycard ---------------- class MemoryCard extends Actor { private int id; public MemoryCard(int id) { super("sprites/card" + id + ".gif", "sprites/cardback.gif"); this.id = id; } public int getId() { return id; } } |
Erklärungen zum Programmcode:
int[] sit | Im Array sit[] wird die Spielsituation gespeichert, damit sie dem Bluetooth-Partner übergeben werden kann. Die erste Stelle des Arrays sit[0] hat den Wert -1 und kennzeichnet das verschickte Paket als Spielsituation. Die Id der ersten Karte (oben links) wird als a[1], ... die Ide der letzten Karte als a[16] gespeichert |
makeSit(int[] sit) | Stellt nach jeder Datenübergabe die aktuelle Spielsituation dar. In jeder Gitterzelle wird eine Karte mit Id gemäss dem Wert von sit[i] |
void sendCard(int state, Actor card) |
Bei jeder Spieler-Aktion werden die Koordinaten der umgedrehten Karte und ihr Status verschickt |
void receiveDataBlock(int[] data) | Empfang der Daten: Wir müssen vier verschiedene Fälle unterscheiden, die aus dem ersten Wert data[0] ersichtlich sind: |