7 days of WordPress themes, graphics & videos - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Game Development
  2. From Scratch

Machen Sie ein Match-3-Spiel in Konstrukt 2: Bewegung blockieren

Scroll to top
Read Time: 16 mins
This post is part of a series called Make a Match-3 Game in Construct 2.
Make a Match-3 Game in Construct 2: More Swapping, Points, and Matching
Make a Match-3 Game in Construct 2: Eliminating Pre-Made Matches

German (Deutsch) translation by Nikol Angelowa (you can also view the original English article)

Im vorherigen Teil dieser Serie haben wir einige kleine, aber wichtige Änderungen an vielen der Systeme vorgenommen, die wir für unser Match-3-Spiel entwickelt haben. Nachdem diese Verbesserungen implementiert sind, werden wir jetzt wieder auf den richtigen Weg kommen und eines der letzten beiden großen Systeme für das Spiel implementieren: das Blockbewegungssystem.

Dieses Tutorial führt Sie durch die gesamte Entwicklung des Systems, das es den Blöcken ermöglicht, bis zum oberen Rand des Bildschirms aufzusteigen, und behandelt auch die Erstellung aller kleineren Systeme, die wir zur Unterstützung des Bewegungssystems implementieren müssen. Die Themen, die ich in diesem Tutorial behandle, sind zwar nicht zu komplex, aber es gibt viel zu besprechen - also kommen wir dazu.


Finale Spieldemo

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


1. Blöcke nach oben verschieben

Bevor wir mit dem Verschieben der Blöcke beginnen, müssen wir eine kleine Änderung an den Ereignissen vornehmen, die die Blöcke hervorbringen. Gehen Sie zum Ereignis System > Beim Start des Layouts und ändern Sie die Y for-Schleife von 0 auf 3, anstatt wie ursprünglich von 0 auf 7 zu gehen.

Die Veranstaltung sollte nun so aussehen:

ModifiedStartingBlockSpawnModifiedStartingBlockSpawnModifiedStartingBlockSpawn

Der Grund für diese Änderung ist, dass das Spiel mit weniger Blöcken auf dem Bildschirm beginnt, damit es nicht so schnell endet, wenn wir im nächsten Tutorial ein Game Over hinzufügen.

Als nächstes erstellen wir eine Variable, die die Geschwindigkeit der Blöcke darstellt:

Jetzt erstellen wir das Ereignis, das die Blöcke tatsächlich bewegt:

Die Veranstaltung sollte so aussehen:

Match3_Part6_BlockMovementEvent1Match3_Part6_BlockMovementEvent1Match3_Part6_BlockMovementEvent1

Wenn Sie das Spiel nach dem Hinzufügen dieses Ereignisses ausführen, sollten Sie als erstes sehen, dass die Blöcke aufgrund der Schwerkraft fallen, die wir in einem früheren Tutorial implementiert haben. Danach sollten die Blöcke langsam steigen, bis sie sich in ihrer ursprünglichen Position befinden, und dann wieder fallen. Dies wird sich unendlich wiederholen, solange Sie nichts mit den Blöcken tun.

Dies geschieht, weil sich die Blöcke über den Punkt hinaus bewegen, an dem die Schwerkraft eintreten soll, und sie entdecken, dass sich keine Blöcke unter ihnen befinden, wodurch sie alle fallen. Dies ist zwar ein Problem, aber nicht das erste, das ich mir ansehen möchte.


2. Austausch reparieren Swa

Führen Sie das Spiel aus und versuchen Sie, einen Tausch durchzuführen. Wenn Sie dies tun, sollten Sie sehen, dass die Blöcke hintereinander stecken bleiben, in Positionen stecken bleiben, die nicht mit dem Raster ausgerichtet sind, und sich im Allgemeinen schlecht benehmen. Es gibt zwei Gründe für dieses Problem.

