Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. From Scratch

Machen eines Match-3-Spiels in Construct 2: Match-Erkennung

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Make a Match-3 Game in Construct 2.
Make a Match-3 Game in Construct 2: Animations and Block Swapping
Make a Match-3 Game in Construct 2: Points, Matching, and Gravity

German (Deutsch) translation by Władysław Łucyszyn (you can also view the original English article)

Bisher wurden in dieser Serie die Grundlagen zum Einrichten eines Match-3-Spiels und zum Implementieren der anfänglichen Gameplay-Elemente wie Block-Swapping behandelt. In diesem Tutorial werden wir darauf aufbauen und feststellen, wann der Spieler ein Match gemacht hat.


Finale Spiel-Demo

Hier ist eine Demo des Spiels, auf das wir in dieser Serie hinarbeiten:


1. Erkennen eines Matches

Im Moment werden wir nur eine Basisversion des Matching-Systems implementieren, wobei wir uns darauf konzentrieren, herauszufinden, wann Matches vorhanden sind, und übereinstimmende Blöcke zerstören. In späteren Artikeln werden wir das System weiterentwickeln und weiterentwickeln.

Tipp: Sie sollten lesen, wie eine rekursive Funktion funktioniert, wenn Sie es noch nicht wissen. Im Wesentlichen ist es eine Funktion, die sich selbst aufruft. Rekursive Funktionen können ähnlich wie Schleifen funktionieren, aber da sie auch Variablen aufnehmen und zurückgeben können, haben sie viel mehr Verwendungsmöglichkeiten als Schleifen.

Wie im vorherigen Tutorial möchte ich zunächst die Funktionsweise des Systems erläutern und dann versuchen, es zu erstellen.

  • Das Match-System durchläuft jede Instanz des Block-Objekts.
  • Für jeden Block wird die Farbe und Position des Blocks, den er betrachtet, in eine rekursive Funktion übergeben, die den horizontalen oder vertikalen Nachbarn betrachtet und feststellt, ob sie dieselbe Farbe haben.
  • Wenn ein Match gefunden wird, wird die Funktion erneut mit der Position und Farbe des neuen Blocks und nicht mit dem ursprünglichen Block aufgerufen.
  • Dies wird fortgesetzt, bis kein Match mehr gefunden wird. Zu diesem Zeitpunkt wird überprüft, wie viele Matches gefunden wurden.
  • Wenn drei oder mehr Matches gefunden wurden, werden alle Blöcke markiert Matched, die gerade als mit der IsMatched-Instanzvariablen übereinstimmend angesehen wurden, die wir in einem der vorherigen Tutorials erstellt haben. sonst macht es nichts.
  • Sobald alle Blöcke überprüft wurden, zerstört die Funktion jeden Block, der als Match markiert ist.

Zunächst benötigen wir ein Event, das jeden Block durchlaufen kann. So wie ich das System aufgebaut habe, durchläuft es die Blöcke tatsächlich zweimal: einmal, um nach vertikalen Matches zu suchen, und einmal, um nach horizontalen Matches zu suchen. Abhängig davon, welche Prüfung durchgeführt wird, wird eine andere Funktion verwendet, um tatsächlich nach dem Match zu suchen.

Das allererste, was wir tun müssen, ist eine globale Variable zu erstellen, um zu verfolgen, wie viele übereinstimmende Blöcke wir in einer bestimmten Iteration gefunden haben:

Lassen Sie uns nun das Event erstellen, das die Blöcke durchläuft:

Ihr Code sollte folgendermaßen aussehen:

Match3_Part3_FindMatchesMatch3_Part3_FindMatchesMatch3_Part3_FindMatches

In diesem Fall durchlaufen wir jeden Block und senden sie an CheckMatchesX oder CheckMatchesY, die Funktionen, die prüfen, ob der benachbarte Block übereinstimmt.

