Bygg et Endless Runner-spill fra grunnen Bakgrunnsbevegelse

Velkommen til den andre opplæringen i serien vår om å bygge et løpespill fra grunnen til Corona SDK. I denne delen skal vi gå over hvordan du raskt får et grunnleggende bakgrunnsrullenivå oppe og går. Åpne teksteditoren din og la oss komme i gang!


Forutsetninger

Hvis du ikke allerede har sett den første opplæringen i denne serien, sjekk den ut veldig fort før du går videre til denne. Hvis du har litt erfaringskoding, så vil du være god til å hoppe raskt gjennom hele første tut, men hvis du ikke har det, bør det være verdt tid å se på noen av grunnleggende programmering med Lua og Corona SDK.


Prosjektoppsett

Så det første som vi trenger å dekke er build.settings-filen. Dette er en fil som må gå i samme mappe som main.lua-filen, og er det vi bruker til å angi noen av våre programspesifikasjoner. Nå, avhengig av hvilken plattform du jobber med (Android eller iOS), vil din build.settings-fil brukes til å angi forskjellige ting. For eksempel må Android-utviklere håndtere sin applikasjons manifestfil og deres tillatelser, mens iOS-utviklere har sin * .plist-fil å bekymre seg for. Build.settings-filen er hvor mange av disse programnivåinnstillingene håndteres. En av de fine tingene med Corona SDK er at vi kan kombinere vår Android og iOS build.settings-informasjon til samme build.settings-fil. På denne måten, hvis du jobber på begge typer enheter, trenger du ikke å administrere flere build.settings-filer. For våre formål akkurat nå skal vi bare bruke filen build.settings for å sette inn enhetens orientering. Så lag en ny fil som heter build.settings i samme mappe som du skal ha din main.lua-fil og sett denne koden inn i den:

 --Legg merke til at du kan bruke kommentarer i dette avsnittet også settings = orientation = default = "landscapeRight", støttet = "landscapeRight", "landscapeLeft",,

Dette gir oss en landskapsrettet enhet på både iOS- og Android-enheter. Koden er ganske rett frem og vi vil gå over flere innstillinger som du vil bruke i fremtidige opplæringsprogrammer, men for nå bør dette være alt vi trenger for å gå videre. Hvis du vil grave dypere på egenhånd, kan du finne alle alternativene for build.settings her. For å sikre at filen fungerte, la oss gjøre en rask test i simulatoren. Åpne din main.lua-fil og sett denne koden inn der:

 --Denne linjen vil fjerne statuslinjen øverst på skjermen, - noen programmer du kanskje vil beholde den inn, men ikke for spill! display.setStatusBar (display.HiddenStatusBar) lokal testRect = display.newRect (0,0,50,50) testRect: setFillColor (150,0,0);

Så, etter at du har lagt alt sammen, hvis din build.settings er på riktig sted, bør du ha noe som ser slik ut:

Hvis enheten er oppreist (portrettmodus), og ikke legger på siden som ovenfor (liggende modus), har noe gått galt. Men forhåpentligvis er det ikke tilfellet som koden ovenfor er alt det er til det. Så, nå som det er ute av veien, kan vi fortsette å få spillet vårt i gang. Målet for hver veiledning er at vi skal ha en ny arbeidsgruppe. Hver vil bygge på sist, men etter hver iterasjon vil du ha noe som burde være spillbart.


Legge til en bakgrunn