Das erste Problem ist, dass wir, obwohl wir die Blöcke selbst verschieben, die Objekte LeftBlock, RightBlock, TopBlock und BottomBlock nicht mit ihnen verschieben, was bedeutet, dass die Blöcke, die Sie zum Erkennen von Swaps verwenden, sich nicht mit dem Blockraster bewegen - sie sitzen nur in der Position, auf die sie eingestellt sind, wenn Sie zum ersten Mal einen Block aufnehmen.

Wenn Sie also versuchen, einen Swap durchzuführen, werden die Blöcke verschoben, da sich die Swap-Erkennungsblöcke überhaupt nicht an das Raster angepasst haben. (Dies ist auch der Grund für das zweite Problem, das wir haben, nämlich dass wir auch die Positionen, die wir im BlockPositions-Array gespeichert haben, nicht ändern.)

Das folgende GIF zeigt dieses Problem:

UnmovingSwapBlocks

Wie Sie im GIF sehen können, bewegen sich die Swap-Erkennungsblöcke nicht, obwohl die Blöcke selbst es sind.

Um diese beiden Probleme zu lösen, fügen wir dem gerade erstellten Ereignis einige weitere Aktionen hinzu:

Das Event sollte nun so aussehen:

Match3_Part6_BlockMovementEvent2Match3_Part6_BlockMovementEvent2Match3_Part6_BlockMovementEvent2

Die ersten vier Aktionen, die wir gerade hinzugefügt haben, passen die Positionen der LeftBlock-, TopBlock-, RightBlock- und BottomBlock-Objekte so an, dass sie im Blockraster bleiben. Die zweiten beiden Events passen die Y-Werte, die wir im BlockPositions-Array gespeichert haben, so an, dass sie auch im Blockraster bleiben.

Wenn Sie das Spiel an dieser Stelle noch einmal testen, sollte das Tauschen größtenteils behoben sein.

An dieser Stelle gibt es noch ein weiteres Problem, mit dem wir uns befassen müssen, damit das Swapping korrekt funktioniert. Führen Sie das Spiel aus und versuchen Sie, mit einem der Blöcke in der unteren Reihe nach unten zu tauschen, während sich diese Reihe teilweise unter dem unteren Bereich des Spielfelds befindet:

Match3_Part6_BlocksBehindFieldMatch3_Part6_BlocksBehindFieldMatch3_Part6_BlocksBehindField
Machen Sie den Tausch, während sich die Blöcke hinter der Grenze befinden, wie die hervorgehobenen im Bild oben.

Wenn Sie dies richtig gemacht haben, sollten Sie sehen, dass nichts passiert ist und die Blöcke nicht vertauscht wurden. Wenn Sie zu lange gewartet haben, haben sich die Blöcke möglicherweise vertauscht, weil sie sich wieder über die Grenze des Spielfelds bewegt haben. Wenn dies passiert ist, versuchen Sie es erneut, sobald sie fallen, und Sie sollten dieses Problem sehen.

Dieses Problem ist ziemlich einfach zu lösen und zu verstehen. Wenn Sie sich den Code für Abwärts-Swaps ansehen, sollten Sie das Event finden, das wir im vorherigen Tutorial hinzugefügt haben und das den Spieler daran hindert, Abwärts-Swaps durchzuführen, die dazu führen, dass der Block vom unteren Rand des Spielfelds fällt. Da diese Anweisung den Spieler daran hindert, nach unten zu tauschen, wenn das BottomBlock-Objekt niedriger als die anfängliche Y-Position des Blocks ist, verhindert sie, dass die Blöcke getauscht werden, wenn sie gefallen sind, und ermöglicht es Ihnen nur, erneut zu tauschen, wenn sie sich über ihre ursprüngliche Position hinaus bewegt haben nochmal.

Um diese Aussage zu korrigieren, werden wir eine kleine Änderung an der Bedingung vornehmen:

Die Bedingung sollte nun so aussehen:

Match3_Part6_ModifiedBottomSwapMatch3_Part6_ModifiedBottomSwapMatch3_Part6_ModifiedBottomSwap

