In deze zelfstudie maken we twee nieuwe functies die echt iets toevoegen aan onze game: scoren en game-over. Het klinkt misschien als een hoop werk, maar ons spel is zo opgezet dat dit snel en gemakkelijk te doen is. Dus, laten we die functies daar halen en ons spel voltooien!
De eerste functie die we zullen aanpakken, is het scoresysteem. Om een goed scoresysteem te krijgen, moeten we een aantal visueel aangename tekst aan onze game toevoegen. U kunt beginnen met het downloaden van een nieuw lettertype naar keuze of het downloaden van het lettertype dat ik in het downloadbestand van deze handleiding heb opgenomen. Als je je eigen hebt gekozen, zorg er dan voor dat je een ".ttf" -bestand downloadt. Er zijn veel geweldige sites beschikbaar met gratis lettertypen; u kunt beginnen door eenvoudig te zoeken naar "gratis lettertypen" en bladeren totdat u iets vindt dat u bevalt. Het downloadsbestand is op dezelfde manier opgezet als in de vorige projecten. Er is een oude en een nieuwe map: de oude map bevat alles wat we tot nu toe hebben gedaan, en de nieuwe map bevat het project zoals het eruit zal zien aan het einde van deze tutorial.
Zodra u dat in de map hebt staan die uw main.lua-bestand bevat, kunt u zowel het bestand main.lua als uw build.settings-bestand openen en laten werken. Het eerste dat we gaan doen, is werken met ons build.settings-bestand. Het is vanaf hier dat we het programma laten weten dat het het aangepaste lettertype moet bevatten.
Wijzig uw build.settings-bestand om er zo uit te zien:
instellingen = orientation = default = "landscapeRight", content = "landscapeRight", supported = "landscapeRight",, --adds het lettertype BorisBlackBloxx.ttf aan onze game - je zult nog steeds moeten verwijzen naar de naam in de --code, maar als je hier niet naar verwijst, zal het niet werken. iphone = plist = UIAppFonts = "BorisBlackBloxx.ttf",,
Merk op dat dit hetzelfde zal zijn, zelfs als u een Android-apparaat heeft. Ik ben voornamelijk een iOS-ontwikkelaar als het gaat om de ontwikkeling van games, dus ik heb dit niet getest op een Android-apparaat. Dit exacte script zou echter zowel op uw Android-apparaat als op uw iOS-apparaat moeten werken. (Als een Android-gebruiker deze tutorial tegenkomt, moet je me dit laten weten en ik zal het verder onderzoeken!) Nu de bovenstaande code aanwezig is, kun je doorgaan en dat bestand sluiten omdat we het niet hoeven aan te raken meer. We zullen controleren of het werkte door wat tekst aan het spel toe te voegen.
Laten we ons main.lua-bestand openen en onze spelers een scoringssysteem geven! Precies daarboven waar we onze displaygroepen maken, voeg je het volgende in:
--variabele om de score van onze game lokaal te houden score = 0 --scoreText is een andere variabele die een string bevat die de score-informatie heeft - als we de score updaten zullen we deze string ook altijd moeten updaten - ***** voor Android-gebruikers moet je misschien de bestandsextensie van het lettertype gebruiken - die je hier kiest, dus het zou BorisBlackBloxx.ttf zijn daar ****** local scoreText = display.newText ("score:" ... score, 0, 0, "BorisBlackBloxx", 50) - Dit is belangrijk, want als je deze regel niet hebt, zal de tekst constant blijven - zichzelf centreren in plaats van zich netjes uit te strekken langs een punt in een vast puntTekst: setReferencePoint (display.CenterLeftReferencePoint) scoreText .x = 0 scoreText.y = 30
Het volgende dat we zullen doen, is het toevoegen aan ons scherm DisplayGroup. Plaats dit nadat alle andere groepen zijn toegevoegd aan de schermgroep:
scherm: insert (scoreText)
Ga je gang en voer dat uit. Dit gaat erg snel, dus zorg ervoor dat alles correct werkt voordat je verder gaat. Je zou zoiets als dit moeten zien:
Zodra je dat hebt getest om er zeker van te zijn dat het werkt, zullen we de score bijwerken zodat deze onmiddellijk waarde heeft in onze game. In de updateBlocks () -functie daar rechts onder de regel die zegt:
if ((blokken [a]). x < -40) then, put this code:
score = score + 1 scoreText.text = "score:" ... score scoreTekst: setReferencePoint (display.CenterLeftReferencePoint) scoreText.x = 0 scoreText.y = 30
Dit zal onze score eenvoudigweg met één punt bijwerken elke keer dat een blok aan de linkerkant van het scherm passeert en opnieuw wordt ingevoegd aan de rechterkant. Dit kan natuurlijk op veel verschillende manieren worden gebruikt. Het is een slim idee om de score hier bij te werken, omdat deze in elk spel consistent blijft. Het baseert de scores op hoe ver de spelers hebben gereisd. Als je wilde noteren hoe ver ze zijn gereisd, zou je de score simpelweg opslaan in de variabele distanceTraveled, meters of iets vergelijkbaars.
De volgende functie die we aanpakken, gaat over wat er gebeurt als een speler sterft. We zullen het eenvoudig houden in deze tutorial, maar je zou kunnen zien hoe je er meer in kunt opnemen zodra we klaar zijn. Houd er rekening mee dat toevoegen aan de score heel eenvoudig is. Laten we zeggen dat je de score met vijf wilt verhogen elke keer dat je een geest of een obstakel doodt. Je zou gewoon de bovenstaande code in de botsingsdetectiesectie plaatsen waar je die objecten vernietigt.
Wanneer ons personage sterft, gaan we verschillende dingen doen:
1) Stop de beweging van de speler.
2) Laat de speler in cirkels ronddraaien voor een dramatisch effect. We doen dit hier omdat ik u alleen de rotatiefunctie voor weergaveobjecten wilt laten zien. Je kunt zijn dood natuurlijk veranderen in wat je maar wilt.
3) Geef een scherm weer boven het spel waarmee de speler het spel opnieuw kan starten als ze dat willen.
Eerst moeten we ervoor zorgen dat de spelsnelheid is ingesteld op 0. Vervolgens moeten we een variabele aan ons monsterweergaveobject toevoegen. Doe dit door de volgende regel code toe te voegen waarin we monster instantiëren:
monster.isAlive = true
Als dat zover is, zullen we de status ervan op een aantal verschillende plekken in het spel controleren. De eerste verandering die we gaan maken is naar updateMonster (), ga je gang en make updateMonster () ziet er zo uit:
functie updateMonster () - als ons monster springt, schakel dan over naar de springanimatie - als de lopende animatie niet blijft spelen (monster.isAlive == true), dan als (onGround) dan if (wasOnGround) dan anders monster: voorbereiden ("running") monster: play () end else monster: prepare ("jumping") monster: play () end if (monster.accel> 0) then monster.accel = monster.accel - 1 end monster.y = monster .y - monster.accel monster.y = monster.y - monster.gravity else monster: draaien (5) einde - update de botsing Rechter blijven voor de botsing van het monsterRect.y = monster.y einde
Merk op dat voordat we de positie van het monster bijwerken, we eerst controleren of de speler nog springlevend is of niet. Als de speler nog leeft, gaan we gewoon door zoals we normaal zouden doen. Als de speler niet leeft, sturen we ons monster in een eindeloze draai. Vervolgens moeten we de status van monster.isAlive daadwerkelijk wijzigen. Ga naar de functie checkCollisions () en we zullen de wijzigingen aanbrengen. Bij de check-botsingen wordt de positie van ons monster vergeleken met 3 verschillende items voor botsingen: blokken, spoken en spikes. In elk van deze secties stellen we de snelheid van het spel in op 0 wanneer een reeks wordt gedetecteerd. Wat u nu moet doen, is deze code aan elk van de drie secties toevoegen direct nadat we de snelheid op 0 hebben gezet.
monster.isAlive = false - dit pauzeert gewoon het huidige animatiemonster: pause ()
Nu is het zo ingesteld dat elke animatie die wordt afgespeeld stopt wanneer je sterft. Ook zal het monster op zijn plaats draaien vanwege de code die we al hebben toegevoegd aan updateMonster (). Voer het spel opnieuw uit en je zou dit moeten zien:
Op dit punt hebben we twee van de drie dingen gedaan die we nodig hadden om het sterfteproces in ons spel beter te maken. Het laatste is om een klein sterfscherm te maken waarmee de speler het spel opnieuw kan starten als ze dat willen. Ga terug naar de bovenkant van het bestand waar we alle displayObjects toevoegen en voeg dit toe:
local gameOver = display.newImage ("gameOver.png") gameOver.name = "gameOver" gameOver.x = 0 gameOver.y = 500
Omdat dit een eenvoudig menu is, ging ik door en maakte het een groot beeld. Ik heb dezelfde methode gebruikt die we voor de rest van de afbeeldingen hebben gebruikt en bewaarde deze buiten het scherm voor later gebruik. Wat we nu moeten doen, is dit op het scherm verplaatsen telkens wanneer onze speler sterft. Ga terug naar het gedeelte van de code waar we net mee gewerkt hebben, waar we monster.isAlive = false hebben geplaatst. Rechts onder dat het volgende toevoegen aan elk van die secties:
gameOver.x = display.contentWidth * .65 gameOver.y = display.contentHeight / 2
Zorg ervoor dat u toevoegt
scherm: insert (gameOver)
naar je code, zodat gameOver correct wordt weergegeven. Zet het als het laatste dat direct na de tekstscore moet worden toegevoegd. Op die manier is het zeker zichtbaar wanneer we het verplaatsen.
Hierdoor wordt het scherm "Game Over" net rechts van het draaiende monster geplaatst, zodat we onze uiteindelijke score linksboven in het scherm nog steeds kunnen zien. Tot slot, om dit allemaal te laten werken, moeten we ervoor zorgen dat het daadwerkelijk iets doet wanneer we het aanraken. Dus de volgende bewerking is de aangeraakte functie (). Verander je aangeraakte functie om er zo uit te zien:
aangeraakte functie (gebeurtenis) if (event.x < gameOver.x + 150 and event.x > gameOver.x - 150 en event.y < gameOver.y + 95 and event.y > gameOver.y - 95) en herstart vervolgens Game () else if (monster.isAlive == true) en daarna if (event.phase == "started") then if (event.x < 241) then if(onGround) then monster.accel = monster.accel + 20 end else for a=1, blasts.numChildren, 1 do if(blasts[a].isAlive == false) then blasts[a].isAlive = true blasts[a].x = monster.x + 50 blasts[a].y = monster.y break end end end end end end end
Merk op dat we maar één verandering hebben aangebracht: in plaats van eerst te controleren om te zien aan welke kant van het scherm de aanraakbediening staat (hoe we springen of schieten bepalen), controleren we om te zien of het object gameOverdisplay is aangeraakt. Als het niet is aangeraakt en het monster leeft, blijf dan springen en schieten zoals normaal. Maar als gameOver is aangeraakt, betekent dit dat het spel is afgelopen omdat het nu zichtbaar is en we gewoon de functie restartGame () aanroepen. Ergens daarboven wordt de functie restartGame () toegevoegd en dat zal alles voor ons doen.
functie restartGame () - beweeg menu gameOver.x = 0 gameOver.y = 500 - reset de score score = 0 - reset de snelheid van het spel = 5 - reset het monster monster.isAlive = true monster.x = 110 monster.y = 200 monster: prepare ("running") monster: play () monster.rotation = 0 - reset de groundLevel groundLevel = groundMin voor a = 1, blocks.numChildren, 1 do blocks [a] .x = ( a * 79) - 79 blokken [a] .y = groundLevel end - plaats de spoken voor a = 1, ghosts.numChildren, 1 do ghosts [a] .x = 800 ghosts [a] .y = 600 end - reset de spikes voor a = 1, spikes.numChildren, 1 do spikes [a] .x = 900 spikes [a] .y = 500 end - reset de blasts voor a = 1, blasts.numChildren, 1 do blasts [a ] .x = 800 ontploffingen [a] .y = 500 einde - reset de achtergronden backgroundfar.x = 480 backgroundfar.y = 160 backgroundnear1.x = 240 backgroundnear1.y = 160 backgroundnear2.x = 760 backgroundnear2.y = 160 end
Voer dat uit en hopelijk zou je nu een klein dood-scherm moeten hebben dat je kunt aanraken om het spel opnieuw te starten.
Met die kleine veranderingen moeten we nu een volledig functioneel spel hebben! De speler verdient een score en we behandelen de dood een beetje gracieuzer. Alles wat we hier deden was heel eenvoudig, maar hopelijk heb je nu een idee van hoe je grotere menu's zou kunnen maken of hoe je een meer ingewikkelde sterfscène kunt maken als je sterft. Een eenvoudige manier zou simpelweg zijn om een paar nieuwe animaties toe te voegen die bij de verschillende sterfgevallen passen, maar ik zal je laten beslissen wat het beste bij je spel past. Als u vragen heeft over de wijzigingen die we hebben aangebracht, kunt u me dit laten weten in de opmerkingen. Bedankt voor het volgende!