Endlich ist es soweit: Wir sind gerade mit unserem Spiel fertig und sind bereit, die endgültige Spielmechanik zu implementieren. In diesem Artikel wird ein Kombinationssystem erstellt, das dem Spieler mehr Punkte für das Erstellen von Ketten gibt, die nach nur einem Tausch mehrere Blockgruppen zerstören.
Darüber hinaus werden wir das Verlustszenario implementieren und einen Game Over-Bildschirm hinzufügen. Zum Schluss werde ich über Dinge sprechen, an denen Sie in Ihrer eigenen Zeit arbeiten können, um das Spiel über das, was wir bisher beschrieben haben, zu verbessern und zu erweitern. Also lass uns ohne weiteres loslegen…
Hier ist eine Demo des Spiels, an dem wir gearbeitet haben und das wir am Ende dieses Teils der Serie bauen werden:
Bevor wir zum Hauptartikel übergehen, möchte ich eine kleine Änderung an dem Zeitpunkt vornehmen FindMatches
wird gerufen.
Bei der Arbeit an diesem Artikel habe ich ein Problem entdeckt, das Sie unten in der GIF sehen können:
Wie Sie in diesem ersten GIF sehen können, funktioniert ein Block, der nur eine Blockdistanz fällt, um eine Übereinstimmung mit einer Gruppe von Blöcken am unteren Rand des Falls zu bilden, perfekt.
In dieser zweiten GIF wird jedoch deutlich, dass ein Block, der in demselben Szenario um eine größere Entfernung verschoben wird, die Übereinstimmung nicht erkennt, bis wir einen weiteren Swap durchführen. Der Grund dafür ist, dass das Spiel nicht oft genug nach Spielen sucht.
Momentan sucht das Spiel nur nach einem Swap nach Matches, aber aufgrund der Zeit, die ein Block benötigt, um diese Distanz zu erreichen, ist die Matcherkennung bereits beendet, wenn der Block den Boden berührt, und das Match wird erst gefunden es wird neu initiiert.
Um dies zu beheben, ändern wir, wenn wir eine FindMatches
prüfen.
Geh zuerst zum SwapBlocks
Funktion und entfernen Sie das letzte Ereignis aus der Funktion, damit es nicht aufgerufen wird FindMatches
überhaupt.
SwapBlocks
sollte jetzt so aussehen:
Zu diesem Zeitpunkt gibt es keine Ereignisaufrufe FindMatches
. Wir werden dies beheben, indem wir dem Ereignis eine neue Aktion hinzufügen, die erkennt, wann Übereinstimmungen möglich sind. Suchen Sie dieses Ereignis und fügen Sie diese Aktion am Ende des Else-Ereignisses hinzu:
Aktion: Funktion> Aufruf Funktion Name = "FindMatches"
Ihre Veranstaltung sollte jetzt so aussehen:
Nutzen Sie auch die Chance, beide zu bewegen Übereinstimmungen möglich
Ereignisse bis zum Ende des Spielcodes, falls Sie dies noch nicht getan haben. Dadurch wird sichergestellt, dass sie vor dem Code, der vorgefertigte Übereinstimmungen verhindert, überhaupt nicht aufgerufen werden.
Wenn Sie das Spiel jetzt ausführen, sollten Sie das oben dargestellte Szenario ohne Probleme ausführen können.
Nachdem das Problem behoben wurde, werden wir das implementieren Verkettung System, das dem Spieler zusätzliche Punkte für Spiele gibt, die durch die Zerstörung eines anderen Spiels verursacht wurden.
Im Folgenden sehen Sie ein Beispiel für die Art der Situation, die ich meine:
In dem obigen Szenario bewegt der Spieler den grünen Block und erstellt eine Übereinstimmung. Durch die Zerstörung der grünen Blöcke fallen dann die blauen Blöcke und bilden einen Moment später ein neues Spiel.
Ich möchte dem Spieler Bonuspunkte geben, um so etwas zu erreichen. Insbesondere möchte ich einen Multiplikator auf die Anzahl der Punkte anwenden, die der Spieler für jedes Match erhält, und den Multiplikator mit jedem aufeinanderfolgenden Match erhöhen.
Damit dieses System funktioniert, erstellen wir eine neue Variable namens Kette
, und nehmen Sie dann einige Änderungen an den vorhandenen Funktionen vor. Erstellen Sie also zuerst eine neue globale Variable:
Globale Variable: Kettentyp = Zahl Anfangswert = 0
Ihre Variable sollte so aussehen:
Diese Variable dient als Multiplikator für die Punkte, um die Dauer der Kette anzugeben.
Gehen Sie jetzt zu dem Ereignis, durch das die Blöcke fallen, und entfernen Sie das Else-Ereignis, das den Aufruf von FindMatches
Funktion.
Gehen Sie jetzt zu FindMatches
selbst und finden Sie die Standorte, an denen Sie das machen FloatingPointsText
Objekte. Ändern Sie die Set Text-Anweisungen so, dass sie eine neue Formel verwenden:
Aktion: FloatingPointsText> Text setzen Text = NumMatchesFound * 10 * Chain
Diese Änderung bewirkt, dass der Floating-Text auf dieselbe Weise geändert wird wie die Punkte selbst.
Gehen Sie als Nächstes zum Abschnitt von FindMatches
wo du anrufst FindMatches
wieder am Ende des Ereignisses, und löschen Sie diesen Funktionsaufruf und die Wait-Anweisung. Warum? Denn wenn wir diese nicht entfernt haben, dann FindMatches
Am Ende würde es zu oft aufgerufen werden, und die Ketten würden niemals korrekt initiiert.
(Aufgrund der Änderungen, die wir zuvor in diesem Artikel vorgenommen haben, FindMatches
wird aufgerufen, wenn sich alle Blöcke im Raster befinden und keine fallen. Mehrere Bereiche haben, in denen wir anrufen FindMatches
würde dazu führen, dass mehrere Instanzen der Funktion gleichzeitig ausgeführt werden, und das Punktesystem könnte durcheinander geraten.)
Zum Schluss nehmen wir noch eine Änderung an dieser Funktion vor. Gehen Sie zum Ende der Funktion und fügen Sie diese Aktion nach dem Einstellen hinzu Punkte gegeben
zu 0
:
Aktion: System> Zu Variable hinzufügen = "Kette" Wert = 1
Wann immer das Spiel Übereinstimmungen findet, gibt es dem Spieler Punkte, zerstört die Blöcke, und erhöht dann den Kettenwert.
Die neue Version von FindMatches
sollte so aussehen:
Gehen Sie als nächstes zum GivePoints
funktionieren und ändern Sie beide Aktionen, die den Wert des Scores erhöhen, sodass sie den Wert der Kette berücksichtigen:
Aktion: System> Zu Variable hinzufügen = Bewertungswert = 10 * Kette
Mit dieser Änderung, GivePoints
sollte jetzt so aussehen:
Wir haben die Variable Chain als Multiplikator für die Punkte implementiert, die der Spieler empfängt (und die Anzahl der Punkte, die in den Floating-Textobjekten angezeigt werden), aber es gibt noch eines, was wir tun müssen: Wir müssen eine Aussage hinzufügen Dadurch wird der Wert von Chain zurückgesetzt, sodass er nicht einfach unendlich zunimmt.
Wir werden diese Aussage dem hinzufügen Beim DragDrop-Start Ereignis, damit der Spieler, sobald er einen neuen Block zieht, als neue Kette betrachtet wird. Der andere Grund, warum wir es hier tun, ist, dass dadurch verhindert wird, dass der Wert der Kette vorzeitig zurückgesetzt wird, wodurch alle Übereinstimmungen im letzten Teil einer Kette weniger wertvoll sind.
Gehe zum Beim DragDrop-Start Ereignis und fügen Sie diese Aktion der Aktionsliste hinzu:
Aktion: System> Wert setzen Variable = Kettenwert = 1
Ihre Veranstaltung sollte jetzt so aussehen:
Wenn Sie das Spiel zu diesem Zeitpunkt testen, sollten Sie feststellen, dass Sie, wenn Sie eine Kette wie die zuvor in der GIF beschriebene Kette erstellen, 90 anstatt 60 Punkte erhalten.
Damit ist das Verkettungssystem vollständig und Sie sollten in der Lage sein, eine Kette so zu erstellen, wie Sie möchten, ohne Probleme.
Als nächstes möchte ich auf ein Problem eingehen, das ich mit dem Blockfallsystem gefunden habe. Wenn Sie das heutige Match-3-Spiel längere Zeit mit dem Spielen verbringen, haben Sie möglicherweise ein Problem festgestellt, bei dem ein Block ab und zu nicht fällt, obwohl kein Block darunter ist.
Sie können sehen, was ich im Bild unten meine:
Obwohl es keinen Block unter dem gelben Block gibt, ist es immer noch nicht in den leeren Raum gefallen. Dies ist ein seltenes Problem, aber wenn es nicht behandelt wird, kann es trotzdem die Punktzahl einer anderen Person durcheinander bringen und verhindern, dass sie eine von ihnen eingerichtete Kette erhalten oder sogar verlieren, wenn wir die Game Over-Funktion hinzufügen.
Die Ausgabe stammt von der Variablen BlockBeingMoved
, Dieses Ereignis wird vom Ereignis verwendet, das bestimmt, wann Blöcke fallen sollen, um sicherzustellen, dass keine Blöcke verschoben werden, wenn ein Block anweist, einen leeren Bereich zu füllen. Wenn der Spieler einen Block verschiebt, wird diese Variable in einigen Szenarien niemals zurückgesetzt, und die Blöcke fallen nicht, bis ein anderer Block verschoben wird und er korrekt zurückgesetzt wird. Um dies zu beheben, fügen wir ein Paar Ereignisse hinzu, die diese Variable korrekt setzen und zurücksetzen, und wir werden die aktuellen Aktionen entfernen, die die Variable festlegen, da sie nicht ordnungsgemäß funktionieren.
Gehen Sie zuerst zum OnDragDrop Start
und Auf DragDrop Drop
Ereignisse, und entfernen Sie alle Aktionen, die sich mit der BlockBeingMoved
Variable aus diesen Events. In jedem Ereignis sollte eine Aktion vorhanden sein, die gelöscht werden muss.
Gehen Sie als Nächstes zu dem Ereignis, bei dem ein leerer Bereich unter einem Block erkannt wird. Wir werden die Bedingungen dieser Veranstaltung ändern. Stellen Sie zunächst sicher, dass die Bedingung überprüft, ob BlockBeingMoved
entspricht 0
ist am Anfang. Fügen Sie dann am Ende des Ereignisses eine weitere Bedingung hinzu, um sicherzustellen, dass keine Blöcke verschoben werden.
Dies ist die Bedingung, die Sie hinzufügen möchten:
Bedingung: Umkehren: Blockieren> Wird gezogen
Ihre Veranstaltung sollte jetzt so aussehen:
Zum Schluss werden wir noch zwei weitere Events am Ende des Veranstaltungsblatt das wird die behandeln BlockBeingMoved
Variable. Gehen Sie bis zum Ende Ihrer Veranstaltungsblatt und füge diese Ereignisse hinzu:
Ereignis: Bedingung: Blockieren> Wird gezogen Aktion: System> Set Variablenname = BlockBeingMoved Value = 1
Ereignis: Bedingung: System> Else Aktion: System> Set Variablenname = BlockBeingMoved Value = 0
Ihre neuen Events sollten so aussehen:
Diese Ereignisse werden sich effektiv ändern BlockBeingMoved
von 0
zu 1
und von 1
zu 0
wann immer ein Block verschoben wird oder ist nicht bewegt werden. Wenn Sie das Spiel zu diesem Zeitpunkt testen, sollten Sie in der Lage sein, so oft zu spielen, wie Sie möchten, ohne dass Probleme mit dem Blockieren des Blocks auftreten.
Jetzt, da unser Verkettungssystem vorhanden ist, werden wir das Verlustszenario und einen Game Over-Bildschirm hinzufügen.
Als erstes müssen wir ein neues Layout hinzufügen, das als Game Over Screen fungiert:
-6, -7
.613, 619
.303, 200
.RestartButton
.262, 410
.100, 30
.Neustart
.Nachdem Sie nun Ihren Game Over-Bildschirm eingerichtet haben, kehren Sie zu Ihrem ursprünglichen Layout zurück, Layout 1, und fügen Sie dem Bildschirm ein neues Element hinzu:
GameOverArea
.196, -30
.344, 150
.0
.Sie sollten feststellen, dass sich dieses Sprite an derselben Position und in derselben Größe wie der obere Teil des Spielfelds befindet. Wir werden dieses Sprite-Objekt verwenden, um herauszufinden, wann der Spieler verloren hat, indem wir erkennen, wann ein Block mit ihm kollidiert. Gehe zu Veranstaltungsblatt 1 so können wir mit der Umsetzung beginnen.
Bevor wir mit dem Erkennen des Verlustszenarios beginnen, müssen wir eine neue Variable hinzufügen, mit der die Blöcke angehalten werden, wenn sie auf das Symbol klicken GameOverArea Objekt, damit sie sich nicht mehr bewegen. Dadurch wird dem Spieler klar, dass er verloren hat.
Globale Variable: MovementPossible Type = Number Initial Value = 0
Gehen Sie nun zu dem Ereignis, bei dem Sie die Blöcke verschieben, und fügen Sie folgende Bedingung hinzu:
Bedingung: System> Variable vergleichen Variable = MovementPossible Vergleich = gleich Wert = 0
Ihr Bewegungsereignis sollte jetzt so aussehen:
Nun, da die Bewegung unsere neue Variable verwendet, fügen wir das Ereignis hinzu, das die Verlustbedingung erkennt:
Ereignis: Bedingung: Blockieren> Überlappt ein anderes Objekt Objekt = GameOverArea Bedingung: Umkehren: Blockieren> IsDragging Aktion: Funktion> Aufruf Funktionsname = "Game Over"
Das Ereignis, das wir gerade gemacht haben, ruft die Game Over-Funktion auf, sobald sich ein Block überlappt GameOverArea
. Jetzt machen wir das tatsächlich Spiel ist aus
Funktion.
Ereignis: Bedingung: Funktion> Ein Funktionsname = "Game Over" Aktion: Blockieren> Aktivierten Status festlegen = Deaktiviert Aktion: System> Wert setzen Variable = MovementPossible Wert = 1 Aktion: System> Wait Seconds = 1.5 Aktion: System> Gehe zu Layout Layout = Layout 2
Ihre zwei neuen Events sollten so aussehen:
Der Grund, warum wir eine separate Funktion erstellt haben, anstatt diese Aktionen innerhalb des Ereignisses auszuführen, das das Spiel tatsächlich erkennt, ist, dass dieses Ereignis nur bestimmte Blöcke aufgrund der Ereignisse betrachtet, die es auslösen. Wie Sie in der von uns erstellten Funktion sehen können, deaktivieren wir die Ziehfunktionen des Blocks, um zu verhindern, dass der Spieler nach dem Erkennen des Spiels weitere Matches abschließt. Wenn wir dies für den Fall tun, dass das Spiel vorbei ist, werden nur die Blöcke deaktiviert, die das Spiel beendet haben, und jeder andere Block kann weiterhin gezogen werden.
Gehen Sie jetzt zu Veranstaltungsblatt 2; wir werden einige Funktionen hinzufügen RestartButton Objekt, das wir früher gemacht haben. Fügen Sie ein neues Ereignis zu hinzu Veranstaltungsblatt 2:
Ereignis: Bedingung: RestartButton> Klicken Sie auf Aktion: System> Gehe zu Layout Layout = Layout 1
Ihre Veranstaltung sollte so aussehen:
Wenn Sie das Spiel jetzt spielen, ein Spiel beenden und neu starten, sollten Sie feststellen, dass es sich wieder auf das ursprüngliche Layout bezieht, die Blöcke bewegen sich jedoch nicht. Der Grund dafür ist, dass alle Variablen, die wir verwendet haben, globale Variablen sind. Daher werden einige von ihnen nicht automatisch zurückgesetzt, wenn wir das Layout neu starten.
Um sie zurückzusetzen, müssen wir unserer Aktion eine Aktion hinzufügen Beim Start des Layouts Ereignis, das sie für uns manuell zurücksetzt.
Gehe zum Beim Start des Layouts Event und fügen Sie diese Aktion dem ursprünglichen Event hinzu, bevor die For-Schleifen aufgerufen werden:
Aktion: System> Globale Variablen zurücksetzen
Ihre Veranstaltung sollte jetzt so aussehen:
Wenn Sie erneut testen, sollten Sie dieses Problem nicht mehr haben.
An dieser Stelle haben wir alle Funktionen besprochen, die ich im Rahmen dieser Tutorials behandeln wollte.
Sie werden feststellen, dass Ihr Spiel immer noch nicht ist genau das gleiche wie in der obigen Demo, mit dem größten Unterschied, dass Ihr Spiel keinen Startbildschirm hat. Ich habe mich nicht für die Erstellung des Startbildschirms entschieden, da er fast genauso aussieht wie der Game Over-Bildschirm - ich lasse das als Übung für Sie.
Stattdessen werde ich ein paar Features besprechen, die Sie in Betracht ziehen könnten, um Ihr Spiel zu verbessern, um es besser oder interessanter zu machen.
Das erste, was ich besprechen möchte, sind Spezialblöcke - Blöcke, die dem Spieler entweder Boni geben oder eine einzigartige Funktion ausführen.
Die meisten Match-3-Spiele enthalten Spezialblöcke, die dazu beitragen, die Action zu beenden und das Spiel spannender zu gestalten. So wie es aussieht, kann das Spiel theoretisch für immer weitergehen, aber das Gameplay ändert sich nie. Durch die Einführung spezieller Blocktypen kann das Spiel nach einiger Zeit interessanter werden.
Um einen Spezialitätsblock zu integrieren, müssen Sie die Art und Weise ändern, in der Blöcke erzeugt werden. Wenn also ein Block erstellt wird, besteht eine zufällige Chance, dass er zu einem Spezialblock wird. Es gibt verschiedene Möglichkeiten, dies zu tun, aber im Allgemeinen ist es am besten, eine Zufallszahl zwischen 1 und 100 zu generieren und einen Spezialblock nur dann zu generieren, wenn der Zufallswert zwischen 95 und 100 liegt oder in einem anderen Bereich, für den Sie sich entscheiden.
Ihr Ziel sollte es sein, Spezialblöcke selten zu machen, aber nicht auch Selten. Auf diese Weise erhält der Spieler sie regelmäßig genug, um das Spiel mehr Spaß zu machen, aber nicht so oft, dass es das Gleichgewicht des Spiels zerstört.
Wenn es um Spezialblöcke geht, haben Sie viele Möglichkeiten. eine der häufigsten ist a Bombenblock.
Bombenblöcke führen dazu, dass zusätzliche Blöcke zerstört werden, wenn sie zerstört werden. Sie sind in jedem Spiel anders: In einigen Spielen zerstören sie alle Blöcke, die sie umgeben. In anderen Fällen zerstören sie eine ganze Reihe oder Spalte von Blöcken.
In der Abbildung unten sehen Sie zwei der Bombenblocktypen des beliebten Spiels Candy Crush Saga:
Bombenblöcke sind im Allgemeinen ziemlich einfach zu integrieren:
Ein anderer Spezialblocktyp, den Sie in vielen Spielen finden, ist einer, der die Geschwindigkeit der Blöcke verlangsamt oder ganz stoppt.
Blöcke wie diese sind sehr einfach herzustellen.
Bewegungen möglich
zu 1
damit die Blöcke aufhören, oder ändern Sie die Geschwindigkeit
so dass sich die Blöcke sehr langsam bewegen.Sie müssen berücksichtigen, dass der Spieler einen Time-Stop-Block aktiviert, während ein anderer Time-Stop-Block bereits aktiv ist. In diesem Szenario sollten Sie den Timer neu starten oder die Standardlänge des Timers zum vorhandenen Timer hinzufügen und normal fortfahren.
Sie können auch andere Spielmodi hinzufügen, wenn sich der Spieler vom Endlosmodus, den wir erstellt haben, langweilt.
Der einfachste Spielmodus, den Sie hinzufügen können, ist der, in dem der Spieler ein Zeitlimit hat. Ziel ist es, so viele Punkte wie möglich zu erhalten, bevor die Zeit abläuft.
In diesem Szenario würden Sie den gesamten Spielcode unberührt lassen, außer, um dem Spiel eine zweite Verlustbedingung hinzuzufügen, wodurch das Spiel endet, wenn der Timer abläuft (sowie wenn die Blöcke oben auf dem Bildschirm angezeigt werden)..
Wenn das Spiel beginnt, würden Sie einen Timer für die Dauer des Modus starten, und wenn der Timer endet, beenden Sie das Spiel auf die gleiche Weise, wie Sie es jetzt tun.
In diesem Spielemodus würden Sie dem Spieler ein sehr spezifisches Spielbrett geben, das Sie im Voraus entworfen haben, und ihn bitten, alle Blöcke in so wenigen Swaps wie möglich zu beseitigen.
(Möglicherweise möchten Sie die Blockbewegung deaktivieren, da bei einer Bewegung der Blöcke im Laufe der Zeit auch neue Blöcke hinzugefügt werden.)
Für diesen Modus müssen Sie möglicherweise ein bestimmtes Blockraster einrichten. Daher benötigen Sie ein System, mit dem Sie beim Start des Spiels ein bestimmtes Block-Setup übergeben können, anstatt eines völlig zufällig zu generieren, wie wir es jetzt tun.
Obwohl dieser Spielmodus relativ einfach zu implementieren ist, müssten Sie viel manuelles Puzzle entwerfen, damit Sie viele einzigartige Rätsel erstellen können, die der Spieler lösen und lösen kann.
Das Hinzufügen eines Spielemodus wie diesem kann aufgrund der erforderlichen Inhaltserstellung ziemlich zeitaufwändig sein, aber es gibt viele Spieler, die sich daran erfreuen würden. Es kann sich wirklich auszahlen, wenn Sie die Zeit einsetzen.
Im Verlauf dieser Tutorialserie haben wir ein komplettes Match-3-Spiel von Anfang bis Ende entwickelt. Es gibt noch viel mehr, was Sie mit diesem Spiel tun können, wenn Sie sich die Zeit nehmen und die Fantasie haben, aber es gibt auch viele Möglichkeiten, wie Sie meine Ideen einsetzen können, um Sie bei anderen Spielprojekten zu unterstützen.
Arbeiten Sie weiter an Ihrem Spiel und entdecken Sie immer wieder neue Ideen, denn Sie wissen nie, wann sich etwas, das Sie hier gelernt haben, später als nützlich erweisen wird.
Ich hoffe, dass Sie etwas davon gelernt haben, egal, ob Sie die ganze Serie durchgingen oder einfach nur zu den Parts gegangen sind, die Sie alleine nicht machen konnten. Wenn Sie irgendwelche Probleme oder Kommentare haben, lassen Sie uns in den Diskussionen unter jedem Artikel wissen - ich würde gerne von Ihnen hören und sehen, welche Wendungen Sie hinzufügen. In jedem Fall vielen Dank für das Lesen und viel Erfolg bei Ihren Spielen!