Lag et Space Invaders Game i Corona Finishing Gameplay

Hva du skal skape

I den forrige delen av denne serien fikk vi spillerens skip, flyttet, fikk inntrengerne til å bevege seg og oppdaget når en spillerkule hadde rammet en invaderer. I denne siste delen av serien får vi inntrengerne angriper spilleren, håndterer nivåer og legger til evnen til spilleren til å dø.

1. Firing Bullets

Hver gang en av inntrengerne brenner en kule. Vi bruker en timer for å oppnå dette. Legg til følgende kode til gamelevel.lua.

funksjon fireInvaderBullet () hvis (#invadersWhoCanFire> 0) deretter lokale randomIndex = math.random (#invadersWhoCanFire) lokale randomInvader = invadersWhoCanFire [randomIndex] lokal tempInvaderBullet = display.newImage ("laser.png", randomInvader.x, randomInvader.y + invaderSize / 2) tempInvaderBullet.name = "invaderBullet" scene.view: sett inn (tempInvaderBullet) physics.addBody (tempInvaderBullet, "dynamisk") tempInvaderBullet.gravityScale = 0 tempInvaderBullet.isBullet = sann tempInvaderBullet.isSensor = sann tempInvaderBullet: setLinearVelocity (0,400) table.insert (invaderBullets, tempInvaderBullet) ellers levelComplete () slutten

I denne funksjonen kontrollerer vi først om invadersWhoCanFire bordet har minst ett element i det. Hvis det er tilfelle, kjører vi koden i if-setningen. Ellers betyr det at nivået er over og vi påberoper levelComplete funksjon.

Det vil alltid være minst en inntrenger som kan brenne en kule til du dreper den siste invaderen, på hvilket tidspunkt invadersWhoCanFire bordet vil være tomt.

Innenfor if-setningen genererer vi et tilfeldig tall randomIndex avhengig av hvor mange elementer som er i invadersWhoCanFire bord. Vi velger da det aktuelle elementet, randomInvader, fra invadersWhoCanFire bord.

Vi lager et kulebilde, gi det en Navn eiendom slik at vi kan identifisere det senere, sette det inn i scenen og sette de samme egenskapene som vi gjorde på spillerens kulde. Til slutt legger vi inn kule i invaderBullets bord slik at vi kan referere det senere.

Vi må nå sette opp timeren. Legg til følgende i scene: Vis metode.

funksjonsscene: show (event) hvis (fase == "gjorde") da --SNIP-- Runtime: addEventListener ("kollisjon", onCollision) invaderFireTimer = timer.performWithDelay (1500, fireInvaderBullet, -1)

Hver 1500 millisekunder fireInvaderBullet er påkalt. Vær oppmerksom på at den siste parameteren vi sender inn er -1, noe som betyr at timeren gjentas for alltid. Når du oppretter en timer som gjentas for alltid, bør du til slutt avbryte den. Vi gjør dette iscene: hide fungere som vist nedenfor.

funksjonsscene: skjul (hendelse) hvis (fase == "vil") da --SNIP-- Runtime: removeEventListener ("collision", onCollision) timer.cancel (invaderFireTimer) endeend

2. Fjerne kuler

Som spillerens kuler vil inntrengernes kuler bevege seg på skjermen og fortsette å bevege seg og ta opp verdifullt minne. For å rette opp dette, fjerner vi dem akkurat som vi gjorde med spillerens kuler.

funksjonen checkInvaderBulletsOutOfBounds () hvis (#invaderBullets> 0) så for i = # invaderBullets, 1, -1 gjør hvis (invaderBullets [i] .y> display.contentHeight) så invaderBullets [i]: removeSelf () invaderBullets [i] = nil table.remove (invaderBullets, i) endeendens ende ende

Denne koden ligner veldig på å sjekke om spillerens kuler er ute av grensene, så jeg vil ikke diskutere implementeringen i detalj.

3. Oppdage et treff

Trinn 1: Kollisjonsdeteksjon

Det neste trinnet er å oppdage om en invaders kulde har truffet spilleren. Legg til følgende kode i onCollision funksjon.

Funksjon onCollision (event) hvis (event.phase == "startet") så --SNIP-- hvis (event.object1.name == "player" og event.object2.name == "invaderBullet") så table.remove (invaderBullets, table.indexOf (invaderBullets, event.object2)) event.object2: removeSelf () event.object2 = null hvis (playerIsInvincible == false) da killPlayer () end tilbake ende hvis (event.object1.name == " invaderBullet "og event.object2.name ==" player ") så table.remove (invaderBullets, table.indexOf (invaderBullets, event.object1)) event.object1: removeSelf () event.object1 = null hvis (playerIsInvincible == false ) da killPlayer () slutter returendets ende ende

Som før vet vi ikke hvilket objekt event.object1 og event.object2 vil være så vi bruker to hvis setninger for å kontrollere begge situasjoner. Vi fjerner invaderens kulde fra invaderBullets bord, fjern det fra skjermen, og sett det på nil. Hvis spilleren ikke er uovervinnelig, dreper vi det.

Trinn 2: Drep spilleren

Når vi dreper spilleren, gir vi ham en kort tid med uovervinnelighet. Dette gir brukeren tid til å gjenvinne fokus på spillet. Hvis numberOfLives variabel er lik 0, Vi vet at spillet er over og overgang til start scene der brukeren kan starte et nytt spill.

funksjon killPlayer () numberOfLives = numberOfLives-1; if (numberOfLives <= 0) then gameData.invaderNum = 1 composer.gotoScene("start") else playerIsInvincible = true spawnNewPlayer() end end

Trinn 3: Spionere en ny spiller

De spawnNewPlayer funksjonen gjør spilleren til å falle inn og ut i noen sekunder. Det er en fin effekt å la brukeren vite at skipet er midlertidig uovervinnelig.

funksjon spawnNewPlayer () lokalnummerOfTimesToFadePlayer = 5 lokalnummerOfTimesPlayerHasFaded = 0 lokal funksjon fadePlayer () player.alpha = 0; overgang.to (spiller, time = 400, alfa = 1,) numberOfTimesPlayerHasFaded = numberOfTimesPlayerHasFaded + 1 hvis (numberOfTimesPlayerHasFaded == numberOfTimesToFadePlayer) then playerIsInvincible = falsk ende ende fadePlayer () timer.performWithDelay (400, fadePlayer, numberOfTimesToFadePlayer)

Vi bruker en lokal funksjon, fadePlayer, som bruker overgangsbiblioteket til å modifisere alfa verdien av spiller. Vi holder styr på hvor mange ganger spiller har bleknet inn og ut, og satte spillernes uovervinnelighet til falsk når vi kommer til numberOfTimesToFadePlayer. Vi bruker en timer til å ringe fadePlayer funksjon for mange ganger numberOfTimesToFadePlayer er lik.

Kjør spillet for å teste dette ut. De spiller skal dø når en invaders kule treffer skipet. Hvis tre kuler rammer skipet, bør du bli tatt til start scene hvor du kan starte et nytt spill.

For å gjøre det enklere å teste, kommentere samtalen til moveInvaders i gameLoop fungere som vist nedenfor.

funksjon gameLoop () checkLayerBulletsOutOfBounds () --moveInvaders () checkInvaderBulletsOutOfBounds () end

4. Fullføre et nivå

Hvis du har klart å drepe hver invader, ville spillet ha kalt levelComplete funksjon, som ikke eksisterer ennå. La fikse det. Legg til følgende kodeblokk.

funksjonsnivåComplete () gameData.invaderNum = gameData.invaderNum + 1 hvis (gameData.invaderNum <= gameData.maxLevels) then composer.gotoScene("gameover") else gameData.invaderNum = 1 composer.gotoScene("start") end end

Vi øker gameData.invaderNum og, hvis det er mindre enn gameData.maxLevels, vi overgår til spillet er slutt scene. Ellers har spilleren fullført alle nivåer og vi tilbakestilt gameData.invaderNum til 1. Vi overgår til start scene hvor spilleren kan starte et nytt spill.

En enkel måte å teste dette på er å kommentere samtalen til moveInvaders i gameLoop funksjon og bruk knappene for å flytte skipet. Hvis det fortsatt er for vanskelig, kan du også kommentere de to anropene til killPlayeronCollision metode.

5. Spill over

Legg til følgende kode til gameover.lua å implementere spillet over scenen.

lokal komponent = krever ("komponent") lokal scene = komponent.newScene () lokal starFieldGenerator = krever ("starfieldgenerator") lokal pulsatingText = krever ("pulsatingtext") lokal nextLevelButton lokal starGenerator funksjonsscene: opprett (hendelse) lokal gruppe = selv .view starGenerator = starFieldGenerator.new (200, gruppe, 5) lokale invadersText = pulsatingText.new ("LEVEL COMPLETE", display.contentCenterX, display.contentCenterY-200, "Conquest", 20, gruppe) invadersText: setColor (1, 1, 1) invadersText: pulsate () nextLevelButton = display.newImage ("next_level_btn.png", display.contentCenterX, display.contentCenterY) gruppe: sett inn (nextLevelButton) sluttfunksjonsscene: show (event) lokale fase = event.phase komponist .removeScene ("gamelevel") hvis (fase == "gjorde") deretter nextLevelButton: addEventListener ("trykk", startNewGame) Runtime: addEventListener ("enterFrame", starGenerator) endeendens funksjonsscene: skjul .fase hvis (fase == "vil") så Runtime: removeEventListener ("enterF rame ", starGenerator) nextLevelButton: removeEventListener (" trykk ", startNewGame) slutten sluttfunksjon startNewGame () composer.gotoScene (" gamelevel ") slutt scene: addEventListener (" create "scene) scene: addEventListener (" show " scene: addEventListener ("skjul", scene) retur scene

Denne koden er veldig lik den start scene så du burde være kjent med det nå.

6. Kolliderer med en invaderer

Den siste kollisjonskontrollen vi trenger å utføre er en kollisjon mellom spilleren og på inntrengerne. Legg til følgende kodeblokk til onCollision metode vi så tidligere.

Funksjon onCollision (event) --SNIP - hvis (event.phase == "startet") så --SNIP-- hvis (event.object1.name == "player" og event.object2.name == "invader" ) så numberOfLives = 0 killPlayer () avslutte hvis (event.object1.name == "invader" og event.object2.name == "player") deretter numberOfLives = 0 killPlayer () slutten

Som vanlig må vi sjekke begge kollisjonssituasjonene. Vi satte numberOfLives til 0 og ring killPlayer. Ved innstilling numberOfLives til 0 og påberope seg killPlayer, spillet er over og spillovergangene til start scene.

7. Flere funksjoner

Dette fullfører spillet vårt, men jeg foreslår at du prøver å utvide spillet med noen få ekstra funksjoner. For eksempel kan du vise spillerens liv i en HUD.

Jeg har også tatt med en UFO-grafikk i kildefilene. Du kan prøve å lage en UFO tilfeldig, og hvis spilleren treffer den med en kule, gi dem et ekstra liv.

Hvis du trenger hjelp med disse konseptene, sjekk ut min Plane Fighting Game-serie på Tuts+.

Konklusjon

Hvis du har fulgt denne serien, bør du nå ha et fullt funksjonelt spill som ligner på de originale Space Invaders. Utvid på det og gjør det ditt eget. Jeg håper du fant denne opplæringen nyttig og har lært noen nye teknikker. Takk for at du leser.