I denna handledning lär du dig hur du skapar, Highway Dodge, ett enkelt, men beroendeframkallande spel. Highway Dodge är lätt att hämta och spela, men det ger den beroendeframkallande kvaliteten på andra populära spel i App Store.
Highway Dodge börjar genom att placera spelaren i en bil på motorvägen. Under spelet måste spelaren undvika kommande trafik på motorvägen genom att knacka på en av de tre tillgängliga banorna. För varje dodged bil får spelaren en poäng och det är spelet över för spelaren när en motkommande bil träffar tävlingsbilen. Med tiden kommer de kommande bilarna ut snabbare och snabbare för att ge spelaren en riktig utmaning.
Detta spel är byggt med hjälp av Lua och Corona SDK. Du behöver åtminstone ha ett konto med Corona Labs och Corona SDK installerat. Du kan få tag i Corona SDK gratis på Corona Labs hemsida. För den här handledningen brukade jag bygga 2015.2731 av Corona SDK.
Låt oss hoppa rätt in och starta Highway Dodge genom att skapa en tom mall. Öppna Corona Simulator och välj Nytt projekt från Fil meny. När du har Skapa nytt projekt fönstret öppet, skriv in Highway Dodge som projektnamn, välj en tom mall och sätt bredden till 400 och höjden till 600. Lämna standard orienteringsset till Upprätt.
När du har skapat ditt projekt, ladda ner bilderna för Highway Dodge. Skapa en ny mapp i ditt nya projekt, namnge det och lägg till bilderna i den här mappen. Ditt projekt ska nu se ut så här:
Med projektet inrättat, låt oss ta en snabb titt på två viktiga filer, build.settings och config.lua.
Den här filen hanterar spelets egenskaper för byggtiden. Den lagrar information om orienteringen av din app, ikoninformation, iOS-inställningar och Android-inställningar. Standardinställningen är tillräcklig för vårt spel.
Den här konfigurationsfilen styr spelets runtimeegenskaper. Detta inkluderar bredd
, höjd
, skala
, fps
(bildrutor per sekund) och imageSuffix
. Den egendom som vi behöver ta en titt på är imageSuffix
. De imageSuffix
Egenskapen används för dynamiskt bildval. I ett nötskal berättar appen att den ska använda en högupplösta bild när den är på en högre upplösningsenhet.
Jag har tillhandahållit högupplösta bilder i bilder mappen så vi behöver uppdatera config.lua följaktligen. Ditt projekt är config.lua filen ska se ut som den nedan. Jag har utelämnat avsnittet push notification, vilket kommenteras.
application = content = width = 400, height = 600, scale = "letterbox", fps = 30, imageSuffix = ["@ 2x"] = 2,,
Med projektet och det dynamiska bildvalet ställs in, låt oss gå vidare till main.lua. Den här filen är startpunkten för varje app som är byggd med Corona SDK. I vårt spel kommer det att hålla tre rader kod.
Den första raden döljer statusfältet på iOS-enheter. Öppna main.lua och lägg till följande rad efter kommentaren -- Din kod här
.
display.setStatusBar (display.HiddenStatusBar)
Därefter börjar vi använda kompositören genom att kräva biblioteket i vårt spel. Vi gör detta genom att lägga till följande rad:
lokal komponist = kräver ("kompositör")
Därefter använder vi kompositören för att flytta till menyscenen. Vi flytta scener genom att ringa funktionen composer.gotoScene ()
, passerar värdet "Scene_menu"
som parameter. Värdet "Scene_menu"
är namnet på scenen och namnet på den fil som vi skapar i nästa avsnitt.
composer.gotoScene ( "scene_menu")
Komponist är det officiella scenhanteringsbiblioteket i Corona. Kompositör tillåter utvecklare att enkelt skapa en scen och övergång mellan scener. I två linjer kunde jag övergå från huvudplatsen till menyscenen. Om du vill läsa mer om Composer, besök Corona Composer Library Guide tillgänglig på Corona Labs Docs webbplats.
Menyscenen i vårt spel består av endast ett par element. Scenen kommer att innehålla en bakgrunds grafik, en titel och en startknapp. Vi använder Coronas inbyggda widgetbibliotek för att skapa startknappen. Med widgetbiblioteket kan vi snabbt och enkelt skapa vanliga användargränssnitt. I vårt spel använder vi det bara för att skapa knappen.
Skapa en ny fil i projektmappen för Highway Dodge, scene_menu.lua, och öppna den i din textredigerare. I stället för att börja från början, kommer vi att använda scenmallen som finns tillgänglig på Corona Labs Docs webbplats. Med sin mall kan vi flytta mycket snabbare. Gå över till Corona Labs Docs och kopiera / klistra in scenmallen till scene_menu.lua.
Lägg till widgetbiblioteket i vårt spel genom att lägga till följande rad, precis under kompositörsbiblioteket.
lokal widget = kräver ("widget")
Vi lägger till vår bakgrund med den grafik som du hämtade tidigare. Bakgrunden ska placeras i mitten av skärmen. I scenen: skapa ()
funktion och efter screenGroup
variabel deklareras, lägg till följande kod:
lokal bakgrund = display.newImageRect (sceneGroup, "images / background.png", 475, 713) background.x = display.contentCenterX background.y = display.contentCenterY
Därefter måste vi lägga till de tre körfält som representerar motorvägen. Vi gör detta genom att använda ett bord för att hålla banorna och skapa en för
slinga som löper tre gånger. Placera det här koden efter bakgrundsgrafen:
lokala banor = för i = 1,3 körfält [i] = display.newImageRect (sceneGroup, "images / lane.png", 79, 713) körfält [i] .x = (display.contentCenterX - 79 * 2 ) + (i * 80) banor [i] .y = display.contentCenterY slutet
För att säkerställa att banorna alltid är centrerade har jag placerat banorna på x-axeln med lite matte. Detta säkerställer att banorna förblir centrerade, oberoende av vilken enhet spelet körs på.
Vi lägger också till vår logotyp för Highway Dodge genom att placera ett bildobjekt nära toppen av skärmen.
lokal logo = display.newImageRect (sceneGroup, "images / logo.png", 300, 150) logo.x = display.contentCenterX logo.y = 75
Innan vi kan lägga till vår knapp widget måste vi skapa en funktion som svarar när knappen berörs. Vi heter namnet handleButtonEvent ()
och flytta spelaren till spelplatsen med composer.gotoScene ()
. Vi svarar bara när spelaren har lyft fingret från knappen eller på slutade
fasen av evenemanget.
Lokalt funktionshandtagButtonEvent (händelse) om ("slutade" == event.phase) sedan komponent.gotoScene ("scene_game", "slideLeft") ändänden
Med funktionen tillagd kan vi lägga till knappen. Vi skapar knappen genom att använda widget.newButton
och passerar några värden till den. Vi anger bredden och höjden på knappen, bildfilerna för knappen, texten som ska visas, teckensnittstypen, teckensnittstorleken och teckensnittsfärgen.
Vi berättar också Corona vilken funktion som ska ringas när knappen trycks ner och placerar den i mitten av skärmen. Källfilerna i denna handledning innehåller kommentarer som förklarar var och en av de värden som används för att ställa in knappen.
lokala btn_startPlaying = widget.newButton width = 220, height = 100, defaultFile = "images / btn-blank.png", overFile = "images / btn-blank-over.png", label = "Börja spela", font = system.defaultFontBold, fontSize = 32, labelColor = default = 0, 0, 0, över = 0, 0, 0, 0.5, onEvent = handleButtonEvent btn_startPlaying.x = display.contentCenterX btn_startPlaying.y = display .contentCenterY sceneGroup: insert (btn_startPlaying)
För att paketera upp menyplatsen måste vi ta bort spelplatsen när den går ut. När Corona flyttar mellan scener tar det inte alltid bort den föregående scenen. Utan dessa linjer kommer spelet alltid att vara i ett spel över scenen efter det har spelats en gång.
För att ta bort föregående scen får vi scennamnet och samtalet composer.removeScene ()
att ta bort det om det existerar. Lägg till följande kod till scenen: visa ()
fungera.
lokala prevScene = composer.getSceneName ("tidigare") om (prevScene) sedan composer.removeScene (prevScene) avsluta
Vi kan nu börja jobba på spelplatsen. Vi använder samma arbetsflöde som vi använde för att skapa menyscenen. Skapa en ny fil, scene_game.lua, och kopiera / klistra in scenmallen som finns tillgänglig på Corona Labs Docs. När du har koden på plats, öppna scene_game.lua i din favorit textredigerare.
För att göra kodningen lättare för spelet, kommer vi att använda widgetbiblioteket och fysikbiblioteket. Den senare används för kollisionsdetektering. Lägg till följande kod till scene_game.lua:
lokal widget = kräver ("widget") lokal fysik = kräver ("fysik") fysik.start () fysik.setGravity (0,0)
På den första och andra raden behöver vi widgetbiblioteket respektive fysikbiblioteket. Vi börjar då fysik och inaktiverar tyngdkraften. Vi behöver inte gravitation för vårt motorvägsspel, istället använder vi transition.to ()
att flytta bilarna.
I scenen: skapa ()
funktion, förklarar vi ett antal variabler som vi kommer att använda i spelet. Dessa variabler kommer att vara ansvariga för spelarens bil, körfält, fiend bilar och spelarpoäng. För att göra det enklare att läsa har jag lagt till några kommentarer.
-- "scen: skapa ()" funktionssektion: skapa (händelse) lokala banor = - skapa en tabell kallad banor lokal spelareCar - en variabel för spelarens bil lokal laneID = 1 - en variabel för landets id = - ett bord för att hålla fiendens bilar lokala fiendeCounter = 1 - start fiendens räknare vid 1 för att hålla reda på fiendens bilar lokala sendEnemyFrequency = 2500 - definierar hur ofta man skickar fiendens bilar i millisekunder lokala tmrToSendCars - en variabel för att hålla en referens till timern för att skicka bilar lokal spelareScore = 0 - starta spelarens poäng på 0 local playerScoreText - ett objekt för att hålla poängen textobjektets slut
Nedanför de variabla deklarationerna ställer vi upp funktionerna för spelet. Vi kommer att genomföra varje funktion i ett senare steg. Lägg till följande kod efter de variabla deklarationerna i scenen: skapa ()
fungera.
lokal funktion incrementScore () sluta lokal funktion moveCar (händelse) sluta lokal funktion sendEnemyCar () sluta lokal funktion onPlayAgainTouch () sluta lokal funktion onGlobalCollision (händelse) slut
Efter funktionerna lägger vi till bakgrunden och körfält. För banorna bifogar vi en händelselyttare till varje körfält för att få dem att reagera på beröringshändelser. När den berörs, lyssnar lyssnaren moveCar ()
fungera.
lokal bakgrund = display.newImageRect (sceneGroup, "images / background.png", 475, 713) background.x = display.contentCenterX background.y = display.contentCenterY för i = 1,3 körfält [i] = display.newImageRect (sceneGroup, "images / lane.png", 79, 713) banor [i] .x = (display.contentCenterX - 79 * 2) + (i * 80) banor [i] .y = display.contentCenterY banor [i ] .id = jag körfält [i]: addEventListener ("touch", moveCar) slutet
Med bakgrunden och körfältet är det dags att skapa ett textobjekt för att hålla spelarens poäng och skapa spelarbilen. Poängen kommer att vara högst upp på skärmen och spelarbilen kommer att vara placerad på den vänstra vägen. Dessutom gör vi spelarbilen ett dynamiskt fysikobjekt.
playerScoreText = display.newText (sceneGroup, "Score:" ... playerScore, 0, 0, native.systemFont, 36) playerScoreText.x = display.contentCenterX playerScoreText.y = 25 playerCar = display.newImageRect (sceneGroup, "images / playerCar. png ", 50, 100) playerCar.anchorY = 1 playerCar.x = lanes [1] .x playerCar.y = display.contentHeight physics.addBody (playerCar) playerCar.bodyType =" dynamic "
Därefter sätter vi en timer för att skicka ut en bil baserat på värdet av sendEnemyFrequency
variabel och skapa en runtime händelse lyssnare för globala kollisioner.
tmrToSendCars = timer.performWithDelay (sendEnemyFrequency, sendEnemyCar, 0) Runtime: addEventListener ("kollision", onGlobalCollision)
Vi kan äntligen lägga till funktionalitet i vårt spel. Det här avsnittet lägger till ytterligare kod till varje funktion som vi deklarerade i föregående avsnitt. Vi kommer igång med incrementScore ()
och sluta med onGlobalCollision ()
.
incrementScore ()
Denna funktion kallas när en fiendbil passerar av spelaren och övergången är klar. När den kallas, ökas spelarens poäng med 1. Lägg till följande implementering i incrementScore ()
fungera.
-- Denna funktion ökar spelarens poäng med 1. Denna funktion kallas när övergången till fiendens bil är klar och är avstängd. local function incrementScore () playerScore = playerScore + 1 playerScoreText.text = "Resultat:" ... playerScore slut
moveCar ()
De moveCar ()
funktion kallas när en körfält berörs. På slutade
fasen av evenemanget tar vi körfältets identifierare och flyttar bilen till rätt körfält. Vi återvänder Sann
i slutet för att indikera en lyckad touch händelse. Lägg till följande implementering i moveCar ()
fungera.
-- moveCar kommer att svara på touch-händelsen på banorna lokala funktionen moveCar (händelse) om (event.phase == "ended") då laneID = event.target.id - ta bort banans id som kommer att vara 1, 2 eller 3 transition.to (playerCar, x = lanes [laneID] .x, time = 50) - flytta spelarens bil till lämplig lane return true - för att indikera en lyckad touch händelse, returnera sanna änden
sendEnemyCar ()
De sendEnemyCar ()
funktion skapar en fiend bil, tilldelar bilen till en körfält, fäster en fysik kropp till bilen och använder transition.to ()
att skicka bilen mot undersidan av skärmen. För att komma igång, låt oss skapa fiendens bilobjekt.
enemyCars [enemyCounter] = display.newImageRect (sceneGroup, "images / enemyCar" ... math.random (1,3) ... ".png", 50, 100)
Därefter ställer vi x-och y-platsen för fiendens bil. Vi skapar också en om då
uttalande för att tilldela fiendens bil till samma lane spelarens bil är i 50% av tiden. Detta kommer att tvinga spelaren att flytta oftare och gör spelet roligare.
enemycars [enemyCounter] .x = lanes [math.random (1, # lanes)] x - placera bilen på en slumpmässig lane om (math.random (1,2) == 1) då fiendenCars [enemyCounter]. x = banor [laneID] .x; slutet - 50% av tiden, placera fiendens bil på spelarens bilväg. enemyCars [enemyCounter] .y = -125 - placera fienden från skärmen högst upp
Vi behöver också rotera fiendens bil så att den vetter ner och lägg till en kinematisk fysik kroppstyp till fiendens bil.
fiendenCars [enemyCounter]): skala (1, -1) - rotera bilarna så att de står inför fysik.addBody (enemyCars [enemyCounter]) - lägg till en fysik kropp till fiendens bilar fiendtliga bilar [enemyCounter] .bodyType = "kinematisk" - gör kropparna kinematiska
Med fiendens bil inrättad använder vi transition.to ()
funktion för att skicka fiendens bil ner en av banorna. När övergången är klar kallar spelet en funktion för att ta bort objektet. Jag ökar också variabeln enemyCounter
av 1 att hålla reda på antalet fiendens bilar i spelet.
transition.to (enemyCars [enemyCounter], y = display.contentHeight + enemyCars [enemyCounter] .höjd + 20, tid = math.random (2250,3000), onComplete = funktion (själv) display.remove (self); incrementScore (); slutet) - en övergång som flyttar fiendens bil mot skärmens botten. Vid fullbordandet avlägsnas fiendens bilobjekt från spelet. enemyCounter = enemyCounter + 1 - öka fiendens räknare med en för spårning
Slutligen vill vi att spelet blir snabbare över tiden. För varje annan bil som skickas, kommer spelet att återskapa tidtabellen och sätter det för att bli 200ms snabbare.
om (enemyCounter% 2 == 0) sedan sendEnemyFrequency = sendEnemyFrequency - 200 om (sendEnemyFrequency < 800) then sendEnemyFrequency = 800; end timer.cancel(tmrToSendCars) tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) end
onPlayAgainTouch ()
Den kortaste funktionen, onPlayAgainTouch ()
, returnerar spelaren till huvudmenyn. Detta är vad genomförandet av onPlayAgainTouch ()
funktionen ser ut som.
-- Låt spelaren återgå till menyns lokala funktion onPlayAgainTouch () composer.gotoScene ("scene_menu", "fade") - flytta spelaren till menyänden
onGlobalCollision ()
De onGlobalCollision ()
funktionen används för att upptäcka kollisioner mellan två fysikobjekt på skärmen. I vårt spel har vi bara två typer av fysikobjekt:
När dessa två objekt kolliderar, stoppar spelet alla timers, övergångar och händelselyttare. Dessutom visar spelet ett spel över scenen som gör att spelaren kan spela igen.
Först skapar vi en om då
uttalande som lyssnar på började
fas.
om (event.phase == "började") sluta sedan
I om då
uttalande, stoppar vi spelet. Vi pausar alla övergångar, avbryter timern, pausar fysiken (även om det inte behövs, det är ett bra rengöringssamtal) och tar bort händelseläsenaren från alla tre banor. Lägg till följande kod inuti om då
påstående:
transition.pause () timer.cancel (tmrToSendCars) physics.pause () för i = 1,3 gör banor [i]: removeEventListener ("touch", moveCar) slutet
Efter att spelmekaniken har slutat lägger vi till en ogenomskinlig rektangel och ett textobjekt som säger "Spel över!". Detta ger en bra visuell indikation på att spelet har slutat.
local gameOverBackground = display.newRect (sceneGroup, 0, 0, display.actualContentWidth, display.actualContentHeight) gameOverBackground.x = display.contentCenterX gameOverBackground.y = display.contentCenterY gameOverBackground: setFillColor (0) gameOverBackground.alpha = 0.5 local gameOverText = display .newText (sceneGroup, "Game Over!", 100, 200, native.systemFontBold, 36) gameOverText.x = display.contentCenterX gameOverText.y = 150 gameOverText: setFillColor (1, 1, 1)
För att paketera upp den globala kollisionsfunktionen lägger vi till knappen Spela igen som skickar spelaren tillbaka till menyn.
local playAgain = widget.newButton width = 220, height = 100, defaultFile = "images / btn-blank.png", overFile = "images / btn-blank.png", label = "Meny", font = system.defaultFontBold , fontSize = 32, labelColor = default = 0, 0, 0, över = 0, 0, 0, 0.5, onEvent = onPlayAgainTouch playAgain.x = display.contentCenterX playAgain.y = gameOverText.y + 100 scengrupp: sätt in (playAgain)
Kör programmet för att se om allt fungerar som förväntat. Du borde kunna spela spelet, fiendens bilar ska dyka upp från toppen av skärmen och din poäng ska öka för varje fiende bil du framgångsrikt undviker.
Tack för att du läste min handledning om att skapa Highway Dodge med Corona SDK. Du kan ladda ner källfilerna för detta spel från GitHub. Tänk på att du kan förbättra spelet ytterligare. Om du letar efter några förslag rekommenderar jag att du lägger till en annan körfält, lägger till fler typer av fienden och till och med lägger till några coola power ups.