In de vorige tutorial hebben we eindelijk ons spel in beweging gezet en beweging toegevoegd aan onze blokken. Bovendien hebben we een rudimentair moeilijkheidsniveau gecreëerd om het spel moeilijker te maken naarmate de speler langer speelt.
Met deze beide functies in het spel zijn we klaar om het systeem te implementeren dat vooraf gemaakte matches van het bord zal elimineren. Hoewel dit niet het laatste artikel in de serie is, is dit het laatste belangrijke systeem dat we moeten implementeren - dus wees gerust, want we hebben ons werk voor ons uitgesneden.
Hier is een demo van de game waaraan we werken in deze serie:
Voordat we aan de slag gaan met het hoofdgedeelte van deze zelfstudie, wil ik een moment nemen om twee problemen op te lossen die ik tijdens het schrijven van de vorige zelfstudie heb ontdekt.
Het eerste probleem waar ik het over heb, komt naar voren in het scenario dat u hieronder kunt zien:
In deze situatie, als je sleept Blok B op de groene stip, zou het moeten vallen vanwege de lege ruimtes onder de stip en uiteindelijk op de geëtiketteerde plek landen C. In de meeste scenario's zal dit gebeuren en het spel zal normaal functioneren, maar in sommige scenario's zal het spel in plaats daarvan een wedstrijd detecteren op het korte moment waar Blok B staat naast de groep EEN en het zal uiteindelijk alle drie de blokken vernietigen.
Dit probleem is niet exclusief voor dat scenario hierboven en kan zich ook voordoen wanneer u hetzelfde doet in het scenario dat ik hieronder heb gemarkeerd.
Als we dit niet oplossen, ontvangt de speler credits en punten voor een aantal wedstrijden die hij nooit wilde maken en kan hij ook in de war raken waarom zoveel blokken onverwachts verdwijnen.
Gelukkig is dit echter een eenvoudig probleem om op te lossen. Om dit probleem op te lossen, gaan we een nieuw maken Globale variabele riep MatchesPossible
wat bepaalt of er wedstrijden kunnen worden gemaakt en een nieuwe gebeurtenis die detecteert wanneer een blok "valt" en zal wijzigen MatchesPossible
om het zo te maken dat er geen overeenkomsten kunnen worden gemaakt terwijl dit gebeurt.
Eerst zullen we de globale variabele creëren:
Global Variable: MatchesPossible Type = Number Initial Value = 1
Uw nieuwe variabele zou er als volgt uit moeten zien:
Nu zullen we het evenement maken dat zal luisteren wanneer een blok valt:
Gebeurtenis: Voorwaarde: Omkeren: Blok> overlapt bij offset Object = Blok Offset X = 0 Offset Y = 8 Voorwaarde: Blok> Vergelijk Y-vergelijking = Minder of gelijk Y-coördinaat = SPAWNY Actie: Systeem> Stel waarde in Variabel = Komt overeen met mogelijke waarde = 1
Deze gebeurtenis zorgt ervoor dat wanneer een blok wordt gevonden een lege ruimte eronder heeft MatchesPossible ingesteld op 1
, betekenis wedstrijden zijn niet mogelijk. Je zult ook opmerken dat het de Y-positie van het blok controleert. Dit is om ervoor te zorgen dat het blok zich niet op de onderste rij blokken bevindt die altijd een lege ruimte eronder hebben.
Vervolgens hebben we een gebeurtenis nodig die instelt MKatchesPossible terug naar 0
wanneer geen blokken een lege ruimte onder hen hebben. Dit tweede evenement zal gebaseerd zijn op een andere voorwaarde:
Gebeurtenis: Voorwaarde: Systeem> Anders Actie: Systeem> Waarde instellen Variable = MatchesPossible Value = 0
Zorg ervoor dat deze gebeurtenis onmiddellijk volgt op de eerste gebeurtenis, zodat de instructie Else correct wordt gebruikt.
Je twee nieuwe evenementen zouden er als volgt uit moeten zien:
Eindelijk gaan we een nieuwe voorwaarde toevoegen aan CheckMatches zodat het ernaar kijkt MatchesPossible om te bepalen of een overeenkomst kan worden gemaakt. Voeg deze voorwaarde toe aan de eerste functieaanroep van de CheckMatches Evenement.
Voorwaarde: Systeem> Variabele vergelijken Variable = MatchesPossible Comparison = Equal to Vale = 0
Met de voorwaarde toegevoegd, uw CheckMatches Evenement zou er nu als volgt uit moeten zien:
In tegenstelling tot de meeste problemen die we tot nu toe tegenkwamen, komt dit probleem tamelijk inconsistent naar voren. Dit betekent dat we niet echt kunnen testen of het probleem is verholpen. We kunnen alleen testen of we andere problemen hebben veroorzaakt. Als je het spel nu speelt, zou je moeten zien dat er geen nieuwe problemen zijn veroorzaakt door deze voorwaarde.
Het tweede probleem dat ik wilde oplossen voordat we iets nieuws toevoegen, heeft betrekking op het Points-systeem.
Tijdens het werken aan het project voor deze tutorial, merkte ik dat iets dat ik deed ervoor zorgde dat het Points-systeem zich vreemd gedroeg en de speler vier of vijf keer zoveel punten gaf als zou moeten worden voor elke wedstrijd. Hoewel ik niet kon vaststellen welke verandering ik heb aangebracht, heeft dit ertoe geleid dat het probleem was dat het GivePoints De functie werd eigenlijk meerdere keren gebeld omdat de blokken niet meteen werden vernietigd. Gelukkig, net als ons laatste nummer, kan dit eenvoudig worden opgelost.
Om dit op te lossen gaan we een nieuwe variabele maken die het systeem zal vertellen of het punten kan geven. Vervolgens, wanneer we op het punt staan om het te gebruiken GivePoints functie zullen we ook de variabele aanpassen om ervoor te zorgen dat de gebeurtenis slechts één keer wordt geactiveerd. Eindelijk, als de punten eenmaal zijn gegeven, zullen we de variabele opnieuw veranderen zodat er geen probleem zal zijn de volgende keer dat we punten proberen te geven.
Maak eerst een Global Variable genaamd PointsGiven
:
Global Variable: PointsGiven Type = Number Initial Value = 0
Uw variabele zou dit leuk moeten vinden:
Vervolgens zullen we het gedeelte van de FindMatches functie die de punten daadwerkelijk geeft door een nieuwe voorwaarde en twee nieuwe acties toe te voegen.
Voorwaarde: Systeem> Variabele vergelijken Variabele = Gekeken vergelijking = Gelijk aan waarde = 0
Voeg nu deze actie toe aan het begin van de actielijst:
Actie: Systeem> Waarde instellen Variabel = Gewijzigde waarde = 1
Voeg ten slotte deze actie toe aan het einde van de actielijst:
Actie: Systeem> Waarde instellen Variabel = puntenwaarde = 0
Het evenement zou er nu als volgt uit moeten zien:
Met deze wijzigingen hebben we het zo gemaakt dat het evenement dat belt GivePoints wordt alleen uitgevoerd als het PointsGiven variabele is 0
. Omdat we meteen de waarde instellen 1
wanneer we het Evenement starten, voorkomt dit dat de Evenement meerdere keren wordt geactiveerd en zorgt het ervoor dat de speler het juiste aantal punten ontvangt.
Als je het spel nu uitvoert, zou je het juiste aantal punten moeten krijgen voor elke wedstrijd die je maakt, zelfs als je dit probleem niet had om mee te beginnen.
Nu we die fixes uit de weg hebben geruimd, kunnen we doorgaan met het maken van het systeem dat matches elimineert die worden voortgebracht door het systeem wanneer het willekeurig kleuren toewijst aan de blokken die het maakt.
Het probleem dat we nu hebben is dat, aangezien de Block-kleuren volledig willekeurig zijn, het niet ongebruikelijk is dat je het spel start en onmiddellijk een aantal matches ziet. Dit is een probleem omdat het de eerste paar seconden van het spel erg verwarrend kan maken voor iemand die nog nooit eerder heeft gespeeld en omdat het de speler punten geeft die ze niet hebben verdiend.
Om het probleem op te lossen, zullen we een functie maken die naar elk blok kijkt en dan kijken of dat blok dezelfde kleur heeft als elk van zijn buren. Als het dezelfde kleur heeft als zijn buren, blijft het de kleur van dat blok wijzigen totdat het niet meer overeenkomt met een van de blokken eromheen.
Om dit systeem te laten werken, moeten we ook meerdere ondersteuningsfuncties en gebeurtenissen maken en een nieuwe instantievariabele toevoegen aan de Blok voorwerp.
Maak eerst een nieuwe instantievariabele voor de Blok voorwerp:
Exemplaar Variabele: BlockID Type = Number Initiële waarde = 0
Deze variabele is wat we zullen gebruiken om een blok gemakkelijk te identificeren, zodat we een aantal van de functies kunnen vertellen die we precies gaan maken naar welk blok we willen kijken, ongeacht de positie.
Voordat we verder gaan, moeten we ook deze variabele gaan gebruiken. Ga naar de Aan het begin van de lay-out Gebeurtenis waarbij de blokken worden gemaakt en een nieuwe actie wordt toegevoegd vóór de actie die toeneemt NumBlocks:
Actie: Blokkeren> Stel waarde in Instance variabele = BlockID Value = NumBlocks
Uw block-spawning-evenement zou er nu als volgt uit moeten zien:
Vervolgens moeten we een functie maken die de X- en Y-positie van een blok inneemt en ons vertelt welke kleur dat blok is:
Gebeurtenis: Voorwaarde: Functie> Aan functie Naam = "GetBlockColor" Subgebeurtenis: Voorwaarde: Blok> Vergelijk X Vergelijking = Gelijk aan X-coördinaat = Functie.Param (0) Voorwaarde: Blok> Vergelijk Y-vergelijking = Gelijk aan Y co -ordinate = Function.Param (0) Actie: Functie> Retourwaarde instellen Waarde = Blok.Kleur Subgebeurtenis: Systeem> Anders Actie: Functie> Retourwaarde instellen Waarde = -1
De functie zou er als volgt uit moeten zien:
Nu we een functie hebben die ons de kleur van elk blok kan vertellen, gaan we de functie maken die daadwerkelijk naar een blok kijkt en bepalen of er aangrenzende blokken zijn die dezelfde kleur hebben.
De manier waarop deze functie werkt, is vrij eenvoudig.
Voordat we dit evenement kunnen maken, moeten we een nieuwe globale variabele maken. In de functie gebruiken we een while-lus om te bepalen of de kleur van het blok moet worden gewijzigd. De variabele die we gaan creëren, is de variabele die de While Loop zal gebruiken om te bepalen of deze moet blijven draaien:
Global Variable: HasMatchingNeighbor Type = Number Initial Value = 0
Tip:Het Event dat we gaan maken bevat een Or-based Event. Als u nog nooit een gebeurtenisblok hebt gemaakt met een of attribuut, hoeft u alleen maar het gebeurtenisblok te maken zoals u normaal zou doen en dan met de rechtermuisknop op het volledige blok te klikken en te kiezen Maak 'Or' Block. In tegenstelling tot een standaard gebeurtenisblok waarvoor alle voorwaarden moeten worden ingevuld voordat het kan worden geactiveerd, wordt een Of-blok geactiveerd als ieder voorwaarde is vervuld.
Laten we het evenement maken:
Gebeurtenis: Voorwaarde: Functie> Aan functie Naam = "RemoveSpawnedMatches" Subgebeurtenis: Voorwaarde: Blok> Vergelijk instantievariabele Instance variabele = BlockID Vergelijking = Gelijk aan Waarde = Function.param (0) Actie: Systeem> Stel waarde in Variabel = HasMatchingNeighbor Waarde = 1 Subgebeurtenis: Voorwaarde: Systeem> While Voorwaarde: Systeem> Variabele vergelijken Variable = HasMatchingNeighbor-vergelijking = Gelijk aan waarde = 1 Subgebeurtenis: voorwaarde: blok> Vergelijk instellingsvariabele Instance-variabele = kleurvergelijking = gelijk aan waarde = functie. Call ("GetBlockColor", Block.X - (Block.Width + 2), Block.Y) Actie: Blokkeren> Instelwaarde Instance variabele = Color Value = floor (Random (1,7)) Actie: Systeem> Waarde instellen Variabel = HasMatchingNeighbor Waarde = 1 Subgebeurtenis: Voorwaarde: Systeem> Anders Voorwaarde: Blok> Vergelijk instantievariabele Instance variabele = Kleurvergelijking = Gelijk aan Waarde = Functie.Gesprek ("GetBlockColor", Block.X + (Block.Width + 2) , Block.Y) Actie: Blok> Stel waarde in Instance variabele = Kleur Waarde = vloer (Willekeurig (1,7)) Actie: Systeem> Waarde instellen Variabel = HasMatchingNeighbor Waarde = 1 Subgebeurtenis: Voorwaarde: Systeem> Anders Voorwaarde: Blok> Vergelijk instelbare variabele Instance variabele = Vergelijking van kleur = Gelijk aan Waarde = Functie.Gesprek ("GetBlockColor", Block.X, Block.Y - (Block.Width + 2)) Actie: Blok> Instelwaarde Instance variabele = Kleur Waarde = floor (Random (1,7)) Actie: Systeem> Stel waarde in Variabel = HasMatchingNeighbor Waarde = 1 Subgebeurtenis: Conditie : Systeem> Anders Voorwaarde: Blok> Vergelijk instandsvariabele Instance variabele = Kleurvergelijking = Gelijk aan Waarde = Function.Call ("GetBlockColor", Block.X, Block.Y + (Block.Width + 2)) Actie: Blokkeren> Instellen waarde Instance variabele = Color Value = floor (Random (1,7)) Actie: Systeem> Stel waarde in Variabel = HasMatchingNeighbor Waarde = 1 Subgebeurtenis: Voorwaarde: Systeem> Anders Actie: Systeem> Stel waarde in Variabel = HasMatchingNeighbor Waarde = 0
Uw evenement zou er als volgt uit moeten zien:
Dus hoe werkt deze functie precies?
Het eerste wat het doet is controleren op een Blok met de BlockID dat het systeem is doorgegeven. Wanneer het dat lokaliseert Blok het bepaalt de waarde van HasMatchingNeighbors naar 1
en voert dan de while-lus uit.
Omdat de while-lus alleen wordt uitgevoerd wanneer HasMatchingNeighbors is 1
, dat is de waarde waar het voor instelt. Tijdens de while-lus wordt getest of er een naburig is Blok naar links, rechts, boven of onder, dezelfde kleur als de Blok we kijken naar. Als het een overeenkomst vindt Blok in ieder van deze posities, wijst het willekeurig een nieuwe kleur toe aan de Blok en voert dan de test opnieuw uit door ervoor te zorgen HasMatchingNeighbors ingesteld op 1
. Wanneer het eindelijk een kleur vindt voor de Blok dat komt niet overeen met een van zijn buren, het verandert de waarde van HasMatchingNeighbors naar 0
zodat de While-lus eindigt en het programma verder kan gaan.
Nu moeten we deze functie in het spel implementeren; om dit te doen zullen we twee nieuwe variabelen en twee nieuwe functies moeten creëren. Laten we beginnen met de variabelen.
Global Variable: CheckStartingMatches Type = Number Value = 0
Algemene variabele: CheckNewestRow Type = Getalwaarde = 0
Uw variabelen moeten er als volgt uitzien:
De twee variabelen die we zojuist hebben gemaakt, worden gebruikt om de twee evenementen te starten die we gaan maken. De gebeurtenissen zelf worden gebruikt om de blokken direct na het maken door te duwen en elk blok naar de RemoveSpawnedMatches functie.
De reden waarom we niet alleen de RemoveSpawnedMatches functie direct na het maken van het blok is omdat het blokraster volledig moet zijn om de functie correct te laten werken. Dus in plaats van alleen de functie direct aan te roepen wanneer er blokken worden gemaakt, activeren we in plaats daarvan een gebeurtenis die door de blokken kan gaan en de functie op zichzelf kan roepen nadat het raster is gegenereerd.
Het eerste evenement zal specifiek zijn voor het itereren door de eerste blokkengroep:
Gebeurtenis: Voorwaarde: Systeem> Vergelijk variabele Instance variabele = CheckStartingMatches Vergelijking = Gelijk aan Waarde = 1 Voorwaarde: Systeem> Voor Naam = "Blokken" Start index = 0 Einde index = NumBlocks-1 Actie: Functie> Oproepfunctie Naam = "RemoveSpawnedMatches" Parameter 0 = loopindex ("Blokken") SubEvent: Voorwaarde: Systeem> Vergelijk twee waarden Eerste waarde = loopindex ("Blokken") Vergelijking = Gelijk aan Tweede waarde = NumBlocks-1 Actie: Systeem> Stel variabele in Exemplaar variabele = CheckStartingMatches Waarde = 0
Dit is hoe uw evenement eruit zou moeten zien:
Het tweede evenement zal specifiek zijn om nieuwe rijen blokken te controleren wanneer ze worden gemaakt:
Gebeurtenis: Voorwaarde: Systeem> Vergelijk variabele Instance variabele = CheckNewestRow vergelijking = Gelijk aan waarde = 1 Voorwaarde: Systeem> Voor naam = "Blokken" Start index = NumBlocks-9 Einde index = NumBlocks-1 Actie: Functie> Oproep functie Naam = " RemoveSpawnedMatches "Parameter 0 = loopindex (" Blokken ") SubEvent: Voorwaarde: Systeem> Vergelijk twee waarden Eerste waarde = loopindex (" Blokken ") Vergelijking = Gelijk aan Tweede waarde = NumBlocks-1 Actie: Systeem> Stel variabele Instance variabele = CheckNewestRow Waarde in = 0
Dit is hoe het tweede evenement eruit zou moeten zien:
Met beide functies in de plaats hoeven we ze nu alleen nog maar te implementeren. Ga naar de eerste gebeurtenis die de blokken maakt, de Aan het begin van de lay-out Evenement. We gaan hier een sub-evenement aan toevoegen, wat het zal vertellen CheckStartingMatches Event om te activeren.
Subgebeurtenis: Voorwaarde: Systeem> Vergelijk twee waarden Eerste waarde = loopindex ("X") Vergelijking Tweede waarde: 7 Voorwaarde: Systeem> Vergelijk twee waarden Eerste waarde = loopindex ("Y") Vergelijking Tweede waarde: 3 Actie: Systeem> Instelwaarde Instance variabele = CheckStartingMatches Waarde = 1
Uw evenement zou er nu als volgt uit moeten zien:
Deze sub-gebeurtenis luistert naar wanneer de geneste For-lus is beëindigd en verandert dan de waarde van de CheckStartingMatches variabele om de juiste gebeurtenis te activeren.
We gaan nu bijna exact hetzelfde Sub-evenement maken en dit koppelen aan de SpawnNewBlocks functie.
Subgebeurtenis: Voorwaarde: Systeem> Vergelijk twee waarden Eerste waarde = loopindex ("X") Vergelijking Tweede waarde: 7 Actie: Systeem> Stel waarde in Exemplaar variabele = CheckNewestRow Waarde = 1
SpawnNewBlocks zou er nu als volgt uit moeten zien:
Dit sub-evenement doet hetzelfde als het vorige, behalve dat het de andere gebeurtenis activeert die we hebben gemaakt. Als je het spel nu uitvoert, zou je moeten zien dat wanneer je het spel start, er niet langer automatisch wedstrijden voorkomen.
In deze zelfstudie hebben we niet teveel wijzigingen aangebracht in het spel, maar degene die we wel hebben gemaakt waren erg belangrijk.
Op dit moment denk ik dat het het beste is dat we nu stoppen en de laatste twee game-elementen opslaan voor de volgende tutorial, waar we ketens / combo's en het scherm Game Over zullen behandelen. Dit is het laatste deel van de serie, dus ik zal ook praten over een aantal spelmechanismen die we niet zullen behandelen in deze tutorials, en je enig advies geven over hoe je die systemen zelf kunt maken.
Als je een voorsprong wilt nemen op de inhoud van de volgende week, begin dan te kijken hoe je zou kunnen detecteren wanneer het Game Over-scherm zou moeten verschijnen, op basis van de positie of hoogte van sommige van de blokken. Je kunt ook gaan nadenken over hoe je kunt detecteren wanneer de speler een kettingreactie maakt waardoor meer dan één groep wordt gevormd.
Wat je ook doet, ik hoop je volgende week terug te zien voor de laatste aflevering van de serie.