Diese Modifikation bedeutet, dass ein Abwärts-Swap nur stattfinden kann, während das BottomBlock-Objekt höchstens einen halben Block unter der Y-Position ist, in der die Blöcke beginnen. Dies bedeutet auch, dass, sobald wir beginnen, neue Blockreihen zu erzeugen und sie von auf den Bildschirm zu schieben unten können diese Blöcke erst dann auf diese Weise getauscht werden, wenn mindestens die Hälfte des Blocks sichtbar ist.

Wir werden auch alle unsere Tausch-Events mit einer ähnlichen Einschränkung versehen, um sicherzustellen, dass alle gleichzeitig verwendet werden können und ein Block erst dann getauscht werden kann, wenn mindestens die Hälfte davon sichtbar ist. Auch dies wird uns helfen, wenn wir das System integrieren, das neue Blockreihen erzeugt. Dazu fügen wir jedem der verbleibenden drei Swap-Ereignisse eine neue Bedingung hinzu.

Die Bedingungen, die wir hinzufügen, sind genau die gleichen wie die, die wir gerade im BottomBlock-Ereignis geändert haben, außer dass sie auf die TopBlock-, RightBlock- und LeftBlock-Objekte anstelle des BottomBlock-Objekts verweisen, je nachdem, in welchem Ereignis es sich befindet.

Die neue Bedingung für das TopBlock Event sollte lauten:

Die neue Bedingung für das LeftBlock Event sollte lauten:

Die neue Bedingung für das RightBlock Event sollte lauten:

Ihr gesamtes On DragDrop-Drop-Event sollte nun so aussehen:

Match3_Part6_ModifiedDragDropEventMatch3_Part6_ModifiedDragDropEventMatch3_Part6_ModifiedDragDropEvent

Mit diesen neuen Bedingungen haben wir unsere Austauschmechanik korrigiert und haben damit begonnen, die bestehenden Systeme für das nächste System vorzubereiten, das wir hinzufügen: dasjenige, das neue Blockreihen hervorbringen wird.


3. Mehr Blöcke hervorbringen

Da sich die Blöcke nun mit konstanter Geschwindigkeit nach oben bewegen, müssen wir die neuen Blockreihen zum richtigen Zeitpunkt erscheinen lassen und dem Spieler erlauben, so lange weiterzuspielen, wie er möchte. Wir werden eine Funktion verwenden, um die neuen Blockreihen zu erzeugen, und wir werden ein Ereignis verwenden, das erkennt, wenn die Blöcke mit SPAWNY inline sind, um diese Funktion auszulösen.

Lassen Sie uns also zuerst die Funktion selbst erstellen.

Ihr neues Event sollte so aussehen:

Match3_Part6_SpawnNewBlocksMatch3_Part6_SpawnNewBlocksMatch3_Part6_SpawnNewBlocks

Wenn diese Funktion verwendet wird, erstellt diese Funktion eine Reihe von Blöcken unter der untersten Reihe von Blöcken im Spielfeld. Wie es jetzt aussieht, verwenden wir diese Funktion jedoch zu keinem Zeitpunkt, also machen wir das Ereignis, das dies tut:

Ihr neues Event sollte so aussehen:

Match3_Part6_CallSpawnNewBlocksMatch3_Part6_CallSpawnNewBlocksMatch3_Part6_CallSpawnNewBlocks

Das soeben erstellte Event überprüft die Y-Position der Blöcke jedes Mal, wenn sie verschoben werden. Wenn es irgendwelche Blöcke findet, die mit SPAWNY inline sind, löst es die SpawnNewBlocks()-Funktion aus, wie wir zuvor besprochen haben. Es überprüft auch, ob der gefundene Block nicht der ist, der vom Spieler gezogen wird.

Wenn Sie Ihr Spiel zu diesem Zeitpunkt testen, wird es funktionieren, aber Sie sollten ein seltsames Problem bemerken. In dem Moment, in dem Sie das Spiel starten, fallen Ihre Blöcke, als wären keine Blöcke darunter, aber danach funktioniert alles perfekt und neue Blöcke werden immer dann erzeugt, wenn sie benötigt werden.

Dies geschieht, weil das Spiel beim ersten Start den Gravitationscode vor dem Code verarbeitet, der neue Blockreihen erzeugt. Um dies zu beheben, werden wir eine kleine Anpassung an dem Code vornehmen, der die anfängliche Gruppe von Blöcken erzeugt, so dass sie unterhalb des Punktes erscheinen, an dem eine neue Zeile benötigt würde. Dadurch kann die sofortige Ausführung des Schwerkraftcodes vermieden und die neue Blockreihe erstellt werden, sobald sich die vorhandenen Blöcke an der richtigen Stelle befinden.

Gehen Sie zu dem Ereignis, das die anfängliche Gruppe von Blöcken hervorbringt, und ändern Sie die Aktion, die den Block tatsächlich erstellt. Ändern Sie die Aktion wie folgt:

Das Event sollte nun so aussehen:

Match3_Part6_ModifiedInitialBlockSpawnMatch3_Part6_ModifiedInitialBlockSpawnMatch3_Part6_ModifiedInitialBlockSpawn

Diese Modifikation bedeutet, dass die Blöcke fünf Pixel unterhalb von SPAWNY erscheinen. Dies bedeutet, dass die Blöcke tatsächlich fünfmal nach oben verschoben werden müssen, bevor eine neue Reihe erscheint, und löst unser Problem.


4. Ein bisschen Animation

An diesem Punkt bewegen sich unsere Blöcke und es werden neue Zeilen erstellt. Denken Sie außerdem daran, dass wir früher verhindert haben, dass der Spieler einen Block verwendet, bis mindestens die Hälfte des Blocks sichtbar ist. Obwohl dies eine gute Funktion ist, versteht der Spieler möglicherweise nicht, warum ein Block nicht sofort verwendet werden kann, wenn er sichtbar wird, auch wenn zu diesem Zeitpunkt nicht viel davon sichtbar ist.

Aufgrund dieses potenziellen UI-Problems werden wir jeden Block dazu bringen, das graue Block-Sprite (am Anfang der Animationsframes des Blocks) zu verwenden, wenn er sich in diesem unbrauchbaren Zustand befindet. Dadurch wird dem Spieler klar, wann ein Block benutzbar wird, und wir haben die Möglichkeit, endlich unser letztes Blockbild zu verwenden.

Im folgenden GIF sehen Sie ein Beispiel, wie es aussehen wird, wenn die Blöcke von inaktiv zu aktiv werden:

BlockColorChange

Das von uns erstellte Ereignis enthält auch eine zweite Bedingung, die überprüft, ob der betrachtete Block nicht gezogen wird. Mit dieser Bedingung können wir sicherstellen, dass der Spieler, wenn er einen Block unter den Punkt zieht, an dem Blöcke verwendbar werden, sein Bild nicht so ändert, dass er grau ist und die Farbe behält, die er haben soll.

Damit diese Animation funktioniert, müssen wir zuerst ein neues Event hinzufügen:

Das neue Event sollte so aussehen:

InactiveBlockAnimationInactiveBlockAnimationInactiveBlockAnimation

Sie sollten jetzt Ihr Spiel testen können und Sie sollten sehen, dass die Blöcke das graue Bild verwenden, wenn sie sich unterhalb des Punktes befinden, an dem sie verwendbar sind.


5. Aktivieren und Deaktivieren von Drag/Drop

Wenn Sie das Spiel jetzt ausführen, werden Sie feststellen, dass die grauen Blöcke zwar nicht miteinander vertauscht werden können, aber die grauen Blöcke immer noch verschoben und manipuliert werden können. Dies liegt daran, dass wir die Drag/Drop-Funktionen des Blocks nie deaktiviert haben, wenn wir den Spieler daran gehindert haben, mit ihnen zu tauschen.

Um zu verhindern, dass die grauen Blöcke verschoben werden können, ändern wir das Event, das wir im vorherigen Abschnitt erstellt haben. Zuerst fügen wir eine neue Aktion hinzu, die das Ziehen ausschaltet, wenn der Block unter dem Punkt liegt, an dem er verwendbar ist.

Fügen Sie diese Aktion zu dem zuvor erstellten Ereignis hinzu:

Wir werden auch eine Else-Anweisung für dieses Ereignis hinzufügen, die den Block erneut ziehen lässt, sobald er über dem Punkt liegt, an dem der Block verwendbar ist:

Mit diesen beiden Änderungen sollte das Event so aussehen:

Match3_Part6_ModifiedInactiveMatch3_Part6_ModifiedInactiveMatch3_Part6_ModifiedInactive

Wenn Sie das Spiel zu diesem Zeitpunkt testen, sollten die Blöcke nicht mehr verwendbar sein, wenn sie grau sind, und sollten wie immer funktionieren, wenn sie es nicht sind.


6. Geschwindigkeitsänderungen

Das letzte, was ich in diesem Artikel behandeln möchte, ist das System, mit dem wir die Geschwindigkeit des Spiels im Laufe der Zeit ändern können. Insbesondere ist dies das System, das die Blöcke schneller bewegen lässt, wenn der Spieler mehr von ihnen eliminiert.

Das System, das wir erstellen werden, ist relativ einfach: Jedes Mal, wenn der Spieler eine bestimmte Anzahl von Punkten erhält, erhöht sich die Geschwindigkeit des Spiels basierend auf einem Modifikator, den wir erstellen werden, und der Anzahl der Punkte, die der Spieler erhalten muss die nächste Geschwindigkeitserhöhung ändert sich basierend auf einem zweiten Modifikator.

Bevor wir mit der Erstellung der Events für dieses System beginnen können, erstellen wir ein paar globale Variablen, um die neuen Funktionen für uns zu handhaben:

Ihre neuen Variablen sollten so aussehen:

Match3_Part6_GlobalVariablesMatch3_Part6_GlobalVariablesMatch3_Part6_GlobalVariables

Nachdem wir nun die Variablen eingerichtet haben, werde ich erklären, was die einzelnen tun.

  • SPEEDMOD ist die Variable, mit der wir die Geschwindigkeit multiplizieren, um sie zu ändern, wenn der Spieler die Anzahl der Punkte erreicht, die er benötigt, um eine Geschwindigkeitserhöhung zu bewirken.
  • PointsForSpeedUp ist die Anzahl der Punkte, die der Spieler benötigt, um die nächste Beschleunigung zu erreichen.
  • PointsBetweenSpeedUps stellt dar, um wie viel die Variable PointsForSpeedUp erhöht wird, wenn der Player eine Beschleunigung erhält, um sie so anzupassen, dass die nächste Beschleunigung noch mehr Punkte benötigt. Im Moment ist es 400, wie PointsForSpeedUp, aber wenn der Spieler tatsächlich eine Beschleunigung erreicht, wird es mit POINTSFORSPEEDUPMOD multipliziert, bevor es zu PointsForSpeedUp hinzugefügt wird.
  • Schließlich ist POINTSFORSPEEDUPMOD die Variable, die wir verwenden werden, um die Anzahl der Punkte zu ändern, die der Spieler benötigt, um seine Geschwindigkeit ein weiteres Mal über den zuletzt erreichten Wert hinaus zu erhöhen.

Neben dem Einrichten der Variablen müssen wir auch ein neues Sprite-Objekt erstellen, das den Spieler benachrichtigt, wenn die Geschwindigkeit steigt.

Gehen Sie zu Layout 1 und führen Sie diese Schritte aus, um das neue Sprite zu erstellen:

  1. Fügen Sie ein neues Sprite-Objekt in Layout 1 ein.
  2. Öffnen Sie mit dem Animationseditor das Bild SpeedIncImage.png.
    1. Setzen Sie den Namen auf SpeedIncreaseIndicator.
    2. Setzen Sie die Ebene auf Game Field.
    3. Stellen Sie die Position auf 188, 329 ein.
    4. Setzen Sie Anfängliche Sichtbarkeit auf Invisible.
      1. Fügen Sie dem Sprite ein Fade-Verhalten hinzu.
      2. Setzen Sie Aktiv beim Start auf No.
      3. Stellen Sie die Ausblendzeit auf 2.5 ein.
      4. Setzen Sie Zerstören auf No.

Ihr Layout sollte nun so aussehen:

Match3_Part6_SpeedLayoutMatch3_Part6_SpeedLayoutMatch3_Part6_SpeedLayout

Jetzt erstellen wir tatsächlich das Ereignis, das die Geschwindigkeit ändert:

So sollte Ihre Veranstaltung aussehen:

Match3_Part6_CheckForSpeedUpMatch3_Part6_CheckForSpeedUpMatch3_Part6_CheckForSpeedUp

Wenn diese Funktion aufgerufen wird, prüft sie, ob der Spieler genügend Punkte gesammelt hat, um eine Geschwindigkeitserhöhung zu rechtfertigen. Wenn ja, dann:

  • es aktiviert das Sprite, das dem Spieler mitteilt, dass die Geschwindigkeit zugenommen hat, indem es sichtbar gemacht und das Fade gestartet wird
  • es erhöht die Geschwindigkeit, indem es mit dem Modifikator multipliziert wird
  • es bestimmt die Anzahl der Punkte, die vor der nächsten Beschleunigung benötigt werden, und
  • es addiert diesen Wert zu der Gesamtpunktzahl, die der Spieler haben muss, bevor die Geschwindigkeit wieder ansteigt.

Wenn diese Funktion abgeschlossen ist, müssen wir nur sicherstellen, dass sie aufgerufen wird. Gehen Sie zur Funktion GivePoints() und fügen Sie diese Aktion am Ende des primären Ereignisses und des untergeordneten Ereignisses hinzu:

Die GivePoints()-Funktion sollte nun so aussehen:

Match3_Part6_ModifiedGivePointsMatch3_Part6_ModifiedGivePointsMatch3_Part6_ModifiedGivePoints

Nach Abschluss dieses Events sollten Sie in der Lage sein, Ihr Spiel zu testen und das Beschleunigungssystem in Aktion zu sehen.

Tipp: Als ich mehr damit spielte, stellte ich fest, dass sich diese Werte ein wenig falsch anfühlten. Ich schlage daher vor, dass Sie sich etwas Zeit nehmen, um mit dem System zu experimentieren und die Werte zu finden, mit denen Sie sich am wohlsten fühlen.


Abschluss

Wir haben in diesem Artikel viele verschiedene Themen behandelt, aber alles, was wir behandelt haben, hatte direkt oder indirekt damit zu tun, dass das Bewegungssystem so funktioniert, wie wir es wollten. Es dauerte zwar einige Zeit und erforderte von uns, mehr Systeme zu entwickeln, als wir am Anfang erwartet hatten, aber der Lohn hat sich gelohnt und wir haben am Ende ein sehr starkes System erhalten.

Da wir bereits so viel behandelt haben, denke ich, dass dies ein guter Ort ist, um diesen Artikel zu beenden. Der nächste Artikel sollte das letzte Tutorial in dieser Serie sein und wir werden viele kleinere Themen darin behandeln, aber das Größte, was wir behandeln, ist definitiv die Eliminierung vorgefertigter Matches.

Wenn Sie versuchen möchten, herauszufinden, wie wir sie eliminieren, sehen Sie sich zunächst an, wie wir Übereinstimmungen erkennen. Das von uns erstellte System wird diesem System sehr ähnlich sein, außer dass es die gefundenen Übereinstimmungen auf andere Weise verwendet. Fangen Sie an, darüber nachzudenken und sehen Sie, was Sie sich einfallen lassen können, und ich sehe Sie das nächste Mal hier zum letzten großen Tutorial der Reihe.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Game Development tutorials. Never miss out on learning about the next big thing.
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.