Velkommen til den fjerde opplæringen i serien vår for å bygge et løpespill fra grunnen til Corona SDK. I denne delen skal vi legge til tyngdekraften, kollisjonsdeteksjon og evnen til å hoppe til spillsprite. La oss gå!
Forhåpentligvis har opplæringene hittil vært hjelpsomme og enkle å følge. Som alltid, hvis du har noen spørsmål, vær sikker på å legge igjen en kommentar! Siste gang vi gikk over hvordan å skape gode sprites fra spritesheets. I dag skal vi ta det vi lærte i den siste opplæringen og få det sprite-monsteret i vårt aktuelle spill. Når han er inne, lærer vi hvordan han skal kontrollere ham og gjøre spillet interaktivt. Måten jeg skal gjøre dette på er å ta kildekoden vi hadde fra bakgrunnsbevegelsen, og legg til våre monster animasjonsspørsmål først. Hvis du laster ned filene for opplæringen, vil du legge merke til at det er 2 mapper, kalt "gamle" og "nye". Gamle inneholder alle filene fra bakgrunnsbevegelsen som du trenger for å begynne å jobbe med denne opplæringen. Ny inneholder all koden og alt du vil ha når denne opplæringen er fullført. Så, gå videre og last ned filene og åpne main.lua-filen fra den gamle mappen. Jeg skal bryte opp alt vi gjør i tre seksjoner. Den første skal dekke organisasjonen av spillet vårt, som vi vil gjøre noen få endringer på. Den andre vil dekke å ta det vi lærte i å bruke sprites-opplæringen og implementere den her. Vi vil gå over den delen ganske raskt, da detaljene om hva som skjer, allerede er dekket. Den tredje delen vil gi vår lille fyr tyngdekraften, kollisjonsdeteksjon og evnen til å hoppe!
Frem til nå setter vi bildene våre i koden i den rekkefølgen vi vil at de skal vises på skjermen. Jo tidligere de kalles, jo lenger tilbake vil de vises i lagene på skjermen. Dette fungerer, men det er en bedre måte å gjøre dette på. Det vil ikke alltid være realistisk å sette hvert enkelt bilde i den eksakte rekkefølgen du vil at de skal vises, og du kan til enhver tid endre rekkefølgen som objekter vises på skjermen. Så åpner du main.lua-filen fra den gamle mappen, og vi begynner å gjøre noen endringer.
Det første vi skal gjøre er å legge til følgende linje øverst på siden rett under display.setStatusBar linje.
lokal sprite = krever ("sprite")
Deretter legger du til følgende to linjer rett under der vi opprettet skjermgruppen blokker:
lokal spiller = display.newGroup () local screen = display.newGroup ()
Skjermgruppespilleren skal være skjermgruppen som holder vår heltsprite og skjermgruppen vil være en skjermgruppe som holder alt annet. La oss legge inn noe mer kode og så skal jeg fullføre forklaringen.
Sett inn følgende kode under forløp der vi instantierer våre grunnblokker:
--lage vår sprite sheet lokale spriteSheet = sprite.newSpriteSheet ("monsterSpriteSheet.png", 100, 100) lokale monsterSet = sprite.newSpriteSet (spriteSheet, 1, 7) sprite.add (monsterSet, "running", 1, 6, 600, 0) sprite.add (monsterSet, "jump", 7, 7, 1, 1) - sett de forskjellige variablene vi vil bruke til vår monster sprite - også setter og starter den første animasjonen for monster local monster = sprite. newSprite (monsterSet) monster: prepare ("running") monster: play () monster.x = 110 monster.y = 200 - disse er 2 variabler som vil kontrollere fallende og hopping av monster monster.gravity = -6 monster .accel = 0 - rektangel brukt til vår kollisjon deteksjon - det vil alltid være foran monster sprite - slik vi vet om monsteret treffer inn i noe lokal kollisjonRect = display.newRect (monster.x + 36, monster .y, 1, 70) kollisjonRect.strokeWidth = 1 kollisjonRekt: setFillColor (140, 140, 140) kollisjonRekt: setStrokeColor (180, 180, 180) kollisjonRect.alpha = 0 - brukes til å sette everythin g på skjermen i skjermgruppen - dette vil la oss endre rekkefølgen som sprites vises på - skjermen hvis vi vil. Jo tidligere er det satt inn i gruppen, vil - det vil gå tilbake til skjermen: Sett inn (baksiden) skjerm: sett inn (bakgrunnsfarer) skjerm: sett inn (backgroundnear1) skjerm: sett inn (backgroundnear2) skjerm: sett inn (blokk) skjerm: sett inn monster) skjerm: sett inn (collisionRect)
Nå, la oss gå over den store kodenavn.
De to første delene vi skal hoppe over. Disse seksjonene oppretter bare vårt monster-sprite fra vårt sprite-ark. Hvis du har spørsmål om hva som skjer skjer det en rask gjennomgang av den siste opplæringen hvor vi gikk, og kom over å skape sprites fra sprite sheets. I neste avsnitt har jeg opprettet et grunnleggende rektangelformat kalt collisionRect, slik skal vi gjøre vår kollisjonssensor, slik at vårt monster kan samhandle med verden. I hovedsak er det som skjer ved å skape et usynlig firkant som går foran vårt monster. Hvis du gjør rektangelet synlig (det vil si bare endre alfa til 100) vil du se at det sitter rett foran monsteret og svinger litt over bakken.
Grunnen til at vi gjør dette er at det vil gi oss et kollisjonssystem som er lett å håndtere. Fordi vi gjør et uendelig løpsspill, er vi hovedsakelig opptatt av hva som foregår rett foran monsteret (normalt det som kommer bak ham, vil ikke drepe ham). Også løfter vi det litt av bakken slik at boksen aldri kolliderer med bakken under monsteret, bare ting foran den. Monsteret selv skal håndtere sammenstøtene med bakken, vi trenger bare noe for å håndtere kollisjonene med eksterne gjenstander som kan slå ham i fronten. Dette vil gjøre enda mer fornuftig i de neste par opplæringsprogrammene som vi legger til ting for ut monster å løpe inn.
Seksjonen etter det er hvor vi setter alt inn på skjermen. Så, skjermen er bare en skjermgruppe - det er ingenting magisk om det. Men ved å gjøre dette gir det oss en stor fordel i forhold til hvordan vi legger ting på skjermen før, og det er hvordan vi har kontroll over hvordan ting blir bestilt. Nå, uansett når vi opprettet sprites, vil de nå vises i den rekkefølgen vi legger dem inn i skjermgruppen skjerm. Så, hvis vi bestemte oss for at monstret skulle gå bak bakgrunnsobjektene, ville vi ganske enkelt måtte sette dem inn i skjermgruppen etter at vi har satt inn monsteret.
Deretter endrer du oppdateringen () for å se slik ut:
lokal oppdatering (event) updateBackgrounds () updateSpeed () updateMonster () updateBlocks () checkCollisions () ende
Dette vil ringe resten av funksjonene som vi må løpe for å sikre at alt er godt oppdatert. En ting å merke seg når du arbeider med oppdateringsfunksjonen er at ordren betyr noe. For vårt lille løpende spill er ordren ikke så viktig som det kalles tretti ganger i sekundet, så alt som oppdateres vil bli fanget ekstremt raskt. Også det er ingen viktige data at funksjonene ca ødelegger for hverandre. Det vil imidlertid være tidspunkter når du må være forsiktig med hvilken rekkefølge du legger inn ting. Dette gjelder spesielt når du har flere funksjoner som oppdaterer de samme variablene på forskjellige måter. Vanligvis skjønt dette er egentlig bare et spørsmål om å bruke sunn fornuft skjønt, og du vil kunne logisk gå gjennom hvilke ting som skal håndteres først.
Her er resten av funksjonene som vil gjøre det arbeidet vi nettopp ringte fra oppdateringsfunksjonen. Sett dem under oppdateringsfunksjonen. Husk å lese kommentarene som jeg vil bruke dem til å beskrive hva som skjer.
funksjon checkCollisions () wasOnGround = onGround - sjekker for å se om kollisjonRect har kollidert med noe. Det er derfor det løftes av bakken - litt, hvis det treffer bakken som betyr at vi har løp inn i en vegg. Vi sjekker dette ved å sykle gjennom --all av bunnstykkene i blokkgruppene og sammenligne deres x- og y-koordinater med kollisjonenesRect for a = 1, blocks.numChildren, 1 gjør hvis (kollisjonRect.y - 10> blokkerer [ a] .y - 170 og blokkerer [a] .x - 40 < collisionRect.x and blocks[a].x + 40 > kollisjonRect.x) så hastighet = 0 ende - dette er hvor vi sjekker for å se om monsteret er på bakken eller i luften, hvis han er i luften så kan han ikke hoppe (beklager, ingen dobbel - jumping for vårt lille monster, men hvis du vil at han skal kunne doble hopp som Mario, så trenger du bare - for å gjøre en liten justering her, ved å legge til en annen variabel som heter noe som harJumped. Sett den til falsk normalt, og snu den til - troll når dobbelt hoppet er gjort. På den måten er han begrenset til 2 hopp per hopp. --Gjennom vi sykler gjennom blokkgruppene og sammenligner x- og y-verdiene for hver. For a = 1, blokker .numChildren, 1 gjør om (monster.y> = blokker [a] .y - 170 og blokkerer [a] .x < monster.x + 60 and blocks[a].x > monster.x - 60) så monster.y = blokker [a] .y - 171 onGround = ekte pause annet onGround = falsk ende endeendingsfunksjonsoppdateringMonster () - om vårt monster hopper og deretter bytte til hoppingsanimasjonen --if ikke fortsett å spille den løpende animasjonen hvis (onGround) da - hvis vi er alread på bakken, trenger vi ikke å forberede noe nytt hvis (varOnGround) så annet monster: forberede ("kjører") monster: play () end else monster: forberede ("hoppe") monster: play () ende hvis (monster.accel> 0) så monster.accel = monster.accel - 1 end - oppdatere monsternes posisjon accel brukes til vårt hopp og - gravity holder monsteret kommer ned. Du kan spille med de to variablene - for å lage mange interessante kombinasjoner av gameplay som situasjoner med lav tyngdekraft monster.y = monster.y - monster.accel monster.y = monster.y - monster.gravity - oppdatere kollisjonen Rect å holde seg foran monster collisionRect.y = monster.y ende - dette er funksjonen som håndterer hoppeventene. Hvis skjermen er berørt på venstre side - gjør det at monster hoppe-funksjonen berøres (hendelse) hvis (event.phase == "startet") så hvis (event.x < 241) then if(onGround) then monster.accel = monster.accel + 20 end end end end
Legg merke til at berørt funksjon aldri kalles. På bunnen av koden rett under der du bruker timeren som kaller oppdateringsfunksjonen, sett denne koden:
Runtime: addEventListener ("touch", rørt, -1)
La oss se på noen få ting fra koden vi bare har lagt inn. Den berørte funksjonen passerer i en hendelse. Hver "hendelse" har egne egenskaper. Når vi sier event.phase == "startet" Vi forteller Corona at vi vil bli varslet så snart brukeren berører skjermen. Tvert imot hvis vi hadde sagt "endte" i stedet for å begynne, ville vi fortelle Corona å ikke varsle oss til brukeren hadde løftet fingeren fra skjermen. Også lagret i hendelsen er koordinatene til berøringen. Det er derfor viktig å bruke startet og slutt. Ønsker du plasseringen av når brukeren først berører skjermen, eller når han lar seg gå? I de fleste spillssituasjoner vil du vite så snart brukeren berører skjermen, men ikke alltid. For en fullstendig henvisning til berøringshendelsene kan du gå her (https://developer.anscamobile.com/reference/index/events/touch).
Så når du kjører dette, vil du legge merke til at du bare hopper hvis du berører venstre side av skjermen. Grunnen til at vi gjør det er fordi vi vil reservere høyre side av skjermen for andre ting, som å skyte ildkuler. Det faller ikke under dette prosjektets omfang, men vi kommer snart snart! Med alt det der inne bør vi nå være godt å gå.
Med alt i sitt sted bør du nå ha et monster som kan løpe og hoppe på bakken! Sakte, vår lille opplæring begynner å føles som et spill! Som alltid, hvis du har noen spørsmål, gi meg beskjed i kommentarfeltet nedenfor og takk for at du følger med!