Bisher wurden in dieser Serie die Grundlagen für die Einrichtung eines Match-3-Spiels und die Implementierung der ersten Gameplay-Elemente wie Block-Swapping behandelt. In diesem Tutorial bauen wir darauf auf und beginnen zu erkennen, wann der Spieler ein Match gemacht hat.
Hier ist eine Demo des Spiels, an dem wir in dieser Serie arbeiten:
Im Moment werden wir nur eine Basisversion des Abgleichsystems implementieren, wobei wir uns darauf konzentrieren, herauszufinden, wann Übereinstimmungen vorhanden sind, und übereinstimmende Blöcke zerstören. In späteren Artikeln werden wir das System weiterentwickeln und weiterentwickeln.
Spitze: Sie sollten wissen, 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. Da sie jedoch auch Variablen aufnehmen und zurückgeben können, haben sie viel mehr Einsatzmöglichkeiten als Schleifen.
Wie beim vorherigen Tutorial möchte ich zuerst die Funktionsweise des Systems besprechen und dann versuchen, es zu erstellen.
Block
Objekt. Block
, Er übergibt die Farbe und Position des Blocks, den er betrachtet, an eine rekursive Funktion, die den horizontalen oder vertikalen Nachbarn betrachtet und bestimmt, ob sie dieselbe Farbe haben. Abgestimmt
mit dem Ist abgestimmt
Instanzvariable, die wir in einem der vorherigen Tutorials erstellt haben; sonst tut es nichts. Erstens brauchen wir ein Ereignis, das jedes durchlaufen kann Block
. So wie ich das System aufgebaut habe, durchläuft es tatsächlich die Blöcke zweimal: einmal für vertikale Übereinstimmungen und einmal für horizontale Übereinstimmungen. Abhängig von der Prüfung wird eine andere Funktion verwendet, um tatsächlich nach dem Treffer zu suchen.
Das allererste, was wir tun müssen, ist eine Globale Variable Um zu verfolgen, wie viele passende Blöcke wir in einer bestimmten Iteration gefunden haben:
Globaler Variablenname: "NumMatchesFound" Type = Number Value = 0
Jetzt machen wir das Veranstaltung das wird durch die Blöcke iterieren:
Ereignis: Funktion> Ein Funktion Name: "FindMatches" Unterereignis: System> Für jedes Objekt: Block Aktion: System> Wert setzen NumMatchesFound = 1 Aktion: Funktion> Aufruf Funktion Name: "CheckMatchesX" Parameter 0: Block.X Parameter 1 : Block.Y Parameter 2: Block.Color-Unterereignis: System> Compare Variable NumMatchesFound> = 3 Aktion: Blockieren> Set Boolean IsMatched = True Unterereignis: System> Für jedes Objekt: Block Aktion: System> Wert setzen NumMatchesFound = 1 Aktion: Funktion> Funktion aufrufen Name: "CheckMatchesY" Parameter 0: Block.X Parameter 1: Block.Y Parameter 2: Block.Color Unterereignis: System> Compare Variable NumMatchesFound> = 3 Aktion: Block> Set Boolean IsMatched = True Unterereignis: Block> Ist eine boolesche Instanzvariable festgelegt System> Wait Second = 0.1 Block> Destroy
Ihr Code sollte so aussehen:
In diesem Fall durchlaufen wir jeden Block und senden ihn in 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:
Nachdem jeder Block an eine der Funktionen gesendet wurde und die Funktion abgeschlossen ist, wird geprüft NumMatchesFound
um zu sehen, ob drei oder mehr übereinstimmende Blöcke gefunden wurden, und beschriftet die Blöcke dann mit Abgestimmt
wenn es tat.
Zum Schluss jeder Block, der als Sein markiert ist Abgestimmt
Wird nach 0,1 Sekunden zerstört. Diese warten
Eine Anweisung gibt dem Spiel die Möglichkeit, die Bilder für die Blöcke auf das Bild umzuschalten, das angibt, dass sie übereinstimmen, und dem Spieler einen Moment zu geben, um diese Änderung zu bemerken.
(Während Sie das entfernen konnten warten
Eine Aussage ohne negativen Einfluss auf das Gameplay, macht das Abgleichen für den Spieler leichter verständlich und verlangsamt das Spiel gerade so weit, dass der Spieler leicht den Überblick behalten kann.)
Als nächstes müssen wir das machen CheckMatchesX
und CheckMatchesY
Funktionen. Diese Funktionen funktionieren ähnlich wie die oben beschriebenen Iteratoren, da es eine Version gibt, um horizontale Übereinstimmungen zu überprüfen, CheckMatchesX
, und eine für vertikale Übereinstimmungen, CheckMatchesY
.
Lassen Sie uns zunächst die horizontale Überprüfungsfunktion erstellen:
Ereignis: Funktion> Ein Funktion Name: "CheckMatchesX" Unterereignis: Bedingung: Block> Compare XX = Function.Param (0) + (Block.Width + 2) Bedingung: Block> Compare YY = Function.Param (1) Bedingung : Block> Vergleiche Instanzvariable Color = Function.Param (2) Aktion: System> Zu Variable hinzufügen = NumBlocks Wert = 1 Aktion: Funktion> Funktion aufrufen Name: "CheckMatchesX" Parameter 0: Function.Param (0) + (Block. Width + 2) Parameter 1: Function.Param (1) Parameter 2: Function.Param (2) Unterereignis: System> Compare Variable NumMatchesFound> = 3 Aktion: Blockieren> Set Boolean IsMatched = True
Ihr Code sollte so aussehen:
Also, was macht diese Funktion??
NumMatchesFound
um eins, und übergibt den neu gefundenen Block genau wie beim Original an die Funktion.Lassen Sie uns nun eine andere Version dieser Funktion erstellen, die dasselbe für vertikale Übereinstimmungen tut. Das wird unser sein CheckMatchesY
Funktion. Sie können entweder die ursprüngliche Funktion kopieren und alle entsprechenden Änderungen vornehmen oder einfach von Grund auf neu erstellen. In beiden Fällen sehen Sie, wie Ihre Funktion aussehen soll, wenn sie fertig ist:
Ereignis: Funktion> Ein Funktion Name: "CheckMatchesY" Unterereignis: Bedingung: Block> Compare XX = Function.Param (0) Bedingung: Block> Compare YY = Function.Param (1) + (Block.Width + 2) Bedingung : Block> Vergleiche Instanzvariable Color = Function.Param (2) Aktion: System> Zu Variable hinzufügen = NumBlocks Wert = 1 Aktion: Funktion> Funktion aufrufen Name: "CheckMatchesY" Parameter 0: Function.Param (0) Parameter 1: Funktion .Param (1) + (Block.Width + 2) Parameter 2: Function.Param (2) Unterereignis: System> Compare Variable NumMatchesFound> = 3 Aktion: Blockieren> Set Boolean IsMatched = True
Ihr Code sollte so aussehen:
Zum Schluss müssen wir das tatsächlich anrufen FindMatches
Funktion. Gehe zum SwapBlocks
Funktion und fügen Sie am Ende der Funktion ein neues Unterereignis hinzu:
Ereignis: Funktion> Unterereignis: Aktion: Funktion> Funktion aufrufen Name: "FindMatches"
Sie werden feststellen, dass dieses Unterereignis keine Bedingungen hat. Wenn Sie noch nie ein Unterereignis wie dieses gemacht haben, erstellen Sie einfach ein Unterereignis mit einer beliebigen Bedingung, da Sie bei der Erstellung eines Unterereignisses eine Bedingung angeben und die Bedingung dann löschen müssen Unterereignis Auf diese Weise stellen Sie sicher, dass das Unterereignis immer ausgeführt wird.
Ihre SwapBlocks
Die Veranstaltung sollte jetzt so aussehen:
Wenn Sie das Spiel zu diesem Zeitpunkt ausführen, werden Sie feststellen, dass die Blöcke bei Spielen zerstört werden. Sie werden auch bemerken, dass alle Matches, die zu Spielbeginn vorhanden sind, nicht verschwinden, bis Sie einen Tausch vornehmen. Das ist so, weil wir niemals das nennen FindMatches
Funktion, 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 Übereinstimmungen wie diese automatisch generiert werden. Es gibt also wirklich keinen Grund, sich um dieses Problem zu sorgen. (Aber bitte rufen Sie uns an FindMatches
Funktion früher, wenn Sie möchten.)
Zu diesem Zeitpunkt haben wir ein ziemlich starkes Abgleichsystem, aber das Problem ist, dass unser Code überflüssig ist. Derzeit haben wir zwei verschiedene Funktionen, die prüfen, ob es einen passenden Nachbarn gibt, und der einzige Unterschied besteht darin, dass eine vertikal und die andere horizontal geprüft wird.
Da die kostenlose Version von Construct 2 die Anzahl der möglichen Events begrenzt, ist dies definitiv eine Verschwendung. Um dies zu lösen, erstellen wir eine neue Version der Funktion, die beide Prüfungen durchführen kann.
Wenn Sie die Funktion betrachten, werden Sie feststellen, dass der einzige Unterschied zwischen den beiden Versionen darin besteht, dass eine hinzugefügt wird Block.Width + 2
an die x-Position des Blocks und der andere fügt ihn der y-Position des Bocks hinzu. Das Hindernis, an dem wir vorbeikommen müssen, um diese Funktion zu einer einzigen Funktion zu machen, gibt der Funktion also die Möglichkeit, sie hinzuzufügen Block.Width + 2
nur zu X
, oder nur Y
, ohne mit einem Ob
Anweisung oder mehrere Funktionen, da dazu mehr Ereignisse ausgeführt werden müssen.
Meine Lösung dafür ist nicht sehr komplex, aber es wird leichter zu verstehen sein, wenn wir sehen, dass es zusammenkommt. Wir werden es implementieren und ich werde erklären, wie es funktioniert, sobald wir alles in Aktion sehen können.
CheckMatchesY
Veranstaltung.CheckMatchesX
Veranstaltung einfach, CheckMatches
.CheckMatchesX
unter dem FindMatches
Veranstaltung: CheckMatches
anstatt CheckMatchesX
.Parameter 3
. 1
.Parameter 4.
0
.CheckMatchesY
unter dem FindMatches
Veranstaltung: CheckMatches
anstatt CheckMatchesY
.Parameter 3
. 0
.Parameter 4
. 1
.Wie ich bald erklären werde, werden diese zusätzlichen Parameter sagen CheckMatches
ob es sich um eine horizontale oder vertikale Prüfung handelt. Wenn wir reinschicken 1
zum Parameter 3
, und 0
zum Parameter 4
, Es ist ein horizontaler Check, und wenn wir einsenden 0
zum Parameter 3
, und 1
zum Parameter 4
, es ist eine vertikale Kontrolle.
Gehen Sie jetzt zurück zum CheckMatches
funktionieren und ändern Sie die Bedingungen und Aktionen so, dass sie folgendermaßen aussehen:
Ereignis: Funktion> Ein Funktion Name: "CheckMatches" Unterereignis: Bedingung: Block> Compare XX = Function.Param (0) + ((Block.Width + 2) * Function.Param (3)) Bedingung: Block> Compare YY = Function.Param (1) + ((Block.Width + 2) * Function.Param (4)) Bedingung: Block> Instanzvariable vergleichen Color = Function.Param (2) Action: Block> Set Boolean IsMatched = True Action : Funktion> Funktion aufrufen Name: "CheckMatches" Parameter 0: Function.Param (0) + ((Block.Width + 2) * Function.Param (3)) Parameter 1: Function.Param (1) + ((Block. Width + 2) * Function.Param (4)) Parameter 2: Function.Param (2) Parameter 3: Function.Param (3) Parameter 4: Function.Param (4) Unterereignis: System> Compare Variable NumMatchesFound> = 3 Aktion: Blockieren> Set Boolean IsMatched = True
Das ist was dein FindMatches
und CheckMatches
Code sollte jetzt so aussehen:
Also, was macht diese neue Version der Funktion tatsächlich??
Nun, wann immer Sie anrufen CheckMatches
Sie senden jetzt zwei weitere Parameter und fügen nicht mehr hinzu Block.Width + 2
entweder zur x- oder zur y-Position, wird addiert (Block.Width + 2) * Function.Param (3)
zur x-Position und (Block.Width + 2) * Function.Param (4)
in die y-Position.
Da wird einer dieser beiden Parameter immer sein 1
, und der andere wird immer sein 0
, Dies bedeutet, dass entweder die x- oder die y-Position geändert wird - niemals beide!
Zum Beispiel, wenn wir reinkommen 1
zum Parameter 3
, und 0
zum Parameter 4
, dann fügt es hinzu (Block.Breite + 2) * 1
, das ist einfach Block.Width + 2
, zur x-Position und (Block.Breite + 2) * 0
, welches ist 0
, in die y-Position.
Hier ist ein schnelles Beispiel, um zu zeigen, was ich meine und wie es die Position des Blocks berechnet, an der er die Übereinstimmung prüfen wird. Nehmen wir an, in diesem Beispiel befindet sich der ursprüngliche Block (200, 200)
, und die Blöcke haben eine Breite von 40
. Wenn wir also die Position des benachbarten vertikalen Blocks ermitteln wollen, würden die Formeln folgendermaßen aussehen:
X = 200 + ((Blockbreite + 2) * 0) = 200 + (40 + 2) * 0 = 200 + 0 = 200
Y = 200 + ((Blockbreite + 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 aussehen:
X = 200 + ((Blockbreite + 2) * 1) = 200 + (40 + 2) * 1 = 200 + 42 = 242
Y = 200 + ((Blockbreite + 2) * 0) = 200 + (40 + 2) * 0 = 200 + 0 = 200
Wenn Sie das Spiel jetzt ausführen, sollte das Spielsystem immer noch so funktionieren, wie es ursprünglich funktioniert hat, aber aus unserer Sicht ist es tatsächlich ein besseres System.
Zu diesem Zeitpunkt ist unsere Übereinstimmungserkennungsfunktion noch unvollständig, aber wir haben in diesem Lernprogramm bereits eine Menge getan und ich denke, es ist wichtig, all das einzusinken, bevor wir etwas 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, damit die Blöcke fallen, wenn Blöcke unter ihnen eliminiert werden.
Wenn Sie sich einen Überblick über den nächsten Artikel verschaffen möchten, sollten Sie sich überlegen, wie Sie feststellen würden, wenn sich unter einem Block ein Leerzeichen befindet. Schauen Sie sich das an Block> Überlappt sich beim Offset
Funktion für die Inspiration!