Welkom bij de vijfde aflevering van de Endless Runner-serie! Tot nu toe zouden we een klein monster moeten laten draaien op een eindeloos schuifplatform. We zouden drie niveaus van parallax scrollen moeten hebben, interactie tussen onze monstersprite en de grond, evenals het vermogen om hem te laten springen via aanrakinginteractie. De stap van vandaag geeft de gebruikers dus een beetje een uitdaging: in plaats van gewoon op een vlakke ondergrond te rennen, zullen er niveauveranderingen en putten zijn waar ze over moeten springen om te blijven spelen.
We zullen deze leuke uitdaging volbrengen door een 'evenementensysteem' toe te voegen. Dit moet niet worden verward met de ingebouwde gebeurtenissen die de Corona SDK gebruikt. Voor onze doeleinden is het woord 'evenement' gewoon een gemakkelijke manier om uit te leggen wat er aan de hand is. Deze tutorial gebruikt hetzelfde formaat als de vorige. In het downloadbestand vindt u twee mappen: 'oud' en 'nieuw'. Als je de andere tutorials niet hebt gevolgd en er gewoon recht op wilt ingaan, kun je gewoon de oude map openen en alle bestanden hebben die je nodig hebt om te beginnen. De nieuwe map bevat het voltooide project, dus als je wilt zien hoe alles er aan het einde uit ziet, neem dan gerust een piek.
Mogelijk herkent u het woord 'evenement' uit de vorige zelfstudies. Kijk bijvoorbeeld naar de aangeraakte functie:
function touched (event) if (event.phase == "started") then if (event.x < 241) then if(onGround) then monster.accel = monster.accel + 20 end end end end
In die functie gebruikten we het woord 'gebeurtenis' om eenvoudig te beschrijven wat er gebeurde. We hadden heel goed de volgende code kunnen gebruiken:
function touched (kapow) if (kapow.phase == "started") then if (kapow.x < 241) then if(onGround) then monster.accel = monster.accel + 20 end end end end
'Evenement' of 'kapow' zijn eenvoudigweg variabelen die we gebruiken. 'Evenement' is gewoon meer beschrijvend dan 'kapow'. Dus wanneer we 'gebeurtenis' zeggen, hebben we het niet over een variabele die iets beschrijft wat er gebeurt (zoals in het vorige voorbeeld), maar we gebruiken het woord als een manier om een systeem te beschrijven dat de stroom van het spel bepaalt . Je vraagt je misschien af wat dit "gebeurtenissysteem" kan regelen. Nou, hoeveel plezier is onze demo nu? Is het iets dat je zou willen verkopen? Wat nog belangrijker is, is het iets dat iemand zou willen spelen? Het antwoord is pijnlijk nee, want hardlopen en springen zonder obstakels is saai.
Om onze game interessanter te maken, moeten we functies toevoegen. Dingen zoals de grondveranderende levels, putten, obstakels, slechteriken, enz., Zullen het spel veel interessanter maken. In een game als Endless Runner kunnen we echter niet dezelfde obstakels in elk spel op hetzelfde moment laten verschijnen. We moeten alles gerandomiseerd hebben. Dat is wat deze spellen zo verslavend maakt. Dit is waar ons 'gebeurtenissysteem' echt gaat schijnen. In deze tutorial gaan we bespreken hoe je twee verschillende evenementen kunt maken: ten eerste, de grondveranderniveaus op en neer, en ten tweede, het creëren van een pit. Deze evenementen worden willekeurig met willekeurige tussenpozen gegenereerd. Er zijn verschillende manieren om dit te doen. Voor dit voorbeeld is de meest logische manier om te controleren of we een nieuwe gebeurtenis moeten starten elke keer dat we een van onze grondstukken naar de rechterkant van het scherm verplaatsen. Laten we verder gaan en kijken naar wat we nodig hebben om dit te doen.
Ga je gang en open het main.lua-bestand in de oude map en we zullen enkele wijzigingen gaan aanbrengen. Het eerste dat u hoeft te doen, is enkele variabelen toe te voegen die we gedurende het hele programma zullen gebruiken. Voeg deze regels toe aan de bovenkant van het bestand direct onder de gewenste sprite-regel:
--deze 2 variabelen zijn de controles die ons gebeurtenissysteem beheren. local inEvent = 0 local eventRun = 0
Ga vervolgens naar de updateSpeed-functie en verander de snelheid. We moeten een langzame, geleidelijke snelheidsverhoging kiezen, zodat het spel echt verder gaat zoals je zou verwachten. Verander de regel naar deze:
--dit zal drastisch vertragen hoe snel de tegels versnellen. - stel dit getal in om de spelsnelheid dichter bij hetgeen werkt voor je spel te krijgen. snelheid = snelheid + .0005
Het volgende dat we gaan doen is ons eerste evenement toevoegen. Ons eerste evenement zal ervoor zorgen dat elk van de blokken verandert in een nieuw ingestelde hoogte elke keer dat er een wordt verplaatst naar de andere kant van het scherm. Dit zal natuurlijk willekeurig worden gedaan, zodat onze game altijd nieuw en spannend is. Om ons gebeurtenissensysteem te starten, wijzigt u eerst de functie updatesBlokken () om er als volgt uit te zien:
function updateBlocks () voor a = 1, blocks.numChildren, 1 do if (a> 1) then newX = (blokkeert [a - 1]). x + 79 else newX = (blokken [8]). x + 79 - speed end if ((blokkeert [a]). x < -40) then (blocks[a]).x, (blocks[a]).y = newX, groundLevel checkEvent() else (blocks[a]):translate(speed * -1, 0) end end end
De eerste regel zou simpelweg de y-positie van het blok gelijk stellen aan het vorige voordat een vlak loopvlak werd gemaakt dat we tot nu toe hebben gezien. De tweede wijzigt de y-positie ongeacht het groundLevel. Het variabele grondniveau zal in kleine intervallen willekeurig worden veranderd in de volgende functies. Ga je gang en voeg deze functies toe, overal onder de update-functie.
function checkEvent () - controleer eerst of we al in een evenement zijn, we willen alleen dat 1 evenement tegelijk gaat (eventRun> 0) en dan - als we in een evenement zijn event-run verminderen. eventRun is een variabele die ons vertelt hoe - hoe langer het evenement zal plaatsvinden. Telkens als we controleren, moeten we decrement --it. Als eventRun op dit moment 0 is, dan is de gebeurtenis beëindigd, dus hebben we inEvent teruggezet - naar 0. eventRun = eventRun - 1 if (eventRun == 0) en vervolgens inEvent = 0 einde - als we in een evenement zijn, dan doe niets als (inEvent> 0 en eventRun> 0) en dan - doe niets anders - als we geen evenementcheck uitvoeren om te zien of we een nieuw evenement gaan starten. Om dit te doen - we genereren een willekeurig getal tussen 1 en 100. We controleren dan of onze 'check' is - going to start a event. We gebruiken hier 100 in het voorbeeld omdat het eenvoudig is om te bepalen - de waarschijnlijkheid dat een evenement zal ontbranden (we zouden net zo goed 10 of 1000 kunnen kiezen). - Als we bijvoorbeeld besluiten dat een evenement gaat beginnen met elke keer dat een controle groter is dan 80, weten we dat telkens wanneer een blok wordt gereset, er een 20% is - dat een evenement begint. Dus één op de vijf blokken zou een nieuw evenement moeten starten. Dit is waar je moet voldoen aan de behoeften van je spel. check = math.random (100) - deze eerste gebeurtenis zorgt ervoor dat de hoogte van de grond verandert. Voor deze game willen we alleen dat de hoogte 1 blok tegelijk wijzigt, dus we krijgen geen lange runs met veranderende verhogingen die onmogelijk kunnen worden gepasseerd, dus stellen we eventRun in op 1. if (vink> 80 aan en vink aan < 99) then --since we are in an event we need to decide what we want to do. By making inEvent another --random number we can now randomly choose which direction we want the elevation to change. inEvent = math.random(10) eventRun = 1 end end --if we are in an event call runEvent to figure out if anything special needs to be done if(inEvent > 0) en vervolgens runEvent () end end - deze functie is vrij eenvoudig, het controleert gewoon om te zien welke gebeurtenis zou moeten gebeuren, en vervolgens - updatet de juiste items. Merk op dat we controleren of de grond zich binnen een bepaald bereik bevindt, we willen niet dat de grond boven of beneden spawnt die op het scherm zichtbaar is. function runEvent () if (inEvent < 6) then groundLevel = groundLevel + 40 end if(inEvent > 5 en inEvent < 11) then groundLevel = groundLevel - 40 end if(groundLevel < groundMax) then groundLevel = groundMax end if(groundLevel > groundMin) en groundLevel = groundMin end end
De eerste functie checkEvent wordt elke keer opgeroepen als we de locatie van het blok opnieuw instellen. Dus, ga je gang en call checkEvent () direct na de regel die we hebben bewerkt in updateBlocks (). Telkens als checkEvent () wordt aangeroepen, controleren we of we een evenement moeten starten. Het zal ook controleren om te zien of een evenement al aan de gang is. Dit zal ons helpen ons gedrag onder controle te houden, zodat we niet te veel gekke gebeurtenissen krijgen die tegelijk voortkomen. Voer dit uit en je zou nu een spel moeten hebben dat veel leuker is om te spelen!
Merk op dat als je een muur tegenkomt, je niet sterft; je stopt gewoon. Dit is voldoende voor nu. Bedenk dat wanneer u sterft of op een ander moment dat u de simulator opnieuw wilt opstarten, u gewoon op de knop of R hoeft te drukken en het niveau wordt onmiddellijk opnieuw gestart.
Je kunt nu zien hoe we evenementen creëren om de stroom van het spel te besturen. Nu gaan we een tweede evenement toevoegen, maar deze keer gaan we runEvent niet gebruiken om onze wijzigingen aan te brengen. We gaan een pit toevoegen waar de speler overheen moet springen om te blijven spelen. Dit kan vrij snel worden toegevoegd, dus laten we aan het werk gaan!
Het eerste dat u hier moet doen, is nog een vinkje toevoegen in de functie checkEvent (). Voeg dit gedeelte direct onder de andere controle toe binnen dezelfde if / else-instructie:
if (check> 98) then inEvent = 11 eventRun = 2 end
Ga vervolgens naar de updateBlocks () -functie en verander de sectie die er als volgt uitziet:
if ((blokken [a]). x < -40) then (blocks[a]).x, (blocks[a]).y = newX, groundLevel checkEvent() else (blocks[a]):translate(speed * -1, 0) end
Laat dat er zo uit zien:
if ((blokken [a]). x < -40) then if(inEvent == 11) then (blocks[a]).x, (blocks[a]).y = newX, 600 else (blocks[a]).x, (blocks[a]).y = newX, groundLevel end checkEvent() else (blocks[a]):translate(speed * -1, 0) end
Nadat je dat hebt uitgevoerd, zou je een tweede evenement in het spel moeten hebben dat willekeurig de pit kan spawnen!
Merk echter op dat in plaats van de actie te definiëren die binnen de runEvent-functie zal plaatsvinden, we dit direct in de updateBlock () -functie doen. Dit is de reden waarom gebeurtenissystemen zoals deze nuttig zijn. Hiermee kunnen we gemakkelijk evenementen definiëren en de game bijwerken in de gebieden van onze code die voor ons het meest logisch zijn. Hopelijk geeft dit je een idee van wat je kunt doen met evenementen. Veel plezier met het spelen met hen en maak je game vol met interessante evenementen. In de volgende tutorial voegen we nog twee evenementen toe om het spel uitdagend te houden: slechte monsters en vernietigbare obstakels! Dus stem de volgende keer af en als u vragen heeft, kunt u me dit laten weten in de opmerkingen.