Passo a passo para fazer plataformas ⬇️ ↔️ ↕️

vamos construir 3 tipos de plataformas e uma bônus ⭐
- Plataforma fixa (a mais comum de todas).
- Plataforma de queda ao detectar colisão com jogador;
- Plataforma de movimento na horizontal ou vertical;
- BÔNUS: Uma plataforma de queda um pouquinho diferente! 🙂
📝 Nota Necessário download da Godot 4.2 para abrir o projeto e poder executar, modificar e criar.
1ª Plataforma: plataforma fixa
Esse é o tipo mais básico e comum de plataforma. Para criá-la vamos criar uma nova cena e adicionar os seguintes nós:
- StaticBody2D
- Sprite2D
- CollisionShape2D
Renomeei os nós com os seguintes nomes:
Próximos passos:
- Adicione ao nó
spriteuma imagem para ser sua plataforma na abaInspector/Texture; - Ao nó
collisiondetermine qual será o shape de colisão que melhor se encaixe à sprite da plataforma. Vá para a abaInspector/Shapee escolha a melhor forma para colisão. Eu escolhi para a minha plataforma o shapeRectangleShape2D. - Ainda no nó
collisiondeixe habilitado a propriedadeOne Way Collision. Essa configuração permitirá ao jogador saltar para a plataforma de baixo para cima, mas não cair através dela de cima para baixo.
A imagem a seguir exemplifica a configuração do nó de colisão:

Com isso feito, nossa primeira plataforma já está feita. Agora basta instanciar a cena platform como filho do nó raiz da cena principal, por exemplo, cena de fase ou nível. Nesse projeto está como: world_01 e então é só posicionar a plataforma no local que quiser na cena de seu jogo. 😉
2ª Plataforma: plataforma de queda ⬇️
Essa plataforma reage à interação do jogador, caindo e depois retornando à sua posição original após um tempo.
Após criar uma nova cena, vamos aos nós que ela terá:
- RigidBody2D
- Sprite2D
- CollisionShape2D
- Timer
- Area2D
- CollisionShape2D
- AnimationPlayer
Renomeei os nós com os seguintes nomes:

Após adicionar ao nó sprite uma imagem que será sua plataforma de queda, vamos às colisões.
Teremos 2 colisões (como ilustrado na imagem a seguir):
- A colisão em verde representa o colisor da plataforma com o personagem;
- A colisão em vermelho indica o colisor da área do nó
body_detector. Esse colisor que dirá se o personagem entrou em contato com a plataforma para que ela caia; - Não esqueça de especificar a camada em que o nó está e com quem ele colidirá.
📝 Nota É importante que o colisor do nó 'Area2D' fique acima do colisor do nó raiz, para que não haja interferências na detecção do personagem e não acabe ocasionando erro na queda da plataforma.
Animação de alerta
Assim que o jogador colidir com a plataforma, ela vai tremer, informando ao jogador que ela vai cair e que ele precisa sair daquela plataforma. Esse tipo de alerta melhora a experiência do jogador ao ser avisado de possíveis acontecimentos enquanto ele joga.
Para fazer essa animação vamos ao nó anim criar uma nova animação alert. Vamos trabalhar com a propriedade Position do nó sprite.
- Crie a animação
alert; - Determine o tempo de animação (eu coloquei 0.4);
- Deixe ativado o botão de
Animation Looping(aparecerá inicialmente com o símbolo de Looping 🔁, clique novamente até mudar a imagem para um simbolo assim ↔️); - Selecione o nó
spritee vá na abaInspector/Position; - Agora clique na 🗝️ da propriedade
Position, isso adicionará um novo ponto na linha de animação; - Agora repita isso para os instantes de tempo
0.1 --> x = 2,0.2 --> x = 0,0.3 --> x = -2e0.4 --> x = 0. Os valores de X são os valores da propriedadePositionno eixo X. Não esqueça de sempre finalizar a alteração de um valor clicando na chave da propriedade para que as alterações sejam salvas na linha do tempo da animação.
A imagem abaixo exemplifica a linha do tempo da animação e as propriedades citadas como o tempo, o lopping e posição no eixo x para que você se localize melhor dentro da engine:

Agora vamos criar o Script da cena e Sinais necessários:
No nó fall_platform_respawn crie um novo script e adicione a ele dois sinais:
- Adicione ao script o sinal
body_entered(body: Node2D)do nóbody_detector; - Adicione ao script o sinal
timeout()do nórespawn_timer.
Não sabe adicionar sinais? Sem problema, é bem simples. Vamos lá!
- Selecione o nó desejado, por exemplo
respawn_detector (Timer); - Na aba de propriedades temos
Inspector - Node - History, clique emNode; - Teremos
SignalseGroups, clique emSignalsse já não estiver selecionado; - Procure o sinal desejado, no caso do nó
respawn_detectorqueremos o sinaltimeout(), clique duas vezes no sinal; - Uma janela para conectar esse sinal a um método será aberta;
- Selecione o nó com o script que fará uso desse sinal (nesse caso o nó
fall_platform_respawn); - Clique em
Connecte então é só partir para o script! 😉
Vamos ao código:
extends RigidBody2D
@onready var respawn_position = self.global_position
@onready var anim = $anim
- A classe do script herda de RigidBody2D;
respawn_positionarmazena a posição inicial da plataforma;animreferencia o nó de animaçãoAnimationPlayercujo nome foi renomeado paraanim.
func _on_body_detector_body_entered(body):
if body.name == "player":
anim.play("alert")
await get_tree().create_timer(1).timeout
set_deferred("freeze", false)
$respawn_timer.start()
- A função
_on_body_detector_body_entered(body)é chamada quando um corpo entra na área de detecção do nóbody_detector; - Primeiro, verifica se o corpo que entrou é o jogador;
- Se for, executa a animação de alerta, indicando que a plataforma vai cair;
- Aguarda 1 segundo;
- Define
freezecomofalse(Se a propriedadefreezefor verdadeira, o corpo fica congelado. A gravidade e a forças não são aplicadas, por isso é importante definirfalsequando quiser que a plataforma sofra com gravidade e outras forças); - Inicia um temporizador
(respawn_timer)para a plataforma se reposicionar depois de cair.
func respawn_platform():
global_position = respawn_position
anim.play("RESET")
set_deferred("freeze", true)
- A função
respawn_platform()Define o comportamento para reposicionar a plataforma após a queda; global_position = respawn_position:Reposiciona a plataforma na posição inicial;anim.play("RESET"):Toca a animação de reset para a plataforma;set_deferred("freeze", true):Define freeze como true novamente, para que a plataforma fique congelada em sua posição inicial até a próxima colisão com o jogador.
func _on_respawn_timer_timeout():
respawn_platform()
- A função
_on_respawn_timer_timeout():é chamada quando o temporizador(respawn_timer)expira; respawn_platform():Chama a funçãorespawn_platform()para reposicionar e "resetar" a plataforma.
3ª Plataforma: plataforma de movimento horizontal e vertical ↔️ ↕️
Chegamos na 3ª plataforma desse tutorial. Essa plataforma móvel tem direção no eixo X e Y é essa direção é escolhida de forma muito simples através de uma variavél externa na qual escolhemos o eixo de movimento de nossa plataforma.
Após criar uma nova cena para essa plataforma diferente das anteriores, vamos aos nós:
- AnimatableBody2D
- CollisionShape2D
- Sprite2D
Após renomeá-los, a árvore ficou assim:
Próximos passos:
- Escolha sua sprite de plataforma;
- Defina a forma do colisor mais ideal para a sua plataforma;
- Não esqueça de ativar
One Way Collisionnas propriedades do nóCollisionShape2Dcaso você deseje que o personagem não sofra colisão ao pular na plataforma de baixo para cima; - Crie um script para o nó
AnimatableBody2D.
Agora que criamos uma cena para a plataforma, vamos instanciá-la 🔗 (Atalho: Ctrl+Shift+A) em nossa cena principal e adicionar um novo nó filho do tipo AnimationPlayer a essa plataforma, como exemplifica a imagem a seguir:

⚠️ Atenção O nó "anim" (AnimationPLayer) deve ser filho do nó "move_platform". Se o nó for posto como filho do nó raiz "World-01" a animação da plataforma terá erros. Verifique o exemplo na imagem acima.
Animação da plataforma:
A plataforma terá duas animações: deslocamento no eixo X (horizontal) e outra no eixo Y (vertical). Para fazermos essas animações no nó filho anim (AnimationPLayer) utilizaremos somente a propriedade Position.
Vou citar duas maneiras de se fazer essa animação:
-
Salvar cada posição clicando na chave ao lado da propriedade manipulada:
- Você pode utilizar a chave 🔑 ao lado da propriedade
Positionpara cada posição que você desejar salvar na linha do tempo da animação, como fizemos em exemplos anteriores.
- Você pode utilizar a chave 🔑 ao lado da propriedade
-
Salvar cada posição com
Auto insert keys:- Pode utilizar o botão
recpara inserir chaves nos instantes de tempo selecionados na animação. Com oAuto insert keysselecionado (ele fica em vermelho) como na imagem abaixo mostra, escolha o instante de tempo, por exemplo em 0.5 segundos e mova o sprite da plataforma até a posição desejada na cena e solte o botão do mouse. Você notará que uma chave será criada na linha do tempo da animação com a posição em X e/ou Y alterada conforme posicionado; - Para essa simples animação determine o tempo em 1 segundo e deixe selecionado o
Animation Looping. No instante 0 indique a posição inicial da plataforma, no instante de tempo 0.5 mova a plataforma na horizontal ou vertical e o instante de tempo 1 retorne à posição inicial da plataforma. Com isso a animação de ida e vinda estará feita; - Faça esse processo para a animação de movimento da horizontal
move_horizontale movimento na verticalmove_vertical. Deixei minha animaçãomove_verticalcom oAutoplay on Loadhabilitado, pois será a animação qua a minha plataforma terá. - Por fim, configure a propriedade
Speed Scalepara a velocidade desejada para a velocidade de deslocamento da plataforma.
- Pode utilizar o botão
Na imagem abaixo, está em destaque o local do botão Auto insert keys, local de criação de uma nova animação Animation, botão de Autoplay on Load, Animation Looping e Speed Scale.

Vamos ao código:
No script do nó move_platform adicione o script a seguir:
extends AnimatableBody2D
@onready var anim = $anim
@export_enum("move_horizontal", "move_vertical") var move_direction = 0
func _ready():
pass
anim.assigned_animation = "move_horizontal" if move_direction == 0 else "move_vertical"
Explicação resumida do script:
-
Extensão de
AnimatableBody2D:- A classe atual herda funcionalidades de
AnimatableBody2D, um nó usado para corpos animáveis em 2D.
- A classe atual herda funcionalidades de
-
Inicialização de
anim:- Utilizar
@onreadyassegura que a variávelanimseja inicializada apenas quando o nó estiver pronto. O$animé um atalho paraget_node("anim"), ou seja, ele está buscando um nó filho chamadoanim. Isso geralmente é utilizado para acessar nós definidos na cena associada a este script.
- Utilizar
-
Exportar Direção de Movimento:
-
Aqui,
@export_enumcria uma propriedade exportada que pode ser editada diretamente no editor da Godot, sem necessidade de retornar ao código para alterar o eixo de direção da plataforma. Os valores possíveis definidos na animação feita anteriormente sãomove_horizontalemove_vertical, emove_directionserá um inteiro que pode ser 0 ou 1, correspondendo a essas direções.var move_direction = 0define o valor padrão paramove_directioncomo 0 (que representamove_horizontal); -
Na imagem a seguir, podemos observar o resultado dessa exportação. Nas propriedades da animação, podemos escolher qual animação a plataforma terá sem que seja necesário acessar o código novamente.
-
-
Função
_ready():- Quando o nó e seus filhos estão prontos, a função
_ready()configura a animação doanimbaseado no valor demove_direction: se for 0, a animação émove_horizontal; caso contrário, émove_vertical.
- Quando o nó e seus filhos estão prontos, a função
Plataforma BÔNUS ⭐
Você reparou no início do passo a passo o GIF exemplificando o funcionamento de cada plataforma? Notou na plataforma no rio que ao detectar a colisão com o jogador ela emite um alerta de que é instável e após um tempo determinado afunda e sobe novamente, semelhante ao comportamento de uma madeira no rio? Afunda com a colisão e após um tempo predeterminado sobe e continua boiando na água. Vamos construí-la? 🔧
Árvore de nós:
Crie uma nova cena para essa plataforma e adicione os seguintes nós:
- RigidBody2D
- Sprite2D
- CollisionShape2D
- AnimationPlayer
- Area2D
- CollisionShape2D
Nós renomeados:

Próximos passos:
- Crie um script para o nó
fall_platform; - Adicione a sprite desejada;
- Configure a colisão do nó raiz
fall_platform; - Configure a colisão do nó filho de
body_detector, sendo essa colisão responsável por detectar o personagem colidindo para executar as animações (Importante! Essa colisãocollision_detectordeve ficar acima do nó de colisãocollision, semelhante à plataforma de queda visto anteriormente); - Adicione o sinal
body_detector(body: Node2D)do nóbody_detector(Area2D) ao script criado.
Animações:
Serão utilizadas 3 animações:
- float: animação inicial com
"Autoplay on Load"e"Animation Looping"🔛 habilitados.- Propriedades utilizadas:
texture,positionerotation; - Propriedade que será alterada:
position; - Tempo de animação: 1 segundo;
- Instante de tempo 0: valores iniciais das propridades X e Y iguais a 0;
- Instante de tempo 1: valor de
positionno eixo Y =-3e X = 0.
- Propriedades utilizadas:
Essas configurações darão o efeito de plataforma flutuando na água. A imagem a seguir auxilia na aplicação das propriedades:

- alert: animação de alerta que faz a plataforma chacoalhar alertando o jogador que ela é instável e que ele precisa sair dela.
"Animation Looping"🔛 habilitado;- Propriedades utilizadas:
texture,positionerotation; - Propriedade que será alterada:
rotation; - Tempo de animação: 0.5 segundos;
- Instante de tempo 0:
Rotation = 0°; - Instante de tempo 0.1:
Rotation = 5°; - Instante de tempo 0.2:
Rotation = 0°; - Instante de tempo 0.3:
Rotation = -5°; - Instante de tempo 0.4:
Rotation = 0°; - Instante de tempo 0.5:
Rotation = 5°;

- falling: animação de queda da plataforma e subida.
"Animation Looping"🔛 desabilitado;- Propriedades utilizadas:
texture,positionerotation; - Propriedade que será alterada:
position; - Tempo de animação: 3 segundos;
- Instante de tempo 0:
position Y = 0; - Instante de tempo 0.5:
position Y = 100; - Instante de tempo 3:
position Y = 0;
- Propriedades utilizadas:
Com essa animação, a plataforma cai rapidamente e sobe lentamente.

Vamos ao código:
extends RigidBody2D
@onready var respawn_position = self.global_position
@onready var anim = $anim
@onready var collision = $collision
@onready var collision_detector = $body_detector/collision_detector
Aqui temos as referências aos nós necessários como AnimationPlayer, CollisionShape2D e posição inicial da plataforma.
func _on_body_detector_body_entered(body):
if body.name == "player":
anim.play("alert")
await get_tree().create_timer(1).timeout
collision.disabled = true
collision_detector.disabled = true
anim.play("falling")
await get_tree().create_timer(3).timeout
collision.disabled = false
collision_detector.disabled = false
anim.play("float")
Nesta função, executamos ações quando o detector de colisão detecta a entrada de um corpo:
- Se o corpo é o jogador
(body.name == "player"): - Toca a animação "alert";
- Espera 1 segundo;
- Desabilita a colisão e o detector de colisão;
- Toca a animação "falling";
- Espera 3 segundos;
- Reabilita a colisão e o detector de colisão;
- Toca a animação "float".
É importante desabilitar temporariamente os colisores no momento em que a plataforma esteja em queda ou subindo para evitar que o jogador ainda possa colidir naquelas posições como se estivesse andando sobre a água.
Veja o jogo completo no GitHub.
Veja os outros capítulos do curso.
