Parallax Scrolling Ett enkelt, effektivt sätt att lägga djup i en 2D-spel

Parallax rullning är ett enkelt och effektivt sätt att skapa djup illusion i ett 2D-spel. Oavsett huruvida du utvecklar en vertikal skytt eller en horisontell sidrullningsplattform, är parallaxrullning ett riktigt spelkrav som avsevärt ökar fördjupningen och den grafiska effekten av ditt projekt. 

I denna handledning täcker jag grunderna för parallaxrullning, tillsammans med flera genomföringsmetoder, så att du säkert kan introducera parallax i din färdighetssätt, oavsett din nuvarande kompetensnivå.

demo

Prova demon nedan för att se scener som använder horisontell, vertikal, både och ingen parallellrullning. Klicka på demo för att aktivera den, använd sedan sifferknapparna för att växla scener och piltangenterna för att flytta rymdskeppet (för lämpliga scener).

Vad är Parallax Scrolling?

Parallax definieras som Den uppenbara förskjutningen av ett observerat objekt på grund av en förändring i observatörens position. Med 2D-parallellrullning ändras observatörens position endast längs x- och y-axlarna. Endast ett objekts hastighet och plats kommer att förändras med observatörens läge, eftersom skalning objektet skulle kräva en förändring längs z-axeln.

Takashi Nishiyama s Moon Patrol är allmänt krediterad som det första spelet som har 2D-parallellrullning, men tekniken fanns i traditionell animering så tidigt som 1933. Med hjälp av en multiplanekamera kunde animatörer skapa en icke-stereoskopisk 3D-effekt som skapade illusionen av djupet genom att tillåta olika konsttillgångar att flytta med olika hastigheter i förhållande till det uppfattade avståndet från kameralinsen. Så här samlas parallaxrullning i moderna videospel, men i stället för en multiplanekamera monteras scener med flera lager och en enda spelkamera eller -vyn.

Genom att dela bakgrunden och förgrundselementen i ett spel i olika lager är det möjligt att styra hastigheten och positionen för dessa element baserat på deras lager. Observatören är i detta fall spelaren och spelkameran är fokuserad på en viss punkt eller ett objekt, medan bakgrunds- och förgrundslagen flyttas i enlighet därmed. 

Denna fokuspunkt rör sig med "normal" hastighet eller den hastighet som definieras av spelningen. Bakgrundsobjekt flyttas långsammare än fokuspunkten medan förgrundsobjekt flyttas snabbare än fokuspunkten. Detta resulterar i en djup illusion som gör att en 2D-scen känns mer nedsänkt.

Exempel 1: Horisontell Parallax Scrolling

I vårt första exempel har vi en mycket enkel scen på en gata på natten som har horisontell rullning utan interaktiva element. De olika bakgrundslagen rör sig vid förutbestämda hastigheter längs x-axeln. För nu, låt oss fokusera på grunderna i parallaxrullning utan att oroa sig för någon spelarrörelse eller skiftande vyer.

Låt oss först bryta ner de enskilda elementen och attributen i vår scen. Spelfönstret är 600x300px, och våra konsttillgångar har en bredd på minst 600px. Genom att använda bakgrundselement som är större än spelfönstret kan vi förhindra att hela tillgången blir synlig vid en viss tidpunkt. Eftersom skikten är kaklade, kommer detta att bidra till att förhindra för mycket uppenbar upprepning eftersom samma tillgång rullar på obestämd tid.

De fyra skikten som utgör vår första scen.

Vår scen består av fyra lager. I det här exemplet definierar lagrets nummer den ordning i vilken tillgången dras till skärmen såväl som dess rörelseshastighet. Om det här var en sidrullningsplattform, så skulle vårt spelarobjekt existera ovanpå lag 3. Detta lager skulle vara observatörens fokuspunkt och skulle också diktera hastigheten på bakgrunds- och förgrundslagen. 

Layer 2 rör sig långsammare än Layer 3 och Layer 1 rör sig långsammare än Layer 2. Layer 4 existerar som förgrundsskiktet, så det rör sig snabbare än fokuseringspunkten på Layer 3.

Det finns flera sätt att implementera denna typ av parallax-rullningsteknik. I detta exempel flyttar lagren vid förutbestämda hastigheter utan att referera till varandra. Om du planerar att ha flera scener med varierande mängder av bakgrunds- och förgrundslager, är det bäst att definiera laghastigheter genom att läsa aktuell hastighet för brännpunktslaget. Till exempel om brännpunkten är Layer 3 och flyttar med en hastighet på 5, då skulle varje successivt bakgrundsskikt flyttas med en hastighet mindre än 5. Alla förgrundsskikt skulle flytta med en hastighet som är större än 5

// Variabler focal_point_speed = 5; layer_difference = 1; // Brännpunktslag lager3.hspeed = focal_point_speed; // Bakgrundslager layer2.hspeed = layer3.hspeed - layer_difference; layer1.hspeed = layer2.hspeed - layer_difference; // Förgrundslager layer4.hspeed = layer3.hspeed + layer_difference; layer5.hspeed = layer4.hspeed + layer_difference;

Exempel 2: Vertikal Parallax Scrolling

Medan parallaxrullning oftast används med horisontella bakgrunder, kan den också användas i vertikala scener, som i det här rymdskeppsexemplet. Det kan finnas mer effektiva sätt att skapa ett stjärnfält, men parallaxrullning får jobbet gjort. 

Det viktigaste att ta bort från detta vertikala exempel är att parallaxrullning fungerar i alla fyra riktningarna längs x- och y-axlarna. (Vi kommer att se hur viktigt detta är i vårt tredje och sista exempel.)

Denna scen har fyra bakgrundsskikt: en statisk svart bakgrund och tre samlingar av stjärnor i olika storlekar. Den statiska bakgrunden rör sig inte, och varje successivt lager av stjärnor växer större och rör sig snabbare, med det slutliga lagret av stjärnor som slutligen bestämmer brännpunktens vertikala hastighet, spelarens rymdskepp. Denna typ av parallaxrullning gör att vi kan simulera djupet av rymden samtidigt som vi simulerar framåtriktad rörelse. Spelarens fartyg rör sig aldrig riktigt upp på skärmen, men du får fortfarande en känsla av snabbare rymdresande.

Exempel 3: Horisontell och vertikal Parallax Scrolling medan du följer ett objekt

Nu när vi har en bättre förståelse för vad parallaxrullning handlar om, kan vi börja konstruera en scen där både horisontell och vertikal rullning implementeras tillsammans med en spelvy som spårar rörelsen för ett spelarstyrt objekt. 

I demo längst upp i handledningen delas denna scen i två exempel. Den första versionen visar hur scenen är utan att någon parallax rullar. Den andra versionen har full vertikal och horisontell parallaxrullning och det illustrerar verkligen hur parallaxrullning kan ge en hel del nedsänkning och djup till vad som ursprungligen var en mycket platt och livlös scen.

Den viktigaste aspekten av detta exempel är spelarrörelse och spelvyn. Eftersom vår bakgrund inte längre är låst i en förutbestämd hastighet eller skärmposition, måste vi beräkna varje lagerets hastighet och position i förhållande till visningsfönstret när spelaren rör sig runt.

Ursprunget för vårt synfönster ligger längst upp till vänster vid (X, Y). Varje bakgrundslagrets tillgång är ursprungligen i övre vänstra hörnet av spritet på (0,0). Genom att hitta nuvarande x- och y-koordinater i visningsfönstret i förhållande till spelvärlden kan vi utföra en beräkning för att bestämma var bakgrundslagets ursprung ska placeras i scenen. Denna position ändras när vyfönstret flyttas utifrån denna beräkning. 

Genom att använda olika värden vid beräkningen av varje lager kan vi flytta varje lager med olika hastigheter beroende på hur snabbt spelaren rör sig.

Koden för att rita skiktet som ligger direkt bakom vårt spelarobjekt är i följande format: draw_background_tiled_horizontal (lager, x, y) var draw_background_tiled_horizontal () är en enkel funktion att rita en kakel tillgång på en viss plats, och bg_ex_3_2 är vår lager tillgång.

// Lag 3 draw_background_tiled_horizontal (bg_ex_3_2, view_xview [view_current] / 2.5, (view_yview [view_current] / 10) + 300);

Skiktets X-värde i detta fall definieras av X-värdet för den aktuella vyn dividerad med ett värde av 2,5, skapa en horisontell rörelse som rör sig något långsammare än själva rörelsens rörelse. 

På liknande sätt definieras lagrets Y-värde av Y-värdet för den aktuella vyn dividerad med 10. Y-värdet på skiktet ökas sedan med 300 att placera den korrekt i förhållande till spelvärlden. Utan denna extra tillägg av 300, tillgången skulle ligga nära toppen av spelvärlden i stället för nära botten där vi vill att den ska vara. 

Dessa värden kommer uppenbarligen att skilja sig åt i ditt projekt, men det viktiga att komma ihåg är att lagrets rörelse ökar när divisionen ökar, men bara upp till en viss punkt. Genom att använda division kan skiktet bara rör sig i samma hastighet eller långsammare än spelarens hastighet.

De två skikten bakom det här lagret rör sig långsammare, så delningsnumren är mindre:

// Lag 1 draw_background_tiled_horizontal (bg_ex_3_0, view_xview [view_current] / 1.5, (view_yview [view_current] / 2.5) + 175); // Layer 2 draw_background_tiled_horizontal (bg_ex_3_1, view_xview [view_current] / 2, (view_yview [view_current] / 5) +250);

För att skapa ett lager som rör sig snabbare än fokuspunkten, t.ex. ett förgrunds lager, behöver en liten förändring göras. Det finns inget förgrundsskikt i det här exemplet, och fokuspunktskiktet är faktiskt bara synligt längst ned på skärmen. Spelaren kan flyga upp och över brännpunkten, vilket är marken, så själva skeppet blir brännpunkten. Vi refererar till marken som kontaktpunkten i det här exemplet eftersom marken är det enda skiktet som rör sig vid samma uppskattade hastighet som rymdskeppet. Här får vi vår sanna känsla av fart i scenen. 

Markskiktet rör sig snabbare än själva siktet, så koden som ritar det här skiktet är något annorlunda än de andra bakgrundsskikten:

// Brännpunktslag (mark) draw_background_tiled_horizontal (bg_ex_3_3, -view_xview [view_current] * 1,5, -view_yview [view_current] + 700);

Med lager som rör sig snabbare än vyn tar vi negativ X- och Y-värdena för den aktuella vyn och multiplicera dem med något värde. Det finns ingen uppgift att beräkna hastigheten på förgrundsskikten. I detta exempel rör markskiktet med en horisontell hastighet som är en och en halv gånger snabbare än fönstret på visningsfönstret. Ingen multiplicering utförs på lagrets vertikala hastighet, så det rör sig i samma hastighet som vyn. Ett extra värde av 700 läggs till lagets Y-värde för att placera det på önskad plats nära spelvärldens botten.

Slutsats

Parallax rullning är ett enkelt men väldigt effektivt sätt att lägga till djupets illusion i ett 2D-spel. Jag hoppas att exemplen i demo har visat hur effektivt det kan vara, och jag hoppas att självstudiet själv har visat hur enkelt det är att implementera!

referenser

  • Street background art av MindChamber
  • Rymdskeppskonst av Jerom
  • Ytterligare konstverk av SonnyBone