Hur man implementerar Parallax Scrolling i Godot

By rik

Parallaxskrollning är en teknik som ofta används i 2D-spel för att skapa en känsla av djup och göra spelbakgrunderna mer visuellt intressanta. Effekten uppnås genom att olika bakgrundslager rör sig i olika hastigheter relativt kamerans rörelse.

Godot 4 har gjort det enklare än någonsin att implementera parallaxskrollning. Dess kraftfulla 2D-motor har inbyggt stöd för parallaxlager, vilket gör att du kan skapa imponerande visuella effekter med minimal ansträngning.

Konfigurera Godot-spelet

För att börja, skapa ett nytt 2D-projekt i Godot-spelmotorn och sätt upp spelscenen med en spelarkaraktär.

Koden som används i den här artikeln finns tillgänglig i detta GitHub-arkiv och är fritt tillgänglig under MIT-licensen.

I det här exemplet lägger du till en CharacterBody2D-nod för spelarrörelse. Lägg också till en CollisionShape2D med en rektangelform och en Sprite2D för att representera spelarkaraktären.

extends CharacterBody2D

var speed = 200

func _physics_process(delta):
    var velocity = Vector2()

    if Input.is_action_pressed('ui_right'):
        velocity.x += 1

    if Input.is_action_pressed('ui_left'):
        velocity.x -= 1

    if Input.is_action_pressed('ui_down'):
        velocity.y += 1

    if Input.is_action_pressed('ui_up'):
        velocity.y -= 1

    velocity = velocity.normalized() * speed
    move_and_collide(velocity * delta)

Denna kod ger spelarkaraktären möjlighet att röra sig åt vänster, höger, upp och ner med hjälp av piltangenterna eller motsvarande inmatningar.

Skapa olika lager med ParallaxLayer-noder

För att skapa parallaxeffekten lägger du till flera ParallaxLayer-noder till scenen. Varje ParallaxLayer representerar ett eget bakgrundslager. För en övertygande parallaxeffekt bör lager längre bort från kameran röra sig långsammare än de närmare.

Lägg till StaticBody2D-noder med CollisionShape2D i varje ParallaxLayer för att skapa kolliderbara objekt i bakgrunden. Dessa objekt interagerar med spelaren och andra element i spelet, vilket ger spelet mer djup.

Här är GDScript-koden för att skapa parallaxlager med kolliderbara objekt:

extends ParallaxBackground

func _ready():

    var layer1 = ParallaxLayer.new()
    layer1.motion_scale = Vector2(0.2, 0.2)
    add_child(layer1)

    var static_body1 = StaticBody2D.new()
    layer1.add_child(static_body1)

    var collision_shape1 = CollisionShape2D.new()
    var shape1 = RectangleShape2D.new()
    shape1.extents = Vector2(32, 32)
    collision_shape1.shape = shape1
    static_body1.add_child(collision_shape1)

    var layer2 = ParallaxLayer.new()
    layer2.motion_scale = Vector2(0.5, 0.5)
    add_child(layer2)

    var static_body2 = StaticBody2D.new()
    layer2.add_child(static_body2)

    var collision_shape2 = CollisionShape2D.new()
    var shape2 = RectangleShape2D.new()
    shape2.extents = Vector2(64, 64)
    collision_shape2.shape = shape2
    static_body2.add_child(collision_shape2)

    var layer3 = ParallaxLayer.new()
    layer3.motion_scale = Vector2(1.0, 1.0)
    add_child(layer3)

    var static_body3 = StaticBody2D.new()
    layer3.add_child(static_body3)

    var collision_shape3 = CollisionShape2D.new()
    var shape3 = RectangleShape2D.new()
    shape3.extents = Vector2(128, 128)
    collision_shape3.shape = shape3
    static_body3.add_child(collision_shape3)

Med den här koden har varje parallaxlager en StaticBody2D-nod med en CollisionShape2D som representerar kolliderbara objekt i bakgrunden.

Dessa kolliderbara objekt interagerar med spelarkaraktären och andra spelelement, vilket ger mer djup och komplexitet till spelet.

Flytta olika lager med olika hastigheter

När du har konfigurerat dina parallaxlager, måste du uppdatera deras positioner baserat på spelarens rörelse. Detta skapar parallaxeffekten, där lager som är närmare kameran rör sig snabbare än de längre bort.

Lägg till följande GDScript-kod till spelarscenen:

extends CharacterBody2D

func _physics_process(delta):
    ...
    move_and_collide(velocity * delta)

    var parallax_background = get_parent()
    var motion = -velocity * delta
    parallax_background.set_scroll_offset(parallax_background.scroll_offset + motion)

Denna kod beräknar rörelsen för parallaxlagren baserat på spelarens rörelse och uppdaterar scrollförskjutningen för ParallaxBackground-noden. Notera det negativa tecknet, som säkerställer att lagren rör sig i motsatt riktning jämfört med spelarens rörelse.

Slumpmässig parallaxskrollning tillför ett element av överraskning och oförutsägbarhet till spelets bakgrund. Genom att dynamiskt generera och placera parallaxlager under spelets gång, kan du skapa en mer engagerande och dynamisk upplevelse för spelarna.

För att implementera slumpmässig parallaxskrollning, lägg till nya parallaxlager med slumpmässiga rörelseskalor och positioner.

extends ParallaxBackground

const MAX_LAYERS = 5
const MIN_SCALE = 0.2
const MAX_SCALE = 1.5
const MIN_SPEED = 0.01
const MAX_SPEED = 0.03
const MIN_X_POSITION = -500
const MAX_X_POSITION = 500
const MIN_Y_POSITION = -300
const MAX_Y_POSITION = 300

func _ready():
    for i in range(MAX_LAYERS):
        create_random_layer()

func create_random_layer():
    var layer = ParallaxLayer.new()
    var scale = lerp(MIN_SCALE, MAX_SCALE, randf())
    layer.motion_scale = Vector2(scale, scale)

    var x_position = randf_range(MIN_X_POSITION, MAX_X_POSITION)
    var y_position = randf_range(MIN_Y_POSITION, MAX_Y_POSITION)
    layer.global_transform.origin.x = x_position
    layer.global_transform.origin.y = y_position

    add_child(layer)

    var static_body = StaticBody2D.new()
    layer.add_child(static_body)

    var collision_shape = CollisionShape2D.new()
    var shape = RectangleShape2D.new()
    shape.extents = Vector2(32, 32)
    collision_shape.shape = shape
    static_body.add_child(collision_shape)

func remove_random_layer():
    if get_child_count() > 0:
        var random_index = randi() % get_child_count()
        var layer_to_remove = get_child(random_index)
        remove_child(layer_to_remove)

Denna kod definierar konstanter som styr slumpmässigheten hos parallaxlagren. Funktionen `lerp` används för att interpolera värden mellan `MIN_SCALE` och `MAX_SCALE`, och genererar en slumpmässig rörelseskala för varje nytt lager. Funktionen har följande signatur:

Variant lerp ( Variant from, Variant to, float weight )

Genom att skicka resultatet av `randf()` som vikt, kan du skapa lager med slumpmässig skala.

Funktionen `randf_range` erbjuder ett annat sätt att generera slumpmässiga värden inom ett givet intervall. Här använder funktionen `create_random_layer` den för att generera slumpmässiga positioner för de nya lagren inom ett specificerat intervall:

var x_position = randf_range(MIN_X_POSITION, MAX_X_POSITION)

Ditt demospel bör nu se ut ungefär så här:

Inkludera ytterligare funktioner

Parallaxskrollning är en bra grund för att förbättra det visuella intrycket av ditt plattformsspel, men du kan göra mer genom att lägga till fler funktioner. Här är några idéer att fundera över.

Bakgrundsobjekt

Skapa interaktiva element i dina parallaxlager, som flytande plattformar, rörliga hinder eller animerade bakgrundsfigurer. Dessa objekt kan addera djup och interaktivitet till ditt plattformsspel.

Dynamisk belysning

Introducera dynamiska ljuseffekter till dina parallaxlager. Genom att lägga till ljuskällor och skuggor kan du skapa en känsla av realism och djup i spelvärlden. Godots ljussystem fungerar bra med 2D-spel och kan förbättra den visuella kvaliteten betydligt.

Partikeleffekter

Integrera partikelsystem i dina parallaxlager för att lägga till subtila visuella effekter. Fallande löv, moln som driver förbi eller gnistrande stjärnor kan förbättra stämningen och göra spelvärlden mer levande. Du kan också lägga till ljudeffekter utan upphovsrätt till ditt spel.

Dag-Natt-cykel

Implementera en dag-natt-cykel som ändrar färg och intensitet på parallaxlagren beroende på tiden på dygnet i spelet. Denna dynamiska funktion kan erbjuda spelarna en ständigt föränderlig upplevelse när de går vidare i spelet.

Även om parallaxskrollning kan förbättra ditt spels grafik, är det viktigt att följa vissa riktlinjer för att säkerställa en smidig och njutbar upplevelse.

Prestandaoptimering

Var uppmärksam på antalet parallaxlager och deras komplexitet. För många lager eller högupplösta resurser kan leda till prestandaproblem, särskilt på mindre kraftfulla enheter. Optimera din grafik och använd förenklade kollisionsformer där det är möjligt.

Lagerarrangemang

Ordna dina parallaxlager med eftertanke. Tänk på den visuella hierarkin och den önskade djupeffekten. Lager som ligger närmast kameran ska röra sig snabbare, medan de längre bort ska röra sig långsammare.

Kameragränser

Sätt gränser för kamerarörelsen för att undvika oönskade tomma utrymmen eller visuella problem när spelaren når kanten av spelvärlden. Detta säkerställer en smidig spelupplevelse.

Testning och finjustering

Testa din parallaxskrollning på olika enheter och skärmstorlekar för att se till att det ser bra ut och fungerar bra på olika plattformar. Att justera rörelseskalor, lagerpositioner och andra parametrar kan finjustera parallaxeffekten för bästa resultat.

Att lägga till slumpmässig parallaxskrollning kan avsevärt förbättra engagemanget i ditt Godot-spel. Slumpmässig parallaxskrollning innebär att dynamiskt generera och positionera parallaxlager under spelets gång.

Genom att göra det, skapar du en känsla av rörelse och dynamik i bakgrunden, vilket gör att spelvärlden känns mer levande och oförutsägbar. Spelare kommer att uppleva en ständigt föränderlig visuell miljö, vilket lägger till ett extra lager av spänning i deras spelupplevelse.