Um den Block in die Funktion zu senden, übergeben wir den Funktionen drei verschiedene Parameter:

  • Parameter 0 ist die X-Position des Blocks
  • Parameter 1 ist die Y-Position des Blocks
  • Parameter 2 ist die Farbe.

Nachdem jeder Block an eine der Funktionen gesendet wurde und die Ausführung der Funktion beendet ist, überprüft er NumMatchesFound, um festzustellen, ob drei oder mehr übereinstimmende Blöcke gefunden wurden, und kennzeichnet die Blöcke dann als Matched, falls dies der Fall ist.

Schließlich wird jeder Block, der als Matched markiert ist, nach Ablauf von 0,1 Sekunden zerstört. Diese wait-Anweisung dient dazu, dem Spiel zu ermöglichen, die Bilder für die Blöcke auf das Bild umzustellen, das angibt, dass sie übereinstimmen, und dem Spieler einen Moment Zeit zu geben, um diese Änderung zu bemerken.

(Während Sie die wait-Anweisung entfernen können, ohne das Gameplay negativ zu beeinflussen, erleichtert dies dem Spieler das Verständnis und verlangsamt das Spiel gerade so weit, dass der Spieler leicht verfolgen kann, was gerade passiert.)


2. Die zwei Prüffunktionen

Als nächstes müssen wir die Funktionen CheckMatchesX und CheckMatchesY ausführen. Diese Funktionen funktionieren ähnlich wie die obigen Iteratoren, da es eine Version zum Überprüfen horizontaler Matches, CheckMatchesX, und eine für vertikale Matches, CheckMatchesY, gibt.

Horizontale Prüfungen

Lassen Sie uns zunächst die horizontale Überprüfungsfunktion erstellen:

Ihr Code sollte folgendermaßen aussehen:

Match3_Part3_CheckMatchesXMatch3_Part3_CheckMatchesXMatch3_Part3_CheckMatchesX

Was macht diese Funktion?

  • Zunächst wird geprüft, ob links von dem Block, den wir übergeben haben, überhaupt ein benachbarter Block vorhanden ist.
  • Sobald die Funktion bestätigt, dass sich am benachbarten Speicherort ein Block befindet, prüft sie, ob er dieselbe Farbe wie der Block hat, den wir übergeben haben.
  • Wenn dies der Fall ist, wird NumMatchesFound um eins erhöht und der neu gefundene Block wird wie beim Original an die Funktion übergeben.
  • Dies wird fortgesetzt, bis ein Block gefunden wird, der nicht die gleiche Farbe wie das Original hat. Zu diesem Zeitpunkt wird überprüft, ob genügend übereinstimmende Blöcke gefunden wurden, um eine Gruppe zu erstellen, und die Blöcke werden als Matches gekennzeichnet, wenn dies der Fall ist.

Vertikale Überprüfungen

Lassen Sie uns nun eine andere Version dieser Funktion erstellen, die dasselbe für vertikale Matches tut. Dies wird unsere CheckMatchesY-Funktion sein. Sie können entweder die ursprüngliche Funktion kopieren und alle entsprechenden Änderungen vornehmen oder sie einfach von Grund auf neu erstellen. In beiden Fällen sollte Ihre Funktion nach Abschluss folgendermaßen aussehen:

Ihr Code sollte folgendermaßen aussehen:

Match3_Part3_CheckMatchesYMatch3_Part3_CheckMatchesYMatch3_Part3_CheckMatchesY

3. Eigentlich nach Checks suchen

Schließlich müssen wir die FindMatches-Funktion tatsächlich aufrufen. Gehen Sie zur SwapBlocks-Funktion und fügen Sie am Ende der Funktion ein neues Unterevent hinzu:

Sie werden feststellen, dass dieses Unterevent keine Bedingungen hat. Wenn Sie noch nie ein Unterevent wie dieses erstellt haben, erstellen Sie einfach ein Untererevent mit einer beliebigen Bedingung, da Sie beim Erstellen eines Untererevents eine Bedingung angeben und löschen Sie dann die Bedingung, lassen Sie aber das Untererevent stehen. Auf diese Weise stellen Sie sicher, dass das Unterevent immer ausgeführt wird.

Ihr SwapBlocks-Event sollte jetzt folgendermaßen aussehen:

Match3_Part3_SwapBlocksMatch3_Part3_SwapBlocksMatch3_Part3_SwapBlocks

Wenn Sie das Spiel zu diesem Zeitpunkt ausführen, werden Sie feststellen, dass die Blöcke bei Matches zerstört werden. Sie werden jedoch auch feststellen, dass alle Matches, die zu Beginn des Spiels vorhanden sind, erst verschwinden, wenn Sie einen Tausch durchführen. Dies liegt daran, dass wir die FindMatches-Funktion niemals aufrufen, nachdem wir das Blockraster erstellt haben.

Der Grund, warum wir diesen Code nicht hinzugefügt haben, ist, dass es in der endgültigen Version eine weitere Funktion gibt, die verhindert, dass Matches wie diese automatisch generiert werden. Es gibt also wirklich keinen Grund, sich über dieses Problem Gedanken zu machen. (Wenn Sie möchten, können Sie die FindMatches-Funktion auch früher aufrufen.)


4. Konsolidierung der Checks

Zu diesem Zeitpunkt haben wir ein ziemlich starkes Matching-System, aber das Problem ist, dass unser Code redundant ist. Derzeit haben wir zwei verschiedene Funktionen, die prüfen, ob es einen passenden Nachbarn gibt, und der einzige Unterschied zwischen ihnen besteht darin, dass eine vertikal und die andere horizontal prüft.

Da die kostenlose Version von Construct 2 die Anzahl der Events begrenzt, ist dies definitiv eine Verschwendung. Um dies zu lösen, werden wir eine neue Version der Funktion erstellen, die beide Überprüfungen durchführen kann.

Wenn Sie sich die Funktion ansehen, werden Sie feststellen, dass der einzige Unterschied zwischen den beiden Versionen darin besteht, dass eine Block.Width + 2 zur x-Position des Blocks und die andere zur y-Position des Bock hinzufügt. Das Hindernis, das wir überwinden müssen, um dies zu einer einzelnen Funktion zu machen, besteht darin, der Funktion die Möglichkeit zu geben, Block.Width + 2 nur zu X oder nur zu Y hinzuzufügen, ohne eine If-Anweisung oder mehrere Funktionen zu verwenden, da diese mehr erfordern Auszuführende Events.

Meine Lösung hierfür ist nicht sehr komplex, aber es wird einfacher zu verstehen sein, wenn wir sehen, dass es zusammenkommt, also werden wir es implementieren und ich werde erklären, wie es funktioniert, sobald wir alles in Aktion sehen können.

  1. Löschen Sie das CheckMatchesY-Event.
  2. Benennen Sie das CheckMatchesX-Event einfach in CheckMatches um.
  3. Im Funktionsaufruf für CheckMatchesX unter dem FindMatches-Event:
    1. Ändern Sie den Funktionsaufruf für CheckMatches anstelle von CheckMatchesX.
    2. Parameter 3 hinzufügen.
      1. Wert = 1.
    3. Parameter 4 hinzufügen.
      1. Wert = 0.
  4. Im Funktionsaufruf für CheckMatchesY unter dem FindMatches-Event:
    1. Ändern Sie den Funktionsaufruf für CheckMatches anstelle von CheckMatchesY.
    2. Parameter 3 hinzufügen.
      1. Wert = 0.
    3. Parameter 4 hinzufügen.
      1. Wert = 1.

