Fünfzehn oder fünfzehn ist ein großartiges Beispiel für ein einfaches Logikspiel, das auf der ganzen Welt beliebt ist. Um das Rätsel zu lösen, müssen Sie die Quadrate mit Zahlen in der Reihenfolge von kleiner bis größer anordnen. Es ist nicht einfach, aber interessant.
Im heutigen Tutorial zeigen wir, wie man mit Eclipse Fifteen in Java 8 entwickelt. Zur Entwicklung der Benutzeroberfläche verwenden wir die Swing-API.
Wir erinnern Sie daran: Für alle Leser von „Habr“ - ein Rabatt von 10.000 Rubel bei der Anmeldung für einen Skillbox-Kurs mit dem Promo-Code „Habr“.
Skillbox empfiehlt: Der Online-Schulungskurs "Profession Java-Entwickler" .
Spieldesign
In dieser Phase müssen Sie die Eigenschaften definieren:
- Größe - die Größe des Spielfelds;
- nbTiles - Die Anzahl der Punkte im Feld. nbTiles = Größe * Größe - 1;
- Tiles ist ein Tag, bei dem es sich um ein eindimensionales Array von Ganzzahlen handelt. Jedes Tag erhält einen eindeutigen Wert im Bereich [0, nbTiles]. Null bezeichnet ein leeres Quadrat;
- blankPos - Position des leeren Quadrats.
Spielelogik
Sie müssen eine Rücksetzmethode definieren, mit der eine neue Spielposition initialisiert wird. Also setzen wir den Wert für jedes Element des Tag-Arrays. Nun, dann setzen wir blankPos an die letzte Position des Arrays.
Sie benötigen auch die Shuffle-Methode, um ein Array von Tags zu mischen. Wir nehmen kein leeres Tag in den Mischvorgang auf, um es an seiner früheren Position zu belassen.
Da nur die Hälfte der möglichen Startpositionen des Puzzles eine Lösung hat, müssen Sie das resultierende Mischungsergebnis überprüfen, um sicherzustellen, dass das aktuelle Layout im Allgemeinen gelöst ist. Dazu definieren wir die isSolvable-Methode.
Wenn einem bestimmten Tag ein Tag mit einem höheren Wert vorangestellt ist, wird dies als Inversion betrachtet. Wenn das leere Tag vorhanden ist, muss die Anzahl der Inversionen gerade sein, damit das Rätsel lösbar ist. Wir zählen also die Anzahl der Inversionen und geben true zurück, wenn die Anzahl gerade ist.
Dann ist es wichtig, die isSolved-Methode zu definieren, um zu überprüfen, ob unsere Ausrichtung von Game Of Fifteen gelöst ist. Zuerst schauen wir uns an, wo sich das leere Tag befindet. In der Ausgangsposition ist die aktuelle Ausrichtung eine neue, die zuvor noch nicht festgelegt wurde. Dann iterieren wir in umgekehrter Reihenfolge über die Kacheln. Wenn der Tag-Wert vom entsprechenden + 1-Index abweicht, geben Sie false zurück. Andernfalls ist es an der Zeit, am Ende der Methode true zurückzugeben, da das Rätsel bereits gelöst wurde.
Eine andere zu definierende Methode ist newGame. Es ist erforderlich, eine neue Instanz des Spiels zu erstellen. Dazu setzen wir das Spielfeld zurück, mischen es dann und fahren fort, bis die Spielposition auflösbar ist.
Hier ist ein Beispielcode mit Schlüssel-Tag-Logik:
private void newGame() { do { reset();
Schließlich müssen Sie die Bewegung der Punkte im Array programmieren. Dieser Code wird später über einen Rückruf aufgerufen, um auf die Cursorbewegung zu reagieren. Unser Spiel unterstützt mehrere Kachelbewegungen gleichzeitig. Nachdem wir die gedrückte Position auf dem Bildschirm in ein Tag umgewandelt haben, erhalten wir die Position eines leeren Tags und suchen nach der Bewegungsrichtung, um mehrere seiner Bewegungen gleichzeitig zu unterstützen.
Hier ist ein Beispielcode:
Wir entwickeln eine Benutzeroberfläche für die Swing-API
Es ist Zeit, die Schnittstelle zu machen. Zuerst nehmen wir an der Jpanel-Klasse teil. Dann zeichnen wir Punkte auf dem Spielfeld - um die Größe der einzelnen Punkte zu berechnen, verwenden wir die Daten, die im Konstruktorparameter des Spiels angegeben sind:
gridSize = (dim - 2 * margin); tileSize = gridSize / size;
Margin ist auch ein im Spielkonstruktor angegebener Parameter.
Jetzt müssen Sie die drawGrid-Methode definieren, um das Raster und die Punkte auf dem Bildschirm zu zeichnen. Wir analysieren das Array von Tags und konvertieren die Koordinaten in die Koordinaten der Benutzeroberfläche. Zeichnen Sie dann jedes Tag mit der entsprechenden Nummer in der Mitte:
private void drawGrid(Graphics2D g) { for (int i = 0; i < tiles.length; i++) {
Schließlich definieren wir die paintComponent-Methode neu, die eine Ableitung der JPane-Klasse ist. Dann verwenden wir die drawGrid-Methode und danach verwenden wir die drawStartMessage-Methode, um eine Meldung anzuzeigen, die uns auffordert, zu klicken, um das Spiel zu starten:
private void drawStartMessage(Graphics2D g) { if (gameOver) { g.setFont(getFont().deriveFont(Font.BOLD, 18)); g.setColor(FOREGROUND_COLOR); String s = "Click to start new game"; g.drawString(s, (getWidth() - g.getFontMetrics().stringWidth(s)) / 2, getHeight() - margin); } } private void drawCenteredString(Graphics2D g, String s, int x, int y) {
Wir reagieren auf Benutzeraktionen in der Benutzeroberfläche
Damit das Spiel seinen Lauf nimmt, müssen Benutzeraktionen in der Benutzeroberfläche verarbeitet werden. Fügen Sie dazu die MouseListener-Implementierung auf dem Jpanel und den Code zum Verschieben der oben bereits gezeigten Spots hinzu:
addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) {
Wir platzieren den Code im Konstruktor der GameOfFifteen-Klasse. Ganz am Ende rufen wir die newGame-Methode auf, um ein neues Spiel zu starten.
Vollständiger Spielcode
Der letzte Schritt, bevor Sie das Spiel in Aktion sehen, besteht darin, alle Codeelemente zusammen zu sammeln. Hier ist das Ergebnis:
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities;
Endlich spielen!
Es ist Zeit, das Spiel zu starten und es in Aktion zu überprüfen. Das Feld sollte folgendermaßen aussehen:

Der Versuch, das Rätsel zu lösen. Wenn alles gut gegangen ist, bekommen wir folgendes:

Das ist alles. Hast du mehr erwartet? :) :)
Skillbox empfiehlt: