Jak zaimplementować przewijanie paralaksy w Godot

Przewijanie paralaksy to technika używana w wielu grach 2D do tworzenia iluzji głębi i dodawania atrakcyjności wizualnej do tła gry. Osiąga efekt przesuwając różne warstwy tła z różnymi prędkościami względem ruchu kamery.

Godot 4 sprawia, że ​​wdrożenie przewijania paralaksy jest łatwiejsze niż kiedykolwiek. Jego potężny silnik 2D zapewnia wbudowaną obsługę warstw paralaksy, umożliwiając tworzenie oszałamiających efektów wizualnych przy minimalnym wysiłku.

Przygotowanie gry Godot

Aby rozpocząć, utwórz nowy projekt 2D w silniku gry Godot i skonfiguruj scenę gry z postacią gracza.

Kod użyty w tym artykule jest dostępny w this Repozytorium GitHub i jest darmowy do użytku na licencji MIT.

W tym przykładzie dodaj węzeł CharacterBody2D do ruchu gracza. Dodaj także CollisionShape2D o kształcie prostokąta i Sprite2D, aby reprezentować postać gracza.

 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)

Za pomocą tego kodu postać gracza może poruszać się w lewo, w prawo, w górę iw dół za pomocą klawiszy strzałek lub podobnych danych wejściowych.

Tworzenie różnych warstw za pomocą węzłów ParallaxLayer

Następnie utwórz efekt paralaksy, dodając do sceny wiele węzłów ParallaxLayer. Każda warstwa ParallaxLayer będzie reprezentować inną warstwę tła. Aby uzyskać przekonujący efekt paralaksy, warstwy znajdujące się dalej od kamery powinny poruszać się wolniej niż te bliższe.

Dodaj węzły StaticBody2D z CollisionShape2D w każdej warstwie ParallaxLayer, aby utworzyć kilka kolidowalnych obiektów w tle. Te zderzające się obiekty będą wchodzić w interakcje z graczem i innymi elementami gry, dodając głębi rozgrywce.

Oto kod GDScript do tworzenia warstw paralaksy z kolidowalnymi obiektami:

 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)

Dzięki temu kodowi każda warstwa paralaksy zawiera teraz węzeł StaticBody2D z elementem CollisionShape2D reprezentującym kolidowalne obiekty w tle.

Te zderzające się obiekty będą wchodzić w interakcje z postacią gracza i innymi elementami gry, dodając głębi i złożoności rozgrywce.

Przenoszenie różnych warstw z różną prędkością

Teraz, gdy masz już skonfigurowane warstwy paralaksy, musisz zaktualizować ich pozycje na podstawie ruchu gracza. Spowoduje to powstanie efektu paralaksy, w którym warstwy bliżej kamery poruszają się szybciej niż te dalej.

Dodaj następujący kod GDScript do sceny Player:

 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)

Ten kod oblicza ruch warstw paralaksy na podstawie ruchu gracza i odpowiednio aktualizuje przesunięcie przewijania węzła ParallaxBackground. Zwróć uwagę na użycie znaku ujemnego, aby upewnić się, że warstwy poruszają się w kierunku przeciwnym do ruchu gracza.

Losowe przewijanie paralaksy wprowadza element zaskoczenia i nieprzewidywalności do tła twojej gry. Dynamicznie generując i pozycjonując warstwy paralaksy podczas rozgrywki, możesz zapewnić graczom bardziej wciągające i dynamiczne wrażenia.

Aby zaimplementować losowe przewijanie paralaksy, dodaj nowe warstwy paralaksy z losowymi skalami ruchu i pozycjami.

 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)

Ten kod definiuje stałe kontrolujące losowość warstw paralaksy. Użyj funkcji lerp, aby interpolować wartości między MIN_SCALE i MAX_SCALE, generując losową skalę ruchu dla każdej nowej warstwy. Ta funkcja ma następującą sygnaturę:

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

Przekazanie wyniku z randf() jako wagi pozwala generować warstwy o losowej skali.

Funkcja randf_range oferuje inny sposób generowania losowych wartości w zakresie. Tutaj funkcja create_random_layer używa go do generowania losowych pozycji dla nowych warstw w określonym zakresie:

 var x_position = randf_range(MIN_X_POSITION, MAX_X_POSITION) 

Twoja gra demonstracyjna powinna teraz wyglądać mniej więcej tak:

W tym dodatkowe funkcje

Przewijanie paralaksy zapewnia solidną podstawę do ulepszenia wizualnej atrakcyjności gry platformowej, ale możesz pójść jeszcze dalej, wprowadzając dodatkowe funkcje. Oto kilka pomysłów do rozważenia.

Obiekty tła

Twórz bardziej interaktywne elementy w warstwach paralaksy, takie jak pływające platformy, poruszające się przeszkody lub animowane postacie w tle. Te obiekty mogą dodać głębi i interaktywności do Twojej gry platformowej.

Dynamiczne oświetlenie

Wprowadź dynamiczne efekty świetlne do swoich warstw paralaksy. Dodając źródła światła i cienie, możesz stworzyć poczucie realizmu i głębi w świecie gry. System oświetlenia Godota dobrze współpracuje z grami 2D i może znacznie poprawić jakość wizualną.

Efekty cząsteczkowe

Zintegruj systemy cząsteczek z warstwami paralaksy, aby dodać subtelne efekty wizualne. Spadające liście, dryfujące chmury lub błyszczące gwiazdy mogą poprawić atmosferę i sprawić, że świat gry będzie bardziej żywy. Możesz także dodać do swojej gry efekty dźwiękowe wolne od praw autorskich.

Cykl dnia i nocy

Zaimplementuj cykl dnia i nocy, który zmienia kolor i intensywność warstw paralaksy w zależności od pory dnia w grze. Ta dynamiczna funkcja może zapewnić graczom stale ewoluujące wrażenia w miarę postępów w grze.

Podczas gdy przewijanie paralaksy może podnieść jakość wizualną gry, konieczne jest przestrzeganie kilku najlepszych praktyk, aby zapewnić płynne i przyjemne wrażenia.

Optymalizacja wydajności

Pamiętaj o liczbie warstw paralaksy i ich złożoności. Zbyt wiele warstw lub zasobów o wysokiej rozdzielczości może prowadzić do problemów z wydajnością, zwłaszcza na słabszych urządzeniach. Zoptymalizuj swoją grafikę i używaj uproszczonych kształtów kolizji tam, gdzie to możliwe.

Układ warstw

Rozmieść warstwy paralaksy w przemyślany sposób. Rozważ hierarchię wizualną i pożądany efekt głębi. Warstwy najbliżej kamery powinny poruszać się szybciej, a te dalej – wolniej.

Granice aparatu

Ustaw granice ruchu kamery, aby zapobiec niechcianej pustej przestrzeni lub usterkom wizualnym, gdy gracz dotrze do krawędzi świata gry. Zapewnia to bezproblemową rozgrywkę dla graczy.

Testowanie i poprawianie

Przetestuj przewijanie paralaksy na różnych urządzeniach i rozmiarach ekranu, aby upewnić się, że wygląda i działa dobrze na różnych platformach. Poprawianie skali ruchu, pozycji warstw i innych parametrów może precyzyjnie dostroić efekt paralaksy w celu uzyskania najlepszych rezultatów.

Dodanie losowego przewijania paralaksy może znacznie zwiększyć poziom zaangażowania w grę Godot. Losowe przewijanie paralaksy obejmuje dynamiczne generowanie i pozycjonowanie warstw paralaksy podczas gry.

W ten sposób tworzysz wrażenie ruchu i dynamizmu w tle, sprawiając, że świat gry wydaje się żywy i nieprzewidywalny. Gracze będą doświadczać stale zmieniającego się środowiska wizualnego, dodając dodatkową warstwę emocji do swoich wrażeń z gry.