Denna handledning tar en titt på att överföra ett Flash / Flex-spel till Corona SDK. Specifikt kommer vi att överföra från ActionScript till Lua, med slutmålet att spela tidigare Flash-only-spel på iPhone. Förutom att visa språk- och API-skillnader, kommer denna handledningsserie också att ta hänsyn till hårdvarubegränsningar som skärmstorlek och brist på fysiska knappar på iPhone.
Nu börjar vi arbeta med vår fiende: "de / pixelate / flixelprimer / Alien.as". Som alltid konverteras syntax först.
När du är klar med det, lägg till modulen dekleration och linda alla funktioner inuti Alien ().
modul (?, package.seeall) - [Inbädda (source = "? /? /? /? /assets/png/Alien.png")] privat var ImgAlien: Klassfunktion Alien (x, y) -: void super (x, y, ImgAlien) hastighet.x = -200 funktionsuppdatering () -: void velocity.y = Math.cos (x / 50) * 50 super.update () änden
Utlänningen fungerar väldigt som vår kula. Den skapar en bild, sätter sin x och y
koordinater, och ger det en hastighet. Så vi kommer att närma oss det på samma sätt. De två översta raderna inuti funktionen kan ersättas med nästan samma kod som vi använde för kula. Den här gången brukar vi använda en bild.
modul (?, package.seeall) funktion Alien (x, y) -: void local Alien = display.newImage ("Alien.png") Alien.x = x Alien.y = y funktionsuppdatering () -: void ? änden
Nu när vi har laddat och laddat upp bilden, låt oss flytta till vänster. Återigen kommer vi att skapa något som kollens uppdateringskod () kod. Lämna de gamla linjerna inom uppdateringen () kommenterade.
modul (?, package.seeall) funktion Alien (x, y) -: void? funktionsuppdatering () -: tom om Alien då om (Alien.x> 0 - Alien.contentWidth) då Alien.x = Alien.x - 2 endänden? kommenterad kod? end Runtime: addEventListener ("enterFrame", uppdatering) slut
Låt oss nu göra en kill () -funktion och göra Alien tillbaka en Alien.
modul (?, package.seeall) funktion Alien (x, y) -: void? funktionsuppdatering () -: void? slutfunktion Alien: kill () Alien.parent: remove (Alien) Alien = nil slutet Runtime: addEventListener ("enterFrame", uppdatering) returnera Alien end
Nu kan vi döda () vår främling om det är x utanför skärmen till vänster. Vi kan också lägga till en ny () funktion som en bekvämlighet.
modul (?, package.seeall) funktion Alien (x, y) -: void local Alien = display.newImage ("Alien.png") Alien.x = x Alien.y = y funktionsuppdatering () -: void om Alien då om (Alien.x> 0 - Alien.contentWidth) då Alien.x = Alien.x - 2 else Alien: kill () slutänden slutfunktion Alien: kill () Alien.parent: remove (Alien) Alien = nil slutet Runtime: addEventListener ("enterFrame", uppdatering) returnera Alien slutfunktion ny (x, y) returnera Alien (x, y) slutet
Att skapa utlänningen var ganska lätt. Nu måste vi börja lägga till dem i spelet via PlayState.
Först importera modulen till PlayState.lua.
modul (?, package.seeall) lokalt skepp = kräver ("skepp") lokala Bullet = kräver ("Bullet") local Alien = kräver ("Alien") lokala knappar = kräver
Nu måste vi ställa in en timer. Den ursprungliga koden hade en variabel _spawnInterval som användes för att ställa in _spawnTimer. Varje gång _spawnTimer nådde 0, skulle den nollställas till värdet av _spawnInterval._spawnInterval skulle sedan minskas med .1, vilket resulterade i att utlänningar blir skötare snabbare.
För att starta, kommentera _spawnInterval och _spawnTimer egenskapsdeklarationer i skapa ().
funktion skapa () -: void - variabeldeklarationer PlayState._inGame = true PlayState._background = noll PlayState._ship = nil - PlayState._aliens = nil PlayState._bullets = nil - PlayState._scoreText = nil --playState. _gameOverText = nil PlayState._spawnTimer = nil PlayState._spawnInterval = nil - SpelaState.SoundExplosionShip = nil - PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? slutet
Nu i variabla uppdrag ställer du in _spawnTimer till 0 och _spawnInterval till 2.5. Lägg också till ett samtal för att återställaSpawnTimer (). Vi skapar den här funktionen om en sekund.
funktion skapa () -: void? - variabla uppdrag PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false PlayState._bullets = display.newGroup () PlayState.SoundBullet = media.newEventSound ("Bullet.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2.5 återställSpawnTimer () slutet
Hitta nu kommenterad funktion resetSpawnTimer (). Det kommer att se ut så här.
funktion resetSpawnTimer () -: void _spawnTimer = _spawnInterval _spawnInterval = _spawnInterval * 0,95 om (_spawnInterval < 0.1) then _spawnInterval = 0.1 end end
Förvånansvärt nog, det är precis vad vi behöver. Vi behöver bara göra PlayStates variabler egenskaper. På så sätt vet funktionen vad _spawnInterval och _spawnTimer vi pratar om.
funktionsåterställningspawnTimer () < 0.1) then PlayState._spawnInterval = 0.1 end end
Nu måste vi lägga till en kod för att uppdatera (). I den ursprungliga koden skapade spelet utomjordingar även om spelet var över och fartyget var dött. För att göra detsamma, låt oss sätta vår utländska hanteringskod utanför där vi kontrollerar om spelet är över.
funktionsuppdatering () PlayState._spawnTimer = PlayState._spawnTimer - (30/1000) om (PlayState._spawnTimer < 0) then spawnAlien() resetSpawnTimer() end if PlayState._inGame then? end end
Koden fungerar precis som källkoden. Den subtraherar 1 rams värde av tid från _spawnTimer. Det kontrollerar sedan om _spawnTimer är mindre än noll. Om det är, återställer det timern och springer en ny utlänning.
Innan vi kan hämta utlänningar behöver vi en bildgrupp för att lägga till dem. Precis som _bullets, uncomment _aliens decleration och tilldela dem till en ny bildgrupp.
funktion skapa () -: void - variabeldeklarationer PlayState._inGame = true PlayState._background = noll PlayState._ship = noll PlayState._aliens = nil PlayState._bullets = nil - PlayState._scoreText = nil --PlayState._gameOverText = nil PlayState._spawnTimer = nil PlayState._spawnInterval = 2.5 - SpelState.SoundExplosionShip = nil - PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil - variabla uppdrag PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = falskt PlayState._aliens = display.newGroup () PlayState._bullets = display.newGroup () PlayState. SoundBullet = media.newEventSound ("Bullet.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2,5 återställSpawnTimer ()? slutet
Hitta nu din spawnAlien () funktion och uncomment den. Det borde se ut så här:
funktion spawnAlien () -: void local x = FlxG.width lokal y = Math.random () * (FlxG.height - 100) + 50 _aliens.add (nytt Alien (x, y)) slutet
Denna kod skapar en alien bara till höger om skärmen och i slumpmässig höjd. Sedan lägger den till den nya alien i bildgruppen. Vi kan göra samma sak med den här koden:
funktion spawnAlien () -: void local x = display.contentWidth local y = math.random () * (display.contentHeight - 240) + 50 PlayState._aliens: insert (Alien.new (x, y)) slut
Om vi kör koden nu fungerar den nästan som originalet. Utlänningarna förekommer i slumpmässiga höjder, och de framträder långsammare oftare. När de kommer utanför skärmen kallar de död () på sig själva. Nu behöver vi bara få dem att flytta som de gjorde i originalkoden. I det ursprungliga spelet följde utlänningar vägen för en cosinovåg som genererades utifrån deras x-läge. Vi har den här koden kommenteras i utlänningsuppdateringen () funciton. Koden tog lite med. Eftersom vi inte har någon hastighet att arbeta med är det svårt att använda originalkoden. Detta är tiden i porten där du bara måste spela med siffrorna. Jag hittade att denna kod fungerade närmast originalet:
funktionsuppdatering () -: tom om Alien då om (Alien.x> 0 - Alien.contentWidth) sedan Alien.x = Alien.x - 2 Alien.y = Alien.y + math.cos (Alien.x / 10 ) * 2 Annat Alien: Kill () Slutänden
Nu när vi har alla våra spelobjekt som fungerar som original, måste vi kolla efter kollisioner mellan kulorna och utomjordingarna och utlänningar och fartyg. I den ursprungliga koden kontrollerades kollisioner i funktionen uppdatering (). Om en kollision inträffade skickades de två objekten till funktionerna överlappAlienBullet () och överlappAlienShip (). Låt oss skapa dessa funktioner först. Om vi uncomment overlapAlienBullet () har vi kod som ser ut så här:
funktionen överlappAlienBullet (alien, bullet) -: void local emitter = createEmitter () emitter.at (alien) alien.kill () bullet.kill () FlxG.play (SoundExplosionAlien) FlxG.score = FlxG.score + 1 _scoreText. text = FlxG.score.toString () slutet
Denna kod skapar en partikelemitterare, dödar båda objekten, spelar en ljudeffekt och uppdaterar poängen. Att återskapa flixelpartikelsystemet ligger utanför omfattningen av denna handledning, och vi har ännu inte implementerat ett poängsystem. För nu, låt oss bara kommentera de här raderna och döda föremålen.
funktion överlappAlienBullet (alien, bullet) -: void alien: kill () bullet: kill () --FlxG.play (SoundExplosionAlien) --FlxG.score = FlxG.score + 1 --_ scoreText.text = FlxG.score. toString () slutet
Gör detsamma för överlappAlienShip ():
funktion överlappAlienShip (alien, skepp) -: tomt skepp: död () alien: kill () --FlxG.play (SoundExplosionShip) --_ gameOverText = ny FlxText (0, FlxG.height / 2, FlxG.width, "GAME ÖVER \ nPRESS ENTER FÖR ATT SPELA IGEN ") --_ gameOverText.setFormat (null, 16, 0xFF597137," center ") --add (_gameOverText) slutet
Låt oss nu skapa ljudeffekten för användning i dessa funktioner. Ovanstående ljudvariabeldeklarationerna i skapa ().
funktion skapa () -: void - variabeldeklarationer PlayState._inGame = true PlayState._background = noll PlayState._ship = noll PlayState._aliens = nil PlayState._bullets = nil - PlayState._scoreText = nil --PlayState._gameOverText = noll PlayState._spawnTimer = noll PlayState._spawnInterval = 2.5 PlayState.SoundExplosionShip = nil PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? slutet
Tilldela dem nu till sina ljud:
funktion skapa () -: void? - variabla uppdrag PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false PlayState._aliens = display.newGroup () PlayState._bullets = display.newGroup () PlayState.SoundBullet = media.newEventSound ( "Bullet.caf") PlayState.SoundExplosionShip = media.newEventSound ( "ExplosionShip.caf") PlayState.SoundExplosionAlien = media.newEventSound ("ExplosionAlien.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2.5 resetSpawnTimer () slutet
Att spela ljudet är lika enkelt som en rad per funktion ().
funktionen överlappAlienBullet (alien, bullet) -: void alien: kill () bullet: kill () media.playEventSound (PlayState.SoundExplosionAlien) --FlxG.score = FlxG.score + 1 --_ scoreText.text = FlxG.score. toString () slutfunktion överlappAlienShip (utlänning, skepp) -: tomt skepp: död () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) --_ gameOverText = ny FlxText (0, FlxG.height / 2, FlxG. bredd, "GAME OVER \ nPRESS ENTER FÖR ATT SPELA IGEN") --_ gameOverText.setFormat (null, 16, 0xFF597137, "center") --add (_gameOverText) slut
Nu när vi har överlappningsfunktioner på plats, måste vi kolla efter kollisioner varje ram. I Corona har vi inte ett enkelt sätt att kontrollera överlappande visningsobjekt. Vi måste göra kontrollerna manuellt. Detta är ett ganska enkelt koncept, men blir ganska rörigt i genomförandet. Låt oss tänka på det här en sekund. Vad definierar en överlappning? Din första instinkt kan vara att kontrollera om ett objekt är inuti en annan. Detta skulle fungera, men i detta fall kan en överlapp bara vara delar av föremålen. Ett objekt behöver inte vara helt inuti en annan för att överlappa varandra. Vad ser det ut i kod? Allt vi behöver göra är att kontrollera om det maximala x-värdet av ett utkast är större än minumum x
värdet på det andra objektet. Då kontrollerar vi om samma saks minsta x-värde är mindre än det andra objektets maximala x-värde. Detta kommer att återvända sant för varje överlappning. Därefter utför vi samma kontroller på objektets y-värden. Om vi går igenom alla objekt i de bildskärmsgrupper som vi skapade tidigare, borde vi ha ett fungerande kollisionssystem.
Låt oss försöka med kulorna och utomjordingarna. Vi behöver bara utföra dessa kontroller i spelet. Så sätt den här koden inuti den korrekta delen av uppdateringen () -funktionen:
funktionsuppdatering () -: void? om PlayState._inGame sedan om PlayState._shoot == sant och PlayState._ship sedan lokal p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) slut om PlayState._bullets.numChildren> 0 och PlayState._aliens.numChildren> 0 därefter för b = 1, PlayState._bullets.numChildren gör lokala bulletXMax = PlayState._bullets [b] .contentBounds.xMax lokal bulletXMin = PlayState._bullets [b] .contentBounds.xMin lokala bulletYMax = PlayState._bullets [b] .contentBounds.yMax lokal bulletYMin = PlayState._bullets [b] .contentBounds.yMin för a = 1, PlayState._aliens.numChildren gör om (PlayState._aliens [a] .contentBounds.xMin <= bulletXMax) then if (PlayState._aliens[a].contentBounds.xMax >= bulletXMin) sedan om (PlayState._aliens [a] .contentBounds.yMin <= bulletYMax) then if (PlayState._aliens[a].contentBounds.yMax >= bulletYMin) överlappar sedanAlienBullet (PlayState._aliens [a], PlayState._bullets [b]
Som jag sa, ser den här koden lite rörigt ut, men det fungerar. Så vad gör det här? Först kontrollerar den om en kula eller en alien ens existerar. Den här koden kan bli riktigt minneintensiv, så vi måste kolla allt. Vi vill inte slösa tid om vi inte ens har båda typer av föremål. När denna kod passerar börjar vi en för loop. Den här slingan ställer in en variabel ("b" som kallas efter "kulor") till 1 och kör resten av koden för varje punkt i _bullets. De fyra följande kodkoderna skapar en lokal kopia av min- och maxvärdena för kula. Som jag sa tidigare måste vi spara minnet här. Vi behöver inte beräkna kulorna x och y värden om och om de inte ändras. Nästa rad börjar ännu en annan för loop. Den här upprepas för alla utomjordingar i _aliens. Koden inuti den andra för slinga utför bara de kontroller vi pratade om tidigare. Är kulaets max x-värde större än aliens min x-värde? Jag kan inte betona minnet nog här, det
varför vi kontrollerar varje villkor i ett separat om uttalande. Om en av dessa test misslyckas, kan vi bara släppa ut ur slingan. Det finns inget behov av att fortsätta kontrollera om det inte finns några kollisioner. Slutligen, i själva mitten, om alla dessa kontroller passerar, kallar vi vår överlappAlienBullet () -funktion med kolliderande kula och främling.
Puh. Det var mycket kod. Nu behöver vi bara göra samma för skeppet.
funktionsuppdatering () -: void? om PlayState._inGame då om PlayState._shoot == true och PlayState._ship då är lokala p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) slutet? om PlayState._aliens.numChildren> 0 då lokala shipXMax = PlayState._ship.contentBounds.xMax lokal shipXMin = PlayState._ship.contentBounds.xMin lokal shipYMax = PlayState._ship.contentBounds.yMax lokal shipYMin = PlayState._ship.contentBounds.yMin för a = 1, PlayState._aliens.numChildren gör om (PlayState._aliens [a] .contentBounds.xMin <= shipXMax) then if (PlayState._aliens[a].contentBounds.xMax >= shipXMin) sedan om (PlayState._aliens [a] .contentBounds.yMin <= shipYMax) then if (PlayState._aliens[a].contentBounds.yMax >= shipYMin) då överlappAlienShip (PlayState._aliens [a], PlayState._ship) ändändets ändände ände ändände ände änden
Denna kod är identisk med kula och alien kod. Den enda skillnaden är att vi bara har ett skepp. Vi vet att det finns ett fartyg, annars skulle PlayState._inGame vara falskt. Vi behöver inte slingra genom en bildskärm av skepp eftersom vi bara har en.
Innan vi kan testa den här koden måste vi göra spelet sluta i överlappAlienShip (). Ändra _inGame till false.
funktionen överlappAlienShip (utlänning, skepp) -: tomt skepp: död () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false --_ gameOverText = ny FlxText (0, FlxG.height / 2, FlxG .width, "GAME OVER \ nPRESS ENTER FÖR ATT SPELA IGEN") --_ gameOverText.setFormat (null, 16, 0xFF597137, "center") --add (_gameOverText) slut
Att köra koden visar nu att vårt hårda arbete har löpt ut. Vi har nu en fullt fungerande hamn i det ursprungliga spelet. Vi behöver fortfarande återskapa poängsystemet, och vi måste kunna starta om spelet, men den svåra porten är klar.
Låt oss börja med poängsystemet. Det här är lika enkelt som att skapa en textetikett och uppdatera den när poängen ändras. Uncomment line _scoreText och lägg till en ny _score-egenskap i Create () -deklarationerna.
funktion skapa () -: void - variabeldeklarationer PlayState._inGame = true PlayState._background = noll PlayState._ship = noll PlayState._aliens = nil PlayState._bullets = nil PlayState._score = nil PlayState._scoreText = nil --Spelstat ._gameOverText = nil PlayState._spawnTimer = noll PlayState._spawnInterval = 2.5 PlayState.SoundExplosionShip = nil PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? slutet
Nu måste vi tilldela dem några värden. _score kan bara ställas in på 0. _scoreText måste tilldelas ett nytt textobjekt längst upp till vänster på skärmen.
funktion skapa () -: void? - variabla uppdrag PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false PlayState._aliens = display.newGroup () PlayState._bullets = display.newGroup () PlayState._score = 0 PlayState._scoreText = display.newText ("0", 10, 8, nil, 32) PlayState._scoreText: setTextColor (89 , 113, 55) PlayState.SoundBullet = media.newEventSound ( "Bullet.caf") PlayState.SoundExplosionShip = media.newEventSound ( "ExplosionShip.caf") PlayState.SoundExplosionAlien = media.newEventSound ( "ExplosionAlien.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2.5 återställSpawnTimer () slutet
NewText API är enkelt: display.newText ("text att visa", x position, y position, typsnitt, storlek). "PlayState._scoreText: setTextColor (89, 113, 55)" ställer bara fyllfärgen till samma gröna färg som kulorna. Allt vi behöver nu är att uppdatera poängen i överlappAlienBullet ():
funktionen överlappAlienBullet (alien, bullet) -: void alien: kill () bullet: kill () media.playEventSound (PlayState.SoundExplosionAlien) PlayState._score = PlayState._score + 1 PlayState._scoreText.text = PlayState._score slutet
Detta lägger bara till 1 till egenskapen _score när en alien dödas av en kula. Då ändras textegenskapen till _scoreText till värdet av poängen.
Innan vi paketerar upp det här spelet behöver vi ett sätt att återställa det. På så sätt kan användaren börja om när de dör. Vi måste göra det i två steg. Först måste vi stoppa allt som användaren kan kontrollera så snart skeppet dör. Då måste vi återställa allt annat när användaren tappar för att starta ett nytt spel.
Låt oss stänga av alla knapparna i funktionen overlapAlienShip (). Låt oss också ta bort fartygsegenskapen. Vi kan göra detta genom att ställa in alla värden till noll.
funktion överlappAlienShip (utlänning, skepp) -: tomgångsskepp: död () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = noll PlayState._upButton.onPress = noll PlayState._upButton. onRelease = noll PlayState._downButton.onPress = noll PlayState._downButton.onRelease = noll PlayState._leftButton.onPress = noll PlayState._leftButton.onRelease = noll PlayState._rightButton.onPress = noll PlayState._rightButton.onRelease = noll PlayState._shootButton.onPress = nil PlayState._shootButton.onRelease = nil --_ gameOverText = ny FlxText (0, FlxG.height / 2, FlxG.width, "GAME OVER \ nPRESS ENTER FÖR ATT SPELA IGEN") --_ gameOverText.setFormat (null, 16, 0xFF597137 , "center") --add (_gameOverText) slutet
Denna kod tilldelar bara alla onPress och onRelease-värden till noll. Knapparna kommer fortfarande
displayen, men de kommer inte att ringa någon kod när de trycks in.
Vi ser nu att den ursprungliga funktionen overlapAlienShip () visade en textetikett för att berätta för användaren att spelet var över. Vi kommer att göra samma sak. Först uncomment vår _gameOverText egenskap i skapa () funktionen.
funktion skapa () -: void - variable declarations PlayState._inGame = true PlayState._background = noll PlayState._ship = nil PlayState._aliens = nil PlayState._bullets = nil PlayState._score = nil PlayState._scoreText = nil PlayState._gameOverText = noll PlayState._spawnTimer = noll PlayState._spawnInterval = 2.5 PlayState.SoundExplosionShip = nil PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? slutet
Tillbaka i överlappAlienShip () måste vi ersätta den kommenterade koden med dessa rader.
funktion överlappAlienShip (utlänning, skepp) -: tomgångsskepp: död () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = noll PlayState._upButton.onPress = noll PlayState._upButton. onRelease = nil PlayState._downButton.onPress = nil PlayState._downButton.onRelease = nil PlayState._leftButton.onPress = nil PlayState._leftButton.onRelease = nil PlayState._rightButton.onPress = nil PlayState._rightButton.onRelease = nil PlayState._shootButton.onPress = noll PlayState._shootButton.onRelease = nil PlayState._gameOverText = display.newText ("GAME OVER TAP TO PLAY AGAIN", 35, display.contentHeight / 2 - 50, nil, 16) PlayState._gameOverText: setTextColor (89, 113, 55) slut
Detta är samma kod som vi brukade skapa och fylla i poängtexten. Positionen ändras för att centrera texten på skärmen, och texten säger "TAP TO PLAY AGAIN" istället för "PRESS ENTER TO PLAY AGAIN".
Eftersom vi kommer att trycka på för att starta om spelet, måste vi lägga till en ny evenemangslyttare. Vi kan göra det på samma sätt som vi tillfogade enterFrame-lyssnaren, men den här gången är den händelse vi lyssnar på "tap". Vi behöver också lägga till en funktion för lyssnaren att ringa. På botten av överlappAlienShip () lägg till den här evenemangslyttaren:
funktion överlappAlienShip (utlänning, skepp) -: tomgångsskepp: död () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = noll PlayState._upButton.onPress = noll PlayState._upButton. onRelease = nil PlayState._downButton.onPress = nil PlayState._downButton.onRelease = nil PlayState._leftButton.onPress = nil PlayState._leftButton.onRelease = nil PlayState._rightButton.onPress = nil PlayState._rightButton.onRelease = nil PlayState._shootButton.onPress = noll PlayState._shootButton.onRelease = nil PlayState._gameOverText = display.newText ("GAME OVER TAP TO PLAY AGAIN", 35, display.contentHeight / 2 - 50, nil, 16) PlayState._gameOverText: setTextColor (89, 113, 55) Runtime: addEventListener ("tryck", tryck) slutet
Denna kod kontrollerar en kran någonstans på skärmen. När en "kran" inträffar, ringer den till funktionsknappen (). Låt oss göra en tom krets () funciton för att den ska ringa. Lägg det precis ovanför skapa ().
? funktionsknappen (händelse) - vi behöver bara det här som en platshållare för nu avsluta funktionen skapa ()? slutet
Låt oss göra en remove () -funktion för att hantera rensning av alla spelobjekt. Sätt den här funktionen över vår nya knapp () -funktion.
? funktion remove () - end-funktionsknappen (händelse) - vi behöver bara detta som platshållare för nu slutfunktions skapa ()? slutet
Till att börja med borde vi döda alla de återstående utomjordingarna och kulorna. För att göra detta kan vi helt enkelt gå igenom respektive visningsgrupper. Det här är rätt sätt att ta bort objekt i Corona:
funktionen ta bort () för i = PlayState._bullets.numChildren, 1, -1 gör PlayState._bullets [i]: kill () sluta för i = PlayState._aliens.numChildren, 1, -1 gör PlayState._aliens [i]: döda () avsluta PlayState._bullets: removeSelf () PlayState._bullets = nil PlayState._aliens: removeSelf () PlayState._aliens = nil end
Dessa loopar fungerar på ett speciellt sätt. Varje slinga börjar med "i" inställd på det sista objektet i bildskärmsgrupperna. Då slår slingan det objektet och subtraherar 1 från "i". Slingan upprepas tills "jag" är lika med 1. Anledningen till att vi subtraherar från "I" är att varje gång vi dödar ett objekt tar det bort sig från bildgruppen. Det betyder att det finns ett mindre objekt i bildgruppen. Om vi skulle lägga till 1 till "jag" skulle vi sluta ringa död () om objekt som inte existerar längre. För att fixa detta räknar vi bakåt varje gång vi tar bort ett objekt.
När alla objekt har tagits bort från grupperna tar vi bort grupperna. Vi ställde också de egenskaper som höll grupperna till noll. Nu kan de användas igen.
Låt oss ange alla använda variabler till noll. På så sätt kan sopsamlare frigöra minnet. Detta kommer också att se till att alla variablerna återställs innan vi börjar ett nytt spel. Ta bort alla knapparna först:
funktionen ta bort () för i = PlayState._bullets.numChildren, 1, -1 gör PlayState._bullets [i]: kill () sluta för i = PlayState._aliens.numChildren, 1, -1 gör PlayState._aliens [i]: döda () avsluta PlayState._bullets: removeSelf () PlayState._bullets = noll PlayState._aliens: removeSelf () PlayState._aliens = nil PlayState._upButton: removeSelf () PlayState._upButton = noll PlayState._downButton: removeSelf () PlayState._downButton = noll PlayState._leftButton: removeSelf () PlayState._leftButton = nil PlayState._rightButton: removeSelf () PlayState._rightButton = noll PlayState._shootButton: removeSelf () PlayState._shootButton = nil end
Vi måste först ta bort dem från teckenfönstret och sedan ställa dem till noll. Låt oss ta hand om våra ljud nu.
funktionen ta bort () för i = PlayState._bullets.numChildren, 1, -1 gör PlayState._bullets [i]: kill () sluta för i = PlayState._aliens.numChildren, 1, -1 gör PlayState._aliens [i]: döda () avsluta PlayState._bullets: removeSelf () PlayState._bullets = noll PlayState._aliens: removeSelf () PlayState._aliens = nil PlayState._upButton: removeSelf () PlayState._upButton = noll PlayState._downButton: removeSelf () PlayState._downButton = noll PlayState._leftButton: removeSelf () PlayState._leftButton = noll PlayState._rightButton: removeSelf () PlayState._rightButton = noll PlayState._shootButton: removeSelf () PlayState._shootButton = noll PlayState.SoundExplosionShip = nil PlayState.SoundExplosionAlien = nil PlayState. SoundBullet = nil slutet
Nu våra textobjekt:
funktionen ta bort ()? PlayState._scoreText: removeSelf () PlayState._scoreText = nil PlayState._gameOverText: removeSelf () PlayState._gameOverText = nil slutet
För att slutföra rengöring måste vi ta bort våra händelselöser. Därefter kan vi slutligen återställa PlayState till en tom array:
funktionen ta bort ()? Runtime: removeEventListener ("enterFrame", uppdatering) Runtime: removeEventListener ("tryck", tryck) PlayState = nil PlayState = end
Omstart av spelet är lika enkelt som att ringa ta bort () och skapa sedan () i vår knapp () -funktion.
funktionsknappen (händelse) ta bort () skapa () slut
Vi är nästan färdiga. Vi behöver bara lägga några finjusteringar. Börja med att ta bort alla kommenterade rader från gammal källkod. Detta kommer att städa våra filer upp ett ton.
En annan snabb tweak vi kan göra är att aktivera multitouch. Du kommer inte märka förändringen på simulatorn, men det är trevligt att kunna trycka flera knappar åt gången på den aktuella enheten. Detta är en linjejustering. Vi behöver bara att det ska hända en gång, så låt oss lägga till den i main.lua-filen.
lokala PlayState = kräver ("PlayState") funktion Main () system.activate ("multitouch") display.setStatusBar (display.HiddenStatusBar) PlayState.PlayState () slut Main ()
Jag hade också lite problem med ui.lua-modulen. Knapparna räknar inte med att dra fingret från enheten en släpp, om inte den sista platsen berördes var knappen. Detta fungerar inte alltid korrekt för det här spelet, och ibland verkar skeppet vara på egen hand eftersom utlösningsfunktionen inte kallas. Detta var en enkel fix. Jag tog bort kontrollen för att se om knappen trycktes när användarens finger släpptes. Detta innebar bara att kommentera om och sluta uttalandena på rad 91 och 98.
? om "slutade" == fas då - bara betrakta det här ett "klick" om användaren lyfter fingret inuti knappens stadium. Bounds -if isWithinBounds then if onEvent då buttonEvent.phase = "release" result = onEvent (buttonEvent) elseif onRelease sedan result = onRelease (event) slutänden slut?
Dessa ändringar ingår i filen ui.lua som ingår i denna handledning.
Vi är klara. Vi har nu en helt fungerande kopia av det ursprungliga flashspelet. Vi har ett skepp som rör sig och bränder, utomjordingar och ett poängsystem. Spelet hanterar minne om alla objekt och har möjlighet att återställa och börja om. Annat än partikelsystemet är detta spel en identisk port. Nu när du har slutfört denna handledning bör du ha tillräcklig kunskap för att porten nästan alla flash / actionscript-spel till iPhone.
Många utvecklare gillar att lägga till funktionalitet eller ändra spelningen lite när man skickar ett spel till en mobil enhet. Jag skulle vilja utmana dig att förbättra / ändra detta spel för att göra det mer som en riktig app. Du kan ändra kontrollschemat till någon av de typerna vi pratade om i lektion 2. Du kan skapa en meny med inställningar eller flera nivåer. Du kan lägga till olika typer av fiender. Du kan lägga till ett lokalt eller online hög poängsystem. Möjligheterna är oändliga. Lyckligtvis gör Corona väldigt snabb utveckling, och är verkligen jämn. Jag hoppas att du haft denna handledning och, viktigare, lärde dig mycket. Lämna en kommentar nedan för att berätta för oss hur sakerna gick.