Wie ich bald erläutern werde, teilen diese hinzugefügten Parameter CheckMatches mit, ob eine horizontale oder eine vertikale Prüfung durchgeführt wird. Wenn wir 1 für Parameter 3 und 0 für Parameter 4 einsenden, handelt es sich um eine horizontale Prüfung, und wenn wir 0 für Parameter 3 und 1 für Parameter 4 einsenden, handelt es sich um eine vertikale Prüfung.

Kehren Sie nun zur CheckMatches-Funktion zurück und ändern Sie die Bedingungen und Aktionen so, dass sie folgendermaßen aussehen:

So sollte Ihr FindMatches- und CheckMatches-Code jetzt aussehen:

Match3_Part3_ModifiedCheckMatchesMatch3_Part3_ModifiedCheckMatchesMatch3_Part3_ModifiedCheckMatches

Wie funktioniert das?

Was macht diese neue Version der Funktion eigentlich?

Nun, wenn Sie CheckMatches aufrufen, senden Sie jetzt zwei weitere Parameter und anstatt Block.Width + 2 entweder zur x- oder zur y-Position hinzuzufügen, wird (Block.Width + 2) * Function.Param(3) hinzugefügt ) zur x-Position und (Block.Width + 2) * Function.Param(4) zur y-Position.

Da einer dieser beiden Parameter immer 1 und der andere immer 0 ist, bedeutet dies, dass entweder die x- oder die y-Position geändert wird - niemals beide!

Wenn wir zum Beispiel 1 für Parameter 3 und 0 für Parameter 4 übergeben, addiert es (Block.Width + 2) * 1, was einfach Block.Width + 2 ist, zur x-Position und (Block.Width + 2) * 0, also 0, zur y-Position.

Hier ist ein kurzes Beispiel, um zu zeigen, was ich meine und wie die Position des Blocks berechnet wird, an dem nach Matches gesucht wird. Angenommen, in diesem Beispiel befindet sich der ursprüngliche Block bei (200, 200) und die Blöcke haben eine Breite von 40. Wenn wir also die Position des benachbarten vertikalen Blocks ermitteln möchten, würden die Formeln folgendermaßen funktionieren:

  • X = 200 + ((Block.Width + 2)*0) = 200 + (40 + 2)*0 = 200 + 0 = 200
  • Y = 200 + ((Block.Width + 2)*1) = 200 + (40 + 2)*1 = 200 + 42 = 242

Wenn wir die Position des benachbarten horizontalen Blocks erhalten wollten, würden die Formeln folgendermaßen funktionieren:

  • X = 200 + ((Block.Width + 2)*1) = 200 + (40 + 2)*1 = 200 + 42 = 242
  • Y = 200 + ((Block.Width + 2)*0) = 200 + (40 + 2)*0 = 200 + 0 = 200

Wenn Sie das Spiel jetzt ausführen, sollten Sie sehen, dass das Match-System immer noch so funktioniert, wie es ursprünglich war, aber aus unserer Sicht ist es tatsächlich ein besseres System.


Abschluss

Zu diesem Zeitpunkt ist unsere Match-Erkennungsfunktion noch unvollständig, aber wir haben bereits viel in diesem Tutorial getan, und ich denke, es ist wichtig, all dies zu berücksichtigen, bevor wir etwas anderes hinzufügen. In diesem Sinne werde ich diesen Artikel hier beenden. Schauen Sie sich die Demo in ihrer aktuellen Form an.

Im nächsten Artikel werden wir ein Punktesystem hinzufügen, das Matching-System verbessern und "Schwerkraft" hinzufügen, so dass die Blöcke fallen, wenn Blöcke darunter entfernt werden.

Wenn Sie sich einen Vorsprung für den nächsten Artikel verschaffen möchten, nehmen Sie sich etwas Zeit, um zu überlegen, wie Sie erkennen würden, wenn sich unter einem Block ein leerer Bereich befindet. Schauen Sie sich die Funktion Block > Is Overlapping at Offset, um sich inspirieren zu lassen!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.