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

Machen eines Match-3-Spiel in Construct 2: Eliminieren der vorgefertigten Matches

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: Block Movement
Make a Match-3 Game in Construct 2: Chaining and Game Overs

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

Im vorherigen Tutorial haben wir endlich unser Spiel in Bewegung gebracht und unseren Blöcken Bewegung hinzugefügt. Darüber hinaus haben wir ein rudimentäres Schwierigkeitsgradsystem entwickelt, um das Spiel zu erschweren, wenn der Spieler länger spielt.

Mit diesen beiden Funktionen im Spiel sind wir bereit, das System zu implementieren, das vorgefertigte Übereinstimmungen vom Spielfeld entfernt. Obwohl dies nicht der letzte Artikel in der Reihe ist, ist dies das letzte wichtige System, das wir implementieren müssen. Machen Sie es sich also bequem, denn wir haben unsere Arbeit für uns ausgeschnitten.


Finale Spiel-Demo

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


Schnellkorrekturen

Bevor wir mit dem Hauptteil dieses Tutorials beginnen, möchte ich mir eine Minute Zeit nehmen, um zwei Probleme zu beheben, die ich beim Schreiben des vorherigen Tutorials entdeckt habe.

Matching

Das erste Problem, auf das ich mich beziehe, taucht in dem Szenario auf, das Sie unten sehen können:

IssueV1

Wenn Sie in dieser Situation Block B auf den grünen Punkt ziehen, sollte er aufgrund der leeren Stellen unter dem Punkt fallen und schließlich an der mit C gekennzeichneten Stelle landen. In den meisten Szenarien geschieht dies und das Spiel funktioniert normal, aber In einigen Szenarien erkennt das Spiel stattdessen eine Übereinstimmung in dem kurzen Moment, in dem sich Block B neben Gruppe A befindet, und zerstört am Ende alle drei Blöcke.

Dieses Problem betrifft nicht nur das oben beschriebene Szenario und kann sich auch zeigen, wenn Sie dasselbe in dem unten hervorgehobenen Szenario tun.

IssueV2

Wenn wir dies nicht beheben, erhält der Spieler Guthaben und Punkte für eine Reihe von Spielen, die er nie beabsichtigt hatte, und könnte auch verwirrt sein, warum so viele Blöcke unerwartet verschwinden.

Zum Glück ist dies jedoch ein einfach zu behebendes Problem. Um dieses Problem zu lösen, erstellen wir eine neue globale Variable namens MatchesPossible, die bestimmt, ob Matches hergestellt werden können, und ein neues Ereignis, das erkennt, wenn ein Block "fällt", und MatchesPossible so ändert, dass keine Matches möglich sind gemacht werden, während dies geschieht.

Zuerst erstellen wir die globale Variable:

Ihre neue Variable sollte folgendermaßen aussehen:

Match3_Part7_MatchesPossibleMatch3_Part7_MatchesPossibleMatch3_Part7_MatchesPossible

Jetzt werden wir das Event erstellen, auf das gewartet wird, wenn ein Block fällt:

Dieses Event bewirkt, dass MatchesPossible auf 1 gesetzt wird, wenn festgestellt wird, dass ein Block einen leeren Bereich darunter hat, was bedeutet, dass keine Matches möglich sind. Sie werden auch feststellen, dass die Y-Position des Blocks überprüft wird. Dies soll sicherstellen, dass sich der Block nicht in der untersten Blockreihe befindet, unter der sich immer ein leerer Raum befindet.

Als nächstes benötigen wir ein Event, das MKatchesPossible auf 0 zurücksetzt, wenn keine Blöcke einen leeren Raum darunter haben. Dieses zweite Event basiert auf einer anderen Bedingung:

Stellen Sie sicher, dass dieses Events unmittelbar auf das erste Event folgt, damit die Else-Anweisung korrekt verwendet wird.

Ihre beiden neuen Events sollten folgendermaßen aussehen:

Match3_Part7_MatchesPossibleEventMatch3_Part7_MatchesPossibleEventMatch3_Part7_MatchesPossibleEvent

Schließlich werden wir CheckMatches eine neue Bedingung hinzufügen, damit MatchesPossible überprüft, ob ein Match hergestellt werden kann. Fügen Sie diese Bedingung zum ersten Funktionsaufruf des CheckMatches-Events hinzu.

Mit der hinzugefügten Bedingung sollte Ihr CheckMatches-Ereignis nun folgendermaßen aussehen:

Match3_Part7_ModifiedCheckMatchesMatch3_Part7_ModifiedCheckMatchesMatch3_Part7_ModifiedCheckMatches

Im Gegensatz zu den meisten Problemen, auf die wir bisher gestoßen sind, tritt dieses Problem auf einer ziemlich inkonsistenten Basis auf. Dies bedeutet, dass wir nicht wirklich testen können, ob wir das Problem behoben haben. Wir können nur testen, ob wir andere Probleme verursacht haben. Wenn Sie das Spiel jetzt spielen, sollten Sie feststellen, dass durch diesen Zustand keine neuen Probleme verursacht wurden.

Punkte

Das zweite Problem, das ich beheben wollte, bevor wir etwas Neues hinzufügen, betrifft das Punktesystem.

Während ich an dem Projekt für dieses Tutorial arbeitete, bemerkte ich, dass etwas, das ich getan habe, dazu führte, dass sich das Punktesystem seltsam verhielt und dem Spieler vier- oder fünfmal so viele Punkte gab, wie er für jedes Spiel bekommen sollte. Obwohl ich nicht feststellen konnte, welche Änderung dies verursachte, stellte ich fest, dass die Ursache des Problems darin bestand, dass die GivePoints-Funktion tatsächlich mehrmals aufgerufen wurde, da die Blöcke nicht sofort zerstört wurden. Zum Glück kann dies wie unser letztes Problem leicht behoben werden.

Um dies zu beheben, werden wir eine neue Variable erstellen, die dem System mitteilt, ob es Punkte geben kann. Wenn wir dann die GivePoints-Funktion verwenden, ändern wir auch die Variable, um sicherzustellen, dass das Ereignis nur einmal ausgelöst wird. Sobald die Punkte vergeben wurden, werden wir die Variable noch einmal ändern, damit es beim nächsten Versuch, Punkte zu geben, kein Problem gibt.

Erstellen Sie zunächst eine globale Variable mit dem Namen PointsGiven:

Ihre Variable sollte folgendermaßen aussehen:

Match3_Part7_PointsGiven

Als nächstes ändern wir den Teil der FindMatches-Funktion, der die Punkte tatsächlich angibt, indem wir eine neue Bedingung und zwei neue Aktionen hinzufügen.

Fügen Sie nun diese Aktion am Anfang der Aktionsliste hinzu:

Fügen Sie diese Aktion schließlich am Ende der Aktionsliste hinzu:

Das Event sollte nun so aussehen:

Match3_Part7_ModifiedIsMatchedMatch3_Part7_ModifiedIsMatchedMatch3_Part7_ModifiedIsMatched

Mit diesen Änderungen haben wir es so gemacht, dass das Ereignis, das GivePoints aufruft, nur ausgeführt wird, wenn die Variable PointsGiven 0 ist. Da wir den Wert beim Starten des Ereignisses sofort auf 1 setzen, wird verhindert, dass das Ereignis mehr als einmal ausgelöst wird, und dies wird sichergestellt Der Spieler erhält die richtige Anzahl von Punkten.

Wenn Sie das Spiel zu diesem Zeitpunkt ausführen, sollten Sie für jedes Spiel, das Sie durchführen, die richtige Anzahl von Punkten erhalten, auch wenn Sie dieses Problem zunächst nicht hatten.


Eliminieren der vorgefertigten Matches

Nachdem wir diese Korrekturen aus dem Weg geräumt haben, können wir mit dem Erstellen des Systems fortfahren, das Matches beseitigt, die vom System erzeugt werden, wenn den von ihm erstellten Blöcken zufällig Farben zugewiesen werden.

Das Problem, das wir jetzt haben, ist, dass es nicht ungewöhnlich ist, dass Sie das Spiel starten und sehen, dass sofort eine Reihe von Matches erzielt werden, da die Blockfarben völlig zufällig sind. Dies ist ein Problem, da dies die ersten Sekunden des Spiels für jemanden, der noch nie zuvor gespielt hat, sehr verwirrend machen kann und weil es den Spielern Punkte gibt, die sie nicht verdient haben.

Um das Problem zu lösen, erstellen wir eine Funktion, die jeden Block untersucht und dann überprüft, ob dieser Block dieselbe Farbe wie einer seiner Nachbarn hat. Wenn es dieselbe Farbe wie eines seiner Nachbarn hat, ändert es weiterhin die Farbe dieses Blocks, bis es nicht mehr mit einem der ihn umgebenden Blöcke übereinstimmt.

Damit dieses System funktioniert, müssen wir auch mehrere Unterstützungsfunktionen und Ereignisse erstellen und dem Block-Objekt eine neue Instanzvariable hinzufügen.

Damit es funktioniert

Erstellen Sie zunächst eine neue Instanzvariable für das Block-Objekt:

Diese Variable wird verwendet, um einen Block leicht zu identifizieren, damit wir einige der Funktionen, die wir erstellen werden, genau angeben können, welchen Block wir betrachten möchten, unabhängig von seiner Position.

Bevor wir fortfahren, müssen wir auch diese Variable verwenden. Gehen Sie zum Ereignis Am Anfang des Layouts, das die Blöcke erstellt, und fügen Sie vor der Aktion, die NumBlocks erhöht, eine neue Aktion hinzu:

Ihr Block-Spawning-Event sollte nun folgendermaßen aussehen:

Match3_Part7_ModifiedBlockSpawningMatch3_Part7_ModifiedBlockSpawningMatch3_Part7_ModifiedBlockSpawning

Als nächstes müssen wir eine Funktion erstellen, die die X- und Y-Position eines Blocks einnimmt und uns sagt, welche Farbe dieser Block hat:

Die Funktion sollte nach Abschluss folgendermaßen aussehen:

Match3_Part7_GetBlockColorMatch3_Part7_GetBlockColorMatch3_Part7_GetBlockColor

Jetzt, da wir eine Funktion haben, die uns die Farbe eines Blocks mitteilen kann, werden wir die Funktion erstellen, die einen Block tatsächlich betrachtet und feststellt, ob er benachbarte Blöcke hat, die dieselbe Farbe haben.

Die Funktionsweise dieser Funktion ist recht einfach.

  • Zuerst übergeben wir eine BlockID an die Funktion.
  • Wenn derzeit ein Block mit dieser BlockID vorhanden ist, überprüft die Funktion die vier benachbarten Blöcke und ermittelt, ob der betrachtete Block dieselbe Farbe wie einer seiner Nachbarn hat.
  • Wenn festgestellt wird, dass es einen Nachbarn mit derselben Farbe gibt, ändert sich die Farbe des Blocks, den es betrachtet, und die Farbe wird so lange geändert, bis der Block eine andere Farbe als alle seine Nachbarn hat.

Bevor wir dieses Event durchführen können, müssen wir eine neue globale Variable erstellen. In der Funktion verwenden wir eine While-Schleife, um zu bestimmen, ob die Farbe des Blocks geändert werden muss. Die Variable, die wir erstellen möchten, ist die Variable, mit der die While-Schleife bestimmt, ob sie weiter ausgeführt werden muss:

Tipp: Das Event, das wir erstellen werden, enthält ein Or-basiertes Event. Wenn Sie noch nie einen Ereignisblock mit einem Or-Attribut erstellt haben, müssen Sie den Event-Block nur wie gewohnt erstellen. Klicken Sie dann mit der rechten Maustaste auf den gesamten Block und wählen Sie "Oder"-Block erstellen. Im Gegensatz zu einem Standard-Ereignisblock, bei dem alle Bedingungen erfüllt sein müssen, bevor er ausgelöst wird, wird ein Or-Block ausgelöst, wenn eine Bedingung erfüllt ist.

Machen wir also das Event:

Ihr Event sollte folgendermaßen aussehen:

Match3_Part7_RemoveSpawnedMatches_FixedMatch3_Part7_RemoveSpawnedMatches_FixedMatch3_Part7_RemoveSpawnedMatches_Fixed

Wie funktioniert diese Funktion genau?

Als erstes wird nach einem Block mit der BlockID gesucht, die das System übergeben hat. Wenn es diesen Block findet, setzt es den Wert von HasMatchingNeighbors auf 1 und führt dann die While-Schleife aus.

Da die While-Schleife nur ausgeführt wird, wenn HasMatchingNeighbors 1 ist, ist dies der Wert, auf den sie festgelegt wird. Während der While-Schleife wird geprüft, ob sich links, rechts, oben oder unten ein benachbarter Block befindet, der dieselbe Farbe hat wie der Block, den wir betrachten. Wenn an einer dieser Positionen ein passender Block gefunden wird, weist er dem Block zufällig eine neue Farbe zu und führt den Test erneut aus, indem sichergestellt wird, dass HasMatchingNeighbors auf 1 gesetzt ist. Wenn schließlich eine Farbe für den Block gefunden wird, die keiner entspricht von seinen Nachbarn ändert es den Wert von HasMatchingNeighbors auf 0, so dass die While-Schleife endet und das Programm fortgesetzt werden kann.

Jetzt müssen wir diese Funktion in das Spiel implementieren. Dazu müssen wir zwei neue Variablen und zwei neue Funktionen erstellen. Beginnen wir mit den Variablen.

Ihre Variablen sollten folgendermaßen aussehen:

Match3_Part7_CheckMatchesVariables

Die beiden Variablen, die wir gerade erstellt haben, werden verwendet, um die beiden Events auszulösen, die wir erstellen möchten. Die Events selbst werden verwendet, um die Blöcke unmittelbar nach ihrer Erstellung zu durchlaufen und jeden Block an die Funktion RemoveSpawnedMatches zu senden.

Der Grund, warum wir die Funktion RemoveSpawnedMatches nicht unmittelbar nach dem Erstellen des Blocks aufrufen, liegt darin, dass das Blockraster vollständig sein muss, damit die Funktion ordnungsgemäß funktioniert. Anstatt die Funktion nur direkt aufzurufen, wenn Blöcke erstellt werden, lösen wir stattdessen ein Event aus, das die Blöcke durchlaufen und die Funktion nach dem Generieren des Rasters selbstständig aufrufen kann.

Das erste Event dient speziell zum Durchlaufen der ersten Gruppe von Blöcken:

So sollte Ihr Event aussehen:

Match3_Part7_CheckStartingMatchesMatch3_Part7_CheckStartingMatchesMatch3_Part7_CheckStartingMatches

Das zweite Event dient speziell zum Überprüfen neuer Blockreihen, wenn diese erstellt werden:

So sollte das zweite Event aussehen:

Match3_Part7_CheckNewestRowMatch3_Part7_CheckNewestRowMatch3_Part7_CheckNewestRow

Implementierung

Mit diesen beiden Funktionen müssen wir sie nur noch implementieren. Wechseln Sie zu dem ersten Event, aus dem die Blöcke bestehen, dem Event Beim Start des Layouts. Wir werden diesem ein Unterereignis hinzufügen, das das CheckStartingMatches-Ereignis anweist, aktiviert zu werden.

Ihr Event sollte nun folgendermaßen aussehen:

Match3_Part7_ModifiedStartofLayoutMatch3_Part7_ModifiedStartofLayoutMatch3_Part7_ModifiedStartofLayout

Dieses Unterereignis überwacht, wann die verschachtelte For-Schleife beendet wurde, und ändert dann den Wert der CheckStartingMatches-Variablen, um das entsprechende Event zu aktivieren.

Wir werden jetzt fast das gleiche Unterereignis erstellen und es an die SpawnNewBlocks-Funktion anhängen.

SpawnNewBlocks sollten jetzt so aussehen:

Match3_Part7_MdifiedSpawnNewBlocksMatch3_Part7_MdifiedSpawnNewBlocksMatch3_Part7_MdifiedSpawnNewBlocks

Dieses Unterereignis macht dasselbe wie das vorherige, außer dass es das andere von uns erstellte Ereignis aktiviert. Wenn Sie das Spiel zu diesem Zeitpunkt ausführen, sollten Sie feststellen, dass beim Starten des Spiels keine Übereinstimmungen mehr automatisch stattfinden.


Abschluss

In diesem Tutorial haben wir nicht zu viele Änderungen am Spiel vorgenommen, aber die, die wir vorgenommen haben, waren sehr wichtig.

An diesem Punkt denke ich, dass es für uns am besten ist, vorerst anzuhalten und die letzten beiden Spielelemente für das nächste Tutorial zu speichern, in dem wir Ketten / Combos und den Game Over-Bildschirm behandeln. Dies wird der letzte Teil der Serie sein, daher werde ich auch über einige Spielmechaniken sprechen, die wir in diesen Tutorials nicht behandeln werden, und Ihnen einige Ratschläge geben, wie Sie diese Systeme selbst herstellen können.

Wenn Sie sich einen Vorsprung beim Inhalt der nächsten Woche verschaffen möchten, sollten Sie sich überlegen, wie Sie anhand der Position oder Höhe einiger Blöcke erkennen können, wann der Bildschirm "Game Over" angezeigt werden soll. Alternativ können Sie darüber nachdenken, wie Sie erkennen können, wann der Spieler eine Kettenreaktion ausführt, bei der sich mehr als eine Gruppe bildet.

Was auch immer Sie tun, ich hoffe, Sie nächste Woche wieder hier zu sehen, um den letzten Teil der Serie zu sehen.

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.