Parallax Background no Godot 2D: Camadas de Profundidade e Scroll Infinito

Aprenda parallax no Godot 2D: ParallaxBackground, ParallaxLayer e o novo Parallax2D. Camadas de profundidade, scroll infinito e autoscroll na prática.
Parallax Background no Godot 2D: Camadas de Profundidade e Scroll Infinito
Parallax é o truque mais barato que existe pra dar profundidade a um jogo 2D: camadas de fundo que se movem em velocidades diferentes da câmera. A montanha lá no fundo quase não sai do lugar, a floresta do meio anda devagar e os arbustos da frente passam voando. O cérebro lê isso como distância, e um cenário chapado vira um mundo com volume.
Implementar parallax no Godot é simples, mas tem duas pegadinhas que travam todo mundo: o sistema antigo (ParallaxBackground + ParallaxLayer) tem comportamento esquisito por ser um CanvasLayer, e a configuração de repetição infinita falha em silêncio se o tamanho não bater com a textura. Esse tutorial cobre os dois sistemas do Godot 4, qual usar em cada caso, e como montar camadas de profundidade e scroll infinito sem bug.
Como o efeito funciona (antes de qualquer node)
A regra é uma só: cada camada se move numa fração da velocidade da câmera, e essa fração representa a distância.
- Fração 1.0: a camada acompanha a câmera por igual. É o plano do jogo, onde o player anda.
- Fração 0.5: a camada se move na metade da velocidade. Parece estar longe.
- Fração 0.1: quase parada. Montanhas no horizonte.
- Fração 0.0: fixa na tela. Céu, sol, lua.
Também dá pra passar de 1.0: uma camada com fração 1.2 se move mais rápido que a câmera e parece estar na frente do plano do jogo, entre o player e a tela. É assim que se faz aquele mato desfocado passando na frente da ação.
No Godot essa fração tem nome: motion_scale no sistema antigo, scroll_scale no novo. Todo o resto (repetição, autoscroll, limites) é em volta desse número.
Os dois sistemas do Godot 4
O Godot 4 tem duas formas de fazer parallax, e vale entender o porquê antes de escolher.
ParallaxBackground + ParallaxLayer é o sistema clássico, herdado do Godot 3. Funciona, mas o ParallaxBackground é um CanvasLayer, não um Node2D. Isso traz efeitos colaterais chatos: ele ignora a transformação dos pais, não respeita a ordenação normal de Y-sort e desenho da cena, e o que você vê no editor nem sempre é o que aparece rodando.
Parallax2D chegou no Godot 4.3 exatamente pra resolver isso. É um Node2D comum: um node só por camada, se comporta como qualquer outro node da cena, e o preview do editor corresponde ao jogo.
Minha recomendação é direta: se o seu projeto está no Godot 4.3 ou mais novo, use Parallax2D. Se está preso numa versão anterior, o sistema clássico funciona e mostro ele logo depois.
Parallax background com Parallax2D
Cada camada de profundidade é um node Parallax2D com um Sprite2D filho. Pra um cenário com céu, montanhas, floresta e o plano do jogo, a cena fica assim:
Level (Node2D)
├── ParallaxCeu (Parallax2D)
│ └── Sprite2D
├── ParallaxMontanhas (Parallax2D)
│ └── Sprite2D
├── ParallaxFloresta (Parallax2D)
│ └── Sprite2D
├── Player (CharacterBody2D)
└── Camera2D (filha do Player ou da cena)
A ordem na árvore importa: o que vem primeiro desenha atrás. Céu em cima da lista, camadas mais próximas embaixo.
Configurando cada camada
Selecione cada Parallax2D e ajuste no Inspector:
Scroll Scale é a fração de velocidade. Valores que funcionam bem como ponto de partida:
- Céu:
(0.0, 0.0)ou algo bem baixo tipo(0.05, 0.05) - Montanhas:
(0.2, 0.2) - Floresta:
(0.6, 0.6)
Repare que é um Vector2: dá pra ter parallax diferente no eixo X e no Y. Em plataforma é comum reduzir bem o parallax vertical (algo como (0.2, 0.05)) pra camada não fugir da tela quando o player pula.
Repeat Size é o que faz o fundo repetir infinitamente. Coloque a largura da sua textura em pixels no X (por exemplo, (1920, 0) pra uma arte de 1920 de largura) e o Godot duplica a camada lateralmente, reposicionando conforme a câmera anda. Com 0 no Y, não repete na vertical.
Repeat Times controla quantas cópias visíveis existem ao mesmo tempo. O padrão 1 já resolve a maioria dos casos; suba se aparecer borda em câmera com zoom out.
E é isso. Sem código. Rode a cena, mova a câmera e as camadas se deslocam cada uma na sua velocidade.
A pegadinha do Repeat Size
Se a sua arte tem 576 pixels de largura mas o sprite está com scale de 2, o tamanho real na tela é 1152, e é esse valor que vai no Repeat Size. Colocar o tamanho da textura sem considerar a escala gera ou um buraco entre as cópias ou uma sobreposição com costura visível. Quando o seu fundo infinito tiver uma emenda aparecendo, é quase sempre isso: Repeat Size diferente do tamanho renderizado do sprite.
Outro detalhe: a arte precisa ser tileable na horizontal (a borda direita emenda com a esquerda). Se a sua não for, abre no editor de imagem e usa um offset de metade da largura pra ver e corrigir a costura no meio.
Autoscroll: fundo que se move sozinho
Pra menu, tela de título ou aquele céu com nuvens que andam mesmo com a câmera parada, o Parallax2D tem a propriedade Autoscroll. É um Vector2 em pixels por segundo:
extends Parallax2D
func _ready():
# Nuvens andando pra esquerda a 30 px/s, sem depender da camera.
autoscroll = Vector2(-30, 0)
Dá pra setar direto no Inspector também. Combinado com Repeat Size, isso te dá um fundo infinito animado com zero lógica de jogo.
O sistema clássico: ParallaxBackground e ParallaxLayer
Se você está no Godot 4.0 a 4.2 (ou mantendo um projeto antigo), a estrutura é diferente: um ParallaxBackground na raiz e um ParallaxLayer pra cada camada.
Level (Node2D)
├── ParallaxBackground
│ ├── CamadaCeu (ParallaxLayer)
│ │ └── Sprite2D
│ ├── CamadaMontanhas (ParallaxLayer)
│ │ └── Sprite2D
│ └── CamadaFloresta (ParallaxLayer)
│ └── Sprite2D
├── Player (CharacterBody2D)
└── Camera2D
As propriedades equivalem quase um pra um às do Parallax2D, com nomes diferentes:
- Motion Scale no ParallaxLayer: a fração de velocidade, mesma lógica do scroll_scale.
- Motion Mirroring no ParallaxLayer: o equivalente do Repeat Size. Coloque o tamanho renderizado da textura e a camada espelha infinitamente. A mesma pegadinha da escala vale aqui, e com um agravante: se o valor do mirroring for menor que a textura, as cópias se sobrepõem sem nenhum aviso.
- Motion Offset: desloca a camada sem mexer no sprite, útil pra ajustar a altura do horizonte.
O ParallaxBackground detecta a Camera2D ativa sozinho. Você não conecta nada: tendo uma câmera correndo na cena, o scroll acontece.
Autoscroll no sistema clássico
Não existe propriedade pronta; o jeito é animar o scroll_offset do ParallaxBackground por script:
extends ParallaxBackground
@export var velocidade = Vector2(-30, 0)
func _process(delta):
scroll_offset += velocidade * delta
Cada ParallaxLayer filho responde a esse offset multiplicado pelo seu próprio motion_scale, então as camadas continuam com profundidades diferentes mesmo no autoscroll. É um padrão comum em endless runner: a câmera nem precisa se mover, o mundo é que passa.
Por que o editor mente pra você
A reclamação mais comum com esse sistema: você posiciona as camadas bonitinhas no editor, roda o jogo e está tudo em outro lugar. Acontece porque o ParallaxBackground é um CanvasLayer e calcula a posição final em função da câmera em runtime. O editor não simula isso direito.
A defesa prática: deixe cada ParallaxLayer e seus sprites na posição (0, 0) sempre que possível e use o Motion Offset pra ajustar enquadramento, testando com o jogo rodando. E aceite que esse vai e vem é exatamente o motivo de o Parallax2D existir.
Profundidade que convence: dicas de composição
A parte técnica é meia hora de trabalho. O que separa um parallax amador de um profissional é composição, e aqui algumas coisas que aprendi montando cenário:
Três a cinco camadas bastam. Menos que três o efeito fica pobre; mais que cinco vira custo de arte sem ganho visual perceptível. Céu, fundo distante, meio e primeiro plano cobrem quase qualquer cenário.
Espalhe os valores de scroll de forma desigual. Camadas com 0.3, 0.5 e 0.7 parecem coladas umas nas outras. Algo como 0.05, 0.25 e 0.65 separa muito melhor os planos, porque a percepção de profundidade não é linear.
Use atmosfera, não só velocidade. Camada distante mais clara, dessaturada e puxando pro azul (perspectiva atmosférica) reforça demais a sensação de longe. Dá pra fazer isso direto no Godot com o modulate do sprite, sem retrabalhar a arte.
Pixel art treme se você deixar. Com motion_scale fracionário, a camada cai em posições quebradas de pixel e fica trepidando. Em Project Settings > Rendering > 2D, ligue o Snap 2D Transforms to Pixel. Se ainda incomodar, use valores de scroll que dividam bem (0.5, 0.25) em vez de números arbitrários.
Cuidado com parallax vertical em plataforma. Se o player sobe muito e a camada de fundo acompanha com scroll Y alto, o céu vai embora e aparece a borda da arte. Ou reduza o componente Y do scroll, ou use os limites (Limit Begin e Limit End no Parallax2D, Scroll Limit no ParallaxBackground) pra travar até onde o fundo desloca.
Performance: parallax é quase de graça
Boa notícia: parallax não é um problema de performance no Godot. As camadas são sprites comuns sendo reposicionados, e a repetição é resolvida pela engine sem instanciar nodes extras. Duas atenções apenas:
- Tamanho de textura. Fundo de 4096 pixels de largura em jogo mobile come memória de vídeo à toa. Trabalhe no tamanho da sua resolução alvo e deixe a repetição cobrir o resto.
- Overdraw. Cinco camadas de tela cheia significam desenhar cada pixel cinco vezes. Em desktop, irrelevante. Em mobile antigo, vale recortar as camadas (a montanha não precisa de textura na parte que o chão cobre) pra reduzir área transparente desenhada.
Fechando
Parallax no Godot se resume a: escolher o sistema certo (Parallax2D no 4.3+, ParallaxBackground antes disso), dar a cada camada uma fração de velocidade que representa a distância, e configurar a repetição com o tamanho renderizado da textura, escala incluída. O resto é composição: poucas camadas, valores bem espalhados e atmosfera na arte.
Pra fixar, pegue qualquer cena com Camera2D que você já tenha e adicione três camadas: céu parado, montanha a 0.2 e árvores a 0.6. São dez minutos de setup e o cenário muda de patamar na hora. Depois experimente um autoscroll de nuvens por cima. Quando você vê a profundidade aparecer na tela, esse conhecimento não sai mais.


