Parallax rulling er en enkel og effektiv måte å skape dybden på dybden i et 2D-spill. Enten du utvikler en vertikal skytespill eller en horisontal side scrolling platformer, er parallax rulling et forsøkt og ekte spillpakke som i stor grad vil øke nedsenking og grafisk effekt av prosjektet ditt.
I denne opplæringen vil jeg dekke grunnleggende ved parallaxrulling, sammen med flere implementeringsmetoder, slik at du vil kunne trygt og vellykket introdusere parallaxrulling i ferdighetssettet ditt, uavhengig av ditt nåværende ferdighetsnivå.
Prøv demonstrasjonen nedenfor for å se scener som bruker horisontal, vertikal, begge og ingen parallellrulling. Klikk på demoen for å aktivere den, bruk talltastene for å bytte scener og piltastene for å flytte mellomskipet (for de aktuelle scenene).
Parallax er definert som Den tilsynelatende forskyvningen av et observert objekt på grunn av endring i observatørens posisjon. Ved 2D-parallellrulling endres observatørens posisjon bare langs x- og y-aksene. Kun et objekts fart og plassering vil endres med observatørens posisjon, da skalering av objektet krever en endring langs z-aksen.
Takashi Nishiyamas Moon Patrol er allment kreditert som det første spillet for å ha 2D-parallellrulling, men teknikken eksisterte i tradisjonell animasjon så tidlig som 1933. Ved hjelp av et multiplanekamera kunne animatører lage en ikke-stereoskopisk 3D-effekt som skapte illusjonen av dybde ved å tillate forskjellig kunstegenskaper til å bevege seg med forskjellige hastigheter i forhold til den oppfattede avstanden fra kameralinsen. Slik oppnås parallaxrulling i moderne videospill, men i stedet for et multiplanekamera blir scener samlet med flere lag og et enkelt spillkamera eller -visning.
Ved å dele bakgrunns- og forgrunnselementene i et spill i forskjellige lag, er det mulig å kontrollere hastigheten og plasseringen av disse elementene basert på lagene deres. Observatøren, i dette tilfellet, er spilleren, og spillkameraet blir fokusert på et bestemt punkt eller objekt, mens bakgrunnen og forgrunnslagene beveger seg tilsvarende.
Dette fokuspunktet beveger seg med "normal" hastighet, eller hastigheten som er definert av gameplay. Bakgrunnsobjekter beveger seg langsommere enn fokuspunktet, mens forgrunnsobjekter beveger seg raskere enn fokuspunktet. Dette resulterer i en dybdefølelse som gjør at en 2D-scene føles mer nedsenkende.
I vårt første eksempel har vi en veldig enkel scene av en gate om natten som har horisontal rulling uten interaktive elementer. De forskjellige bakgrunnslagene beveger seg ved forhåndsbestemte hastigheter langs x-aksen. For nå, la oss fokusere på det grunnleggende ved parallaxrulling uten å bekymre deg for noen spillerbevegelse eller skiftende visninger.
La oss først bryte ned de enkelte elementene og egenskapene til vår scene. Spillvinduet er 600x300px, og våre kunstmidler har hver sin bredde på minst 600px. Ved å bruke bakgrunnselementer som er større enn spillvinduet, kan vi forhindre at hele aktiva blir synlig til enhver tid. Siden lagene er flislagt, vil dette bidra til å forhindre for mye åpenbar gjentagelse, da den samme egenskapen ruller på ubestemt tid.
De fire lagene som utgjør vår første scene.Vår scene består av fire lag. I dette eksemplet definerer nummeret på laget rekkefølgen der aktiva trekkes til skjermen, i tillegg til bevegelseshastigheten. Hvis dette var en side-scrolling platformer, så ville vårt spillerobjekt eksistere på toppen av lag 3. Dette laget ville være fokuspunktet til observatøren, og vil også diktere hastigheten til bakgrunnen og forgrunnslagene.
Lag 2 beveger seg sakte enn Lag 3, og Lag 1 beveger seg sakte enn Lag 2. Lag 4 eksisterer som forgrunnslag, slik at det beveger seg raskere enn fokuspunktet på Lag 3.
Det er flere måter du kan implementere denne typen parallax rulleteknikk. I dette eksemplet beveger lagene seg til forhåndsbestemte hastigheter uten å referere til hverandre. Hvis du planlegger å ha flere scener med varierende mengder bakgrunns- og forgrunnslag, vil det være best å definere laghastigheter ved å lese nåværende hastighet for fokuspunktlaget. For eksempel, hvis fokuspunktet er Layer 3 og beveger seg med en hastighet på 5
, så vil hvert suksessivt bakgrunnslag bevege seg med en hastighet mindre enn 5
. Noen forgrunnslag ville bevege seg med en hastighet større enn 5
.
// Variabler focal_point_speed = 5; layer_difference = 1; // Fokuspunktlag layer3.hspeed = focal_point_speed; // Bakgrunnslag layer2.hspeed = layer3.hspeed - layer_difference; layer1.hspeed = layer2.hspeed - layer_difference; // Forgrunnslag layer4.hspeed = layer3.hspeed + layer_difference; layer5.hspeed = layer4.hspeed + layer_difference;
Mens parallaxrulling oftest brukes med horisontale bakgrunner, kan den også brukes i vertikale scener, som i dette romskytespillet. Det kan være mer effektive måter å lage et stjernefelt på, men parallaxrulling får jobben gjort.
Det viktigste å ta bort fra dette vertikale eksempelet er at parallellrulling virker i alle fire retninger langs x- og y-aksene. (Vi ser bare hvor viktig dette er i vårt tredje og siste eksempel.)
Denne scenen har fire bakgrunnslag: en statisk svart bakgrunn og tre samlinger av stjerner i forskjellige størrelser. Den statiske bakgrunnen beveger seg ikke, og hvert suksessivt lag av stjerner vokser større og beveger seg raskere, med det siste lag av stjerner som i siste rekke bestemmer den vertikale hastigheten til fokuspunktet, spillerens romskip. Denne typen parallaxrulling gjør det mulig for oss å simulere dybden av rom samtidig som vi simulerer fremoverbevegelse. Spillerens skip flytter aldri opp på skjermen, men du får fortsatt en følelse av fartsfylt rom som reiser.
Nå som vi har en bedre forståelse av hva parallaxrulling handler om, kan vi begynne å konstruere en scene der både horisontal og vertikal rulling er implementert, sammen med en spillvisning som sporer bevegelsen til et spillerkontrollert objekt.
I demonstrasjonen øverst i opplæringen er denne scenen delt i to eksempler. Den første versjonen viser hvordan scenen er som uten parallaxrulling. Den andre versjonen har full vertikal og horisontal parallaxrulling, og det illustrerer virkelig hvordan parallaxrulling kan legge til mye nedsenking og dybde til det som opprinnelig var en veldig flat og livløs scene.
Det viktigste aspektet av dette eksempelet er spillerbevegelse og spillvisningen. Fordi bakgrunnen vår ikke lenger er låst inn i en forhåndsbestemt hastighet eller skjermstilling, må vi beregne hvert lags fart og posisjon i forhold til visningsvinduet når spilleren beveger seg rundt.
Opprinnelsen til visningsvinduet ligger øverst til venstre på (X, Y)
. Hvert bakgrunnsobjektets aktivitets opprinnelse er i øvre venstre hjørne av spritet på (0,0)
. Ved å finne de nåværende x- og y-koordinatene i visningsvinduet i forhold til spillverdenen, kan vi utføre en beregning for å bestemme hvor et bakgrunnslags opprinnelse skal plasseres i scenen. Denne posisjonen endres når visningsvinduet beveger seg ut fra denne beregningen.
Ved å bruke forskjellige verdier i beregningen av hvert lag, kan vi flytte hvert lag med forskjellige hastigheter, avhengig av hvor raskt spilleren beveger seg.
Koden for å tegne laget som ligger rett bak spillerobjektet, er i følgende format: draw_background_tiled_horizontal (lag, x, y)
hvor draw_background_tiled_horizontal ()
er en enkel funksjon for å tegne en flislagt eiendel på et bestemt sted, og bg_ex_3_2
er vårt lag aktiva.
// Lag 3 draw_background_tiled_horizontal (bg_ex_3_2, view_xview [view_current] / 2.5, (view_yview [view_current] / 10) + 300);
X-verdien av laget i dette tilfellet er definert av X-verdien til den nåværende visningen divideres med en verdi på 2.5
, skaper en horisontal bevegelse som beveger seg litt langsommere enn bevegelsen av selve visningen.
På samme måte er Y-verdien av laget definert av Y-verdien av den nåværende visningen divideres med 10
. Y-verdien av laget blir deretter økt med 300
å plassere det riktig i forhold til spillverdenen. Uten denne ekstra tillegg av 300
, aktiva vil vises nær toppen av spillverdenen i stedet for nær bunnen der vi vil at den skal være.
Disse verdiene vil selvsagt variere i prosjektet ditt, men det viktige å huske er at hastigheten på lagets bevegelse øker etter hvert som divisjonsnummeret øker, men bare opp til et bestemt punkt. Ved å bruke divisjon, kan laget bare bevege seg med samme hastighet eller langsommere enn spillerenes hastighet.
De to lagene bak dette laget beveger seg sakte, så divisjonstallene er mindre:
// Lag 1 draw_background_tiled_horizontal (bg_ex_3_0, view_xview [view_current] / 1.5, (view_yview [view_current] / 2.5) + 175); // Lag 2 draw_background_tiled_horizontal (bg_ex_3_1, view_xview [view_current] / 2, (view_yview [view_current] / 5) +250);
For å lage et lag som beveger seg raskere enn fokuspunktet, for eksempel et forgrunnslag, må det gjøres en liten endring. Det er ikke noe forgrunnslag i dette eksemplet, og fokuspunktlaget er faktisk bare synlig nederst på skjermen. Spilleren kan fly opp og over fokuspunktet, som er bakken, slik at skipet selv blir fokuspunktet. Vi refererer til bakken som fokuspunkt i dette eksemplet fordi bakken er det eneste laget som beveger seg i samme oppfattede fart som romskipet. Det er her vi får vår sanne følelse av fart i scenen.
Jordlaget beveger seg raskere enn selve visningen, så koden som tegner dette laget er litt annerledes enn de andre bakgrunnslagene:
// Brennpunktslag (bakken) draw_background_tiled_horizontal (bg_ex_3_3, -view_xview [view_current] * 1,5, -view_yview [view_current] + 700);
Med lag som beveger seg raskere enn visningen tar vi negativ X og Y-verdier av den nåværende visningen, og multipliser dem med noe verdi. Det er ingen divisjon involvert i å beregne hastigheten til forgrunnslag. I dette eksemplet beveger jordlaget seg i en horisontal hastighet som er en og en halv ganger raskere enn hastigheten på visningsvinduet. Ingen multiplikasjon utføres på lagets vertikale hastighet, slik at den beveger seg i samme hastighet som visningen. En tilleggsverdi på 700
legges til lagets Y-verdi for å plassere det på ønsket sted nær bunnen av spillverdenen.
Parallax rulling er en enkel, men svært effektiv måte å legge til illusjonen av dybden til et 2D-spill. Jeg håper eksemplene i demonstrasjonen har vist hvor effektivt det kan være, og jeg håper selvstudiet har vist hvor enkelt det er å implementere!