Rolagem Parallax no Godot: Tutorial Completo com Exemplos!

O efeito de rolagem parallax é um recurso amplamente utilizado em jogos 2D para simular profundidade e aumentar o interesse visual dos cenários. A técnica consiste em deslocar diferentes planos de fundo em velocidades distintas, em relação ao movimento da câmera.

Na versão 4 do Godot, a implementação do efeito parallax tornou-se notavelmente simplificada. O robusto motor 2D oferece suporte integrado para camadas de paralaxe, permitindo a criação de efeitos visuais atraentes com pouco esforço.

Configurando o Jogo no Godot

Para começar, crie um novo projeto 2D no motor de jogos Godot e estruture a cena com um personagem controlável pelo jogador.

O código demonstrado neste artigo está disponível neste Repositório GitHub, sendo de uso livre sob a licença MIT.

Neste exemplo, adicione um nó CharacterBody2D para permitir o movimento do jogador. Inclua também um CollisionShape2D com formato retangular e um Sprite2D para representar o personagem.

 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)

Com esse código, o personagem do jogador pode se mover para os lados, para cima e para baixo, usando as setas do teclado ou comandos similares.

Criando Camadas Distintas com Nós ParallaxLayer

Em seguida, implemente o efeito parallax adicionando diversos nós ParallaxLayer à cena. Cada ParallaxLayer representará um plano de fundo diferente. Para um efeito parallax convincente, as camadas mais afastadas da câmera devem se mover mais lentamente em comparação com as mais próximas.

Adicione nós StaticBody2D com CollisionShape2D em cada ParallaxLayer, criando alguns objetos de fundo com os quais o jogador poderá colidir. Estes objetos interagirão com o jogador e outros elementos, aprofundando a jogabilidade.

Segue o código GDScript para criar as camadas de parallax com objetos colidíveis:

 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)

Com o código acima, cada camada parallax agora possui um nó StaticBody2D com um CollisionShape2D, representando objetos colidíveis no plano de fundo.

Esses objetos interagem com o personagem do jogador e outros elementos, adicionando profundidade e complexidade à dinâmica do jogo.

Deslocando as Camadas em Diferentes Velocidades

Com as camadas parallax configuradas, é necessário atualizar suas posições com base no movimento do jogador. Isso cria o efeito parallax, onde as camadas próximas à câmera se movem mais rapidamente do que as mais distantes.

Adicione o seguinte código GDScript à cena do Jogador:

 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)

O código acima calcula o movimento das camadas parallax com base no movimento do jogador e atualiza o deslocamento de rolagem do nó ParallaxBackground de acordo. O sinal negativo garante que as camadas se desloquem na direção oposta ao movimento do jogador.

O efeito de rolagem parallax aleatória adiciona um elemento de surpresa e imprevisibilidade ao cenário do jogo. Ao gerar e posicionar dinamicamente as camadas parallax durante o jogo, é possível criar uma experiência mais dinâmica e envolvente para os jogadores.

Para implementar a rolagem parallax aleatória, adicione novas camadas parallax com escalas e posições de movimento aleatório.

 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)

O código acima define constantes para controlar a aleatoriedade das camadas parallax. A função lerp é utilizada para interpolar valores entre MIN_SCALE e MAX_SCALE, gerando uma escala de movimento aleatória para cada nova camada. A função tem a seguinte assinatura:

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

Ao passar o resultado de randf() como o peso, é possível gerar camadas com uma escala aleatória.

A função randf_range oferece outro meio de gerar valores aleatórios dentro de um intervalo. Aqui, a função create_random_layer usa-a para gerar posições aleatórias para as novas camadas dentro de uma faixa especificada:

 var x_position = randf_range(MIN_X_POSITION, MAX_X_POSITION) 

O jogo de demonstração deverá se apresentar da seguinte maneira:

Incluindo Recursos Adicionais

A rolagem parallax oferece uma base sólida para refinar o apelo visual do seu jogo de plataforma. É possível ir mais longe, integrando recursos adicionais. Algumas ideias a serem consideradas são:

Objetos de Fundo

Crie elementos mais interativos nas camadas parallax, como plataformas flutuantes, obstáculos móveis ou personagens de fundo animados. Esses objetos podem agregar profundidade e interatividade ao seu jogo.

Iluminação Dinâmica

Introduza efeitos de iluminação dinâmicos nas camadas parallax. Adicionando fontes de luz e sombras, é possível criar uma sensação de realismo e profundidade no universo do jogo. O sistema de iluminação do Godot funciona bem em jogos 2D e pode aprimorar significativamente a qualidade visual.

Efeitos de Partículas

Integre sistemas de partículas nas camadas parallax para inserir efeitos visuais sutis. Folhas caindo, nuvens flutuantes ou estrelas cintilantes podem melhorar o ambiente e tornar o mundo do jogo mais vivo. Também é possível adicionar efeitos sonoros de uso livre.

Ciclo Dia-Noite

Implemente um ciclo dia-noite que modifique a cor e a intensidade das camadas parallax com base na hora do dia no jogo. Esse recurso dinâmico pode proporcionar aos jogadores uma experiência em constante evolução à medida que avançam no jogo.

Embora a rolagem parallax eleve a parte visual do jogo, é essencial seguir algumas práticas recomendadas para garantir uma experiência suave e agradável.

Otimização de Desempenho

É importante monitorar o número de camadas parallax e sua complexidade. Muitas camadas ou recursos em alta resolução podem causar problemas de desempenho, especialmente em dispositivos menos potentes. Otimize os elementos visuais e utilize formas de colisão simplificadas sempre que possível.

Disposição das Camadas

Organize as camadas parallax de forma criteriosa. Analise a hierarquia visual e o efeito de profundidade desejado. As camadas próximas à câmera devem se mover mais rapidamente, enquanto as mais distantes devem se mover mais lentamente.

Limites da Câmera

Defina limites para o movimento da câmera, evitando espaços vazios indesejados ou falhas visuais quando o jogador alcançar os limites do mundo do jogo. Isso assegura uma experiência fluida para os jogadores.

Testes e Ajustes

Teste a rolagem parallax em diversos dispositivos e tamanhos de tela para garantir que a aparência e o desempenho sejam adequados em diferentes plataformas. Ajustar as escalas de movimento, as posições das camadas e outros parâmetros pode refinar o efeito parallax para obter os melhores resultados.

Adicionar rolagem parallax aleatória pode elevar significativamente o nível de envolvimento do seu jogo Godot. A rolagem parallax aleatória consiste em gerar e posicionar camadas de paralaxe dinamicamente durante o jogo.

Dessa forma, cria-se uma sensação de movimento e dinamismo no plano de fundo, tornando o mundo do jogo mais vivo e imprevisível. Os jogadores experimentarão um cenário visual em constante transformação, adicionando uma camada extra de emoção à experiência de jogo.