Det første vi skal ønske å gjøre, er å få nivået vårt i bevegelse. Vi skal ha flere lag i vårt spill som skal rulle på forskjellige hastighetsnivåer. Dette kommer til å gi oss en illusjon av hva vi liker å kalle parallax rulling. Når du kjører programmet i simulatoren, fortsett og velg iPhone for nå (hvis du ikke allerede har gjort det). Endre dette ved å gå til Vindu> Vis som> iPhone i simulatoren. Aktivene er utformet for en enhet som kjører med en oppløsning på 480x320px. Det er selvfølgelig måter å sørge for at det fungerer for alle oppløsninger, men for vår testformål holder vi bare med iPhone-simulatoren. Gå videre og sett denne koden i programmet ditt:

 --tar bort skjermlinjen øverst på skjermbildet display.setStatusBar (display.HiddenStatusBar) - legger et bilde til vårt spill sentrert på x og y koordinater lokale backbackground = display.newImage ("images / background.png") backbackground. x = 240 backbackground.y = 160 lokale backgroundfar = display.newImage ("images / bgfar1.png") backgroundfar.x = 480 backgroundfar.y = 160

For dette å jobbe, gå videre og bruk bildene jeg har gitt. For at koden skal fungere som den er, må du plassere bildene i en mappe som heter bilder. Bildemappen skal være i samme mappe som filen main.lua og build.settings. Når du gjør det, bør du få en skjerm som ser slik ut:

Legg merke til hvordan bakgrunnsbildbildet er foran backbackground? Tenk deg å stable flere plater oppå hverandre. Jo mer du stabler på, jo mer du har dekket den første platen, har du stablet alt på til å begynne med. Dette gjelder også med bilder og tekst som du legger inn i koden din. Hver gang du vil legge til noe på skjermen, med mindre annet er regissert, vil det ekstra elementet dekke alt du allerede har stablet på. La oss gå videre og stable noen flere ting på vår skjerm. Legg dette til koden din under de andre linjene:

 lokal bakgrunnsfil = 1

Nå skal vi ha et annet lag stablet på toppen slik:

Nå, når du ser på dette, skal du legge merke til at selv om vi la til 2 forekomster av bgnear2.png, vises bare en av dem på skjermen. Grunnen til at vi gjør ting dette, vil bli litt mer opplagt når vi begynner å flytte alt rundt. For nå, gå videre og bytt visning fra iPhone til iPhone 4 på samme måte som før. Fordi vi utformet våre bilder rundt oppløsningen til en iPhone uten nettlinje (for eksempel 480x320px), skifter vi nedover, og vi kan se mer av det som skjer. Hvis vi bytter til en høyere oppløsning, for eksempel iPhone 4 (f.eks. 960x640px). Bytt til iPhone 4-oppløsningen, og du bør se dette nå:

Når vi vil se hva som skjer, vil bytte til større visning være svært nyttig. Legg merke til at bare fordi du ikke ser noe, betyr det ikke at ingenting skjer. Nå som vi har disse bakgrunnsbildene der ute, la oss få dem til å flytte. Når jeg går gjennom veiledningene, vil jeg prøve å dokumentere alt som skjer inni koden i seg selv, så hvis du noen gang ikke er sikker på hva noe gjør, er det sikkert å lese kommentarene i koden! Nå legger du til følgende under koden som er lagt til:

 --Oppdateringsfunksjonen vil kontrollere mest alt som skjer i spillet vårt - dette vil bli kalt hver ramme (30 bilder per sekund i vårt tilfelle, som er Corona SDK-standard) Lokal funksjonoppdatering (hendelse) --updateBackgrounds vil ringe en funksjon laget spesielt for å håndtere bakgrunnsbevakningsoppdateringenBackgrounds () end-funksjonoppdateringBackgrounds () --far bakgrunnsbevakning backgroundfar.x = backgroundfar.x - (.25) --nær bakgrunnsbevegelse backgroundnear1.x = backgroundnear1.x - (3) --if Sprite har flyttet av skjermen flytte den tilbake til den andre siden, så den vil gå tilbake hvis (backgroundnear1.x < -239) then backgroundnear1.x = 760 end backgroundnear2.x = backgroundnear2.x - (3) if(backgroundnear2.x < -239) then backgroundnear2.x = 760 end end --this is how we call the update function, make sure that this line comes after the --actual function or it will not be able to find it --timer.performWithDelay(how often it will run in milliseconds, function to call, --how many times to call(-1 means forever)) timer.performWithDelay(1, update, -1)

Når du kjører, kjør det først mens du fortsatt er i iPhone 4-visningen. Dette vil la deg se hva som egentlig skjer med alle de forskjellige sprites som vi beveger oss rundt. Når du har sett på det i denne visningen, går du videre og bytter tilbake til vanlig iPhone-visning slik at du kan se hvordan det egentlig ser ut. Med alt det der inne bør du nå ha alt som beveger seg! Nå et par ting å se på før vi går videre. Legg merke til hvordan det er bare én forekomst av bakgrunnsfarer, men det er to forekomster av bakgrunnsgenerering? Dette er noe som er helt opp til deg. Grunnen til at det er to er det fordi for den nærmere bakgrunnen (for eksempel trær som flyr av), vil vi gjenta det igjen og igjen. For den lange bakgrunnen ønsket jeg at det skulle være noe som vil passere veldig sakte og ikke gjenta seg selv (for eksempel vil du vanligvis bare gjøre dette for bakgrunner som er langt tilbake, det gir nivåer en unik følelse). Dette er noe du vil gjøre når rullingsnivået ditt kommer til å få slutt på det. Hvis du virkelig ville ha en never ending scroller, ville du ønsker å ta samme tilnærming som du gjorde for nær bakgrunn og sette to ved siden av. Ved å plassere to ved siden av hverandre, eller tre eller hvor mange du vil, lar det deg skape tilsynelatende store verdener med svært små ressurser. Det eneste vi må gjøre er å flytte sprite tilbake til den andre siden av skjermen.

Den neste tingen vi skal gjøre er å legge til bakken. Dette skal ta noen få skritt, men vi går sakte og sørger for at alt blir satt på rett sted. Hvis du ikke gjorde den første opplæringen og ikke forstår hvordan du bruker grupper eller forstår hva de er, vil det være en god tid å sjekke det ut. Her er koden til plop in (sett den rett under koden der vi konfigurerer backgroundnear2, før oppdateringsfunksjonen):

 --opprett en ny gruppe for å holde alle blokkene våre lokale blokker = display.newGroup () - sett opp noen variabler som vi skal bruke til å plassere bakken, lokal grunnMin = 420 lokal bakkeMax = 340 lokal grunnLevel = grunnMin - dette for sløyfe vil generere alle dine bunnstykker, vi skal - lage 8 i det hele tatt. for a = 1, 8, 1 gjør isDone = false - sett et tilfeldig tall mellom 1 og 2, dette er hva vi skal bruke til å bestemme hvilken - tekstur som skal brukes til våre sprites. Å gjøre dette vil gi oss tilfeldige grunner - stykker så det virker som bakken fortsetter for alltid. Du kan ha så mange forskjellige - teksturer som du vil. Jo mer du har jo mer tilfeldig det vil være, bare husk å - opp tallet i math.random (x) til hvor mange teksturer du har. NumGen = math.random (2) lokal newBlock-utskrift (numGen) hvis (numGen == 1 og isDone == false) og newBlock = display.newImage ("images / ground1.png") isDone = sann ende hvis (numGen == 2 og isDone == false) da newBlock = display.newImage ("images / ground2.png") isDone = true end - nå at vi har riktig bilde for blokken vi skal - for å gi det noen medlemsvariabler som vil hjelpe oss med å holde oversikt over hver blokk og plassere dem der vi vil ha dem. newBlock.name = ("block" ... a) newBlock.id = a - fordi a er en variabel som endres hver runde vi kan tildele - verdier til blokken basert på a. I dette tilfellet ønsker vi x-posisjonen å - plasseres bredden på en blokk fra hverandre. newBlock.x = (a * 79) - 79 newBlock.y = groundLevel blokker: sett inn (newBlock) slutten

Kommentarene i koden skal hjelpe deg å forstå hva alt gjør så langt. Forhåpentligvis ser det som du ser på nå noe slikt ut:

Nå er det siste som vi trenger å gjøre, å begynne å få blokkene i bevegelse. La oss gå videre og legge til koden for det. Sett inn denne koden etter slutten av oppdateringsfunksjonen:

 funksjonsoppdateringBlokker () for a = 1, blokker.numBørn, 1 gjør om (a> 1) og newX = (blokker [a - 1]). x + 79 annet newX = (blokker [8]). if ((blokkene [a]). x < -40) then (blocks[a]).x, (blocks[a]).y = newX, groundLevel else (blocks[a]):translate(-5, 0) end end end

Før noe vil flytte, må vi være sikker på at vi faktisk kaller funksjonen fra oppdateringsfunksjonen. Så, inne i oppdateringsfunksjonen under oppdateringsBackgrounds () -linjen, ring funksjonaliseringsblokkene (). Med det der skal vi ha alt som beveger seg nå. Legg merke til at i stedet for å flytte blokkene manuelt, brukte vi i stedet oversettelsesfunksjonen. Denne funksjonen er tilgjengelig for ethvert objekt vi lager via newImage-samtalen. Enten metode vil fungere, så bruk den ene eller den andre, eller bruk en blanding. En annen ting du bør merke er at det er et mellomrom mellom noen av blokkene. Dette skjer fordi vi plasserer plasseringen av de nye blokkene rett ved siden av den gamle plasseringen av den siste blokken. Problemet er at når vi gjør det på denne måten, prøver vi å plassere det ved siden av et bevegelige objekt, så vi kan ikke alltid slå rett ved siden av det. Dette problemet vil bli enda større når vi prøver å øke reisens hastighet på blokkene, jo raskere de beveger seg, desto større vil gapet bli. Dette problemet kan løses ved å bare legge til en hastighetsvariabel og gjøre beregningene våre basert på den hastigheten. Gå tilbake til kodelinjene der vi initialiserte variablene groundMin og groundMax, og legg til dette:

 lokal hastighet = 5;

Deretter erstattes funksjonene updateBlocks () og updateBackgrounds () med disse:

 funksjonsoppdateringBlokker () for a = 1, blokker.numHolder, 1 gjør om (a> 1) og newX = (blokker [a - 1]). x + 79 annet newX = (blokker [8]). x + 79 - hastighets ende hvis ((blokkene [a]). x < -40) then (blocks[a]).x, (blocks[a]).y = newX, (blocks[a]).y else (blocks[a]):translate(speed * -1, 0) end end end function updateBackgrounds() --far background movement backgroundfar.x = backgroundfar.x - (speed/55) --near background movement backgroundnear1.x = backgroundnear1.x - (speed/5) if(backgroundnear1.x < -239) then backgroundnear1.x = 760 end backgroundnear2.x = backgroundnear2.x - (speed/5) if(backgroundnear2.x < -239) then backgroundnear2.x = 760 end end

Med de oppdaterte funksjonene, bør blokkene dine bevege seg pent uten hull i det hele tatt!

En siste ting å gjøre dette mer spilllignende. Gå tilbake i oppdateringsfunksjonen og sett inn denne linjen med kode etter oppdateringsfunksjonene:

 hastighet = hastighet + .05

Når det er der inne, vil du kunne se nivået raskere før øynene dine! Den eksakte verdien selvfølgelig er bare et eksempel, hvor fort du oppdaterer spillet, avhenger av spillet ditt og målgruppen din. Alt som er igjen på dette punktet, kaster inn en helt og noen hindringer, og vi har oss selv et spill. Det vil komme senere skjønt, da dette bryter opp prosjektet for nå. Å få alt som kjører, var ikke så ille, og vi vil fortsette å legge til mye funksjonalitet hver iterasjon. Husk å sjekke tilbake for neste opplæring, og hvis du har spørsmål eller tilbakemelding, gi meg beskjed i kommentarene nedenfor!