pratica

Movimento de Personagens 2D: KinematicBody2D

Aprenda sobre movimento de personagens 2d: kinematicbody2d

45 min
Aula 3 de 5

Movimento de Personagens 2D: KinematicBody2D

Olá, futuros desenvolvedores de jogos! 👋 Nesta aula prática, vamos mergulhar no coração do movimento de personagens 2D no Godot Engine, utilizando o nó KinematicBody2D. Este é um dos componentes mais importantes para criar jogadores e inimigos que você controla diretamente através de código. Prepare-se para dar vida aos seus personagens! 🚀

1. Introdução: Dando Vida aos Seus Personagens ✨

No desenvolvimento de jogos 2D, mover um personagem de forma responsiva e previsível é fundamental. O Godot oferece várias opções para corpos físicos, mas para personagens controlados pelo jogador, o KinematicBody2D é a escolha ideal.

Diferente de um RigidBody2D (que é movido por forças físicas e simulação), o KinematicBody2D é projetado para ser movido inteiramente pelo seu código. Ele não se move por conta própria com base em gravidade ou colisões; em vez disso, você define sua velocidade e o Godot lida com a detecção e resposta a colisões de forma suave. Isso nos dá controle total sobre como nosso personagem interage com o ambiente.

Vamos começar a explorar como ele funciona!

2. Entendendo o KinematicBody2D 🧠

O KinematicBody2D é uma classe que herda de PhysicsBody2D, o que significa que ele pode detectar colisões com outros corpos físicos. Sua principal característica é que ele não é afetado pela física automaticamente. Você "empurra" o corpo programaticamente, e ele relata o que colidiu e como ele deveria deslizar ou parar.

Os métodos mais importantes para mover um KinematicBody2D são:

  • move_and_slide(): O método mais comum para movimento de personagens. Ele move o corpo, detecta colisões e tenta deslizar ao longo das superfícies colididas. É perfeito para um personagem que anda em plataformas e sobe rampas.
  • move_and_collide(): Este método move o corpo e para imediatamente ao colidir com algo. Ele retorna um objeto KinematicCollision2D que contém informações detalhadas sobre a colisão. É útil para projéteis ou para quando você precisa de controle mais granular sobre a resposta à colisão.

Nesta aula, focaremos principalmente no move_and_slide() por ser o mais adequado para o movimento de um personagem principal.

2.1. O Método move_and_slide() 🏃‍♂️

O método move_and_slide() é a estrela do show para o movimento de personagens. Ele recebe um vetor de velocidade (Vector2) como argumento principal e, opcionalmente, um vetor de direção para cima (up_direction).

func _physics_process(delta):
    # 'velocity' é um Vector2 que representa a velocidade atual do corpo.
    # Ele é definido pelo seu código (input do jogador, gravidade, etc.).
    velocity = move_and_slide(velocity, up_direction)
  • velocity (Vector2): A velocidade desejada do corpo. move_and_slide() tentará mover o corpo por essa velocidade.
  • up_direction (Vector2): Este é um parâmetro crucial! Ele informa ao Godot qual direção é "para cima" para o seu personagem. Geralmente é Vector2.UP (ou Vector2(0, -1)). Isso permite que o Godot identifique superfícies como pisos (onde o personagem pode "ficar") e paredes (onde ele deve "deslizar"). É essencial para que a gravidade e o pulo funcionem corretamente.

O move_and_slide() retorna a velocidade restante após a colisão. Isso é importante porque, se você colidir com uma parede, a velocidade horizontal pode ser zerada, mas a vertical (gravidade) pode continuar. Ao atribuir o resultado de volta à sua variável velocity, você garante que a velocidade do seu personagem seja atualizada corretamente após as interações com o mundo.

2.2. Implementando Input e Gravidade 🎮⬇️

Para mover nosso personagem, precisaremos de duas coisas:

  1. Input do jogador: Para saber quando o jogador quer mover o personagem.
  2. Gravidade: Para que o personagem caia quando não estiver em uma plataforma.

Vamos ver um exemplo básico:

# KinematicBody2D.gd
extends KinematicBody2D
 
@export var speed: float = 100.0 # Velocidade de movimento
@export var jump_force: float = 300.0 # Força do pulo
@export var gravity: float = 800.0 # Força da gravidade
 
var velocity: Vector2 = Vector2.ZERO # Velocidade atual do personagem
 
func _physics_process(delta: float) -> void:
    # 1. Aplicar Gravidade
    if not is_on_floor(): # Se não estiver no chão, aplica gravidade
        velocity.y += gravity * delta
 
    # 2. Capturar Input Horizontal
    var direction: float = Input.get_axis("move_left", "move_right")
    if direction != 0:
        velocity.x = direction * speed
    else:
        velocity.x = move_toward(velocity.x, 0, speed * delta) # Desacelera se não houver input
 
    # 3. Capturar Input de Pulo
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = -jump_force # Pulo (eixo Y negativo é para cima no Godot)
 
    # 4. Mover o personagem e lidar com colisões
    # O Vector2.UP (0, -1) indica a direção "para cima" para o Godot.
    velocity = move_and_slide(velocity, Vector2.UP)

Explicação do Código:

  • @export var speed: float = 100.0: Define uma variável de velocidade que pode ser ajustada no editor.
  • _physics_process(delta): Esta função é chamada a cada frame físico, ideal para lógica de movimento e física. delta é o tempo decorrido desde o último frame, essencial para movimentos suaves e independentes da taxa de quadros.
  • if not is_on_floor():: O KinematicBody2D possui métodos úteis como is_on_floor(), is_on_wall(), is_on_ceiling() para verificar o estado de colisão.
  • velocity.y += gravity * delta: Acelera o personagem para baixo.
  • Input.get_axis("move_left", "move_right"): Uma forma conveniente de obter um valor entre -1 e 1 para movimento horizontal, combinando duas ações de input.
  • move_toward(velocity.x, 0, speed * delta): Desacelera a velocidade horizontal para 0 quando o jogador solta as teclas de movimento.
  • Input.is_action_just_pressed("jump"): Detecta quando a ação "jump" é pressionada (apenas uma vez por pressionamento).
  • velocity.y = -jump_force: Define a velocidade vertical para um valor negativo para pular (lembre-se, Y negativo é para cima no Godot).
  • velocity = move_and_slide(velocity, Vector2.UP): Move o corpo e atualiza a velocidade com base nas colisões. Vector2.UP é crucial para o is_on_floor() funcionar corretamente.

2.3. O Método move_and_collide() 💥

Para casos onde você precisa de um controle mais preciso sobre a colisão, ou quando o objeto não deve deslizar, move_and_collide() é a escolha.

# Exemplo de um projétil simples
extends KinematicBody2D
 
@export var speed: float = 500.0
 
func _physics_process(delta: float) -> void:
    var collision_info: KinematicCollision2D = move_and_collide(transform.x * speed * delta)
    if collision_info:
        print("Colidiu com: ", collision_info.get_collider().name)
        queue_free() # Destrói o projétil ao colidir
  • move_and_collide() recebe um Vector2 que representa o vetor de movimento.
  • Ele retorna um objeto KinematicCollision2D se uma colisão ocorrer, ou null caso contrário.
  • O objeto KinematicCollision2D contém informações como:
    • get_collider(): O nó com o qual colidiu.
    • get_position(): O ponto de colisão no espaço global.
    • get_normal(): A normal da superfície colidida.

3. Código de Exemplo Oficial (Adaptado) 🧑‍💻

A documentação oficial do Godot frequentemente apresenta exemplos de scripts de movimento para KinematicBody2D. O código a seguir é uma adaptação de um exemplo comum, utilizando as melhores práticas para o Godot 4.

Crie uma nova cena 2D no Godot.

  1. Adicione um KinematicBody2D como nó raiz. Renomeie-o para Player.
  2. Adicione um Sprite2D como filho do Player. Carregue uma textura para ele (pode ser um ícone do Godot ou qualquer imagem pequena).
  3. Adicione um CollisionShape2D como filho do Player. Adicione um RectangleShape2D ou CapsuleShape2D ao shape no inspetor para que ele tenha uma forma de colisão. Ajuste o tamanho para cobrir o Sprite2D.
  4. Crie um novo script GDScript para o nó Player.
# Player.gd
extends KinematicBody2D
 
@export var speed: float = 150.0 # Velocidade de movimento horizontal
@export var jump_velocity: float = 400.0 # Força do pulo
@export var acceleration: float = 10.0 # Quão rápido o personagem acelera/desacelera
 
# Gravidade é um valor fixo para o projeto.
# Você pode obtê-lo de Project Settings -> Physics -> 2D -> Default Gravity.
# Ou definir uma variável aqui.
var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
 
var _velocity: Vector2 = Vector2.ZERO
 
func _physics_process(delta: float) -> void:
    # 1. Aplicar Gravidade
    if not is_on_floor():
        _velocity.y += gravity * delta
 
    # 2. Capturar Input Horizontal
    var input_direction: float = Input.get_axis("move_left", "move_right")
    if input_direction != 0:
        _velocity.x = lerp(_velocity.x, input_direction * speed, acceleration * delta)
    else:
        _velocity.x = lerp(_velocity.x, 0.0, acceleration * delta)
 
    # 3. Capturar Input de Pulo
    # Certifique-se de que "jump" é uma ação configurada em Project Settings -> Input Map
    if Input.is_action_just_pressed("jump") and is_on_floor():
        _velocity.y = -jump_velocity
 
    # 4. Mover e Colidir
    _velocity = move_and_slide(_velocity, Vector2.UP)

Configuração do Input Map:

Para que o script funcione, você precisa configurar as ações "move_left", "move_right" e "jump" no seu projeto Godot:

  1. Vá em Project -> Project Settings....
  2. Clique na aba Input Map.
  3. Na caixa Action, digite move_left e clique em Add.
  4. Clique no sinal + ao lado de move_left e selecione Physical Key. Pressione a tecla A (ou a que preferir).
  5. Repita para move_right (tecla D).
  6. Repita para jump (tecla Space).

4. Exercícios/Desafios Práticos 🛠️

Agora é a sua vez de colocar a mão na massa! Siga os passos abaixo para criar um personagem jogável do zero.

Checklist de Tarefas:

  • Criar um Novo Projeto Godot: Inicie um novo projeto 2D no Godot Engine.
  • Configurar Cena Principal:
    • Crie uma nova cena 2D (Node2D).
    • Salve-a como Main.tscn.
    • Adicione um nó StaticBody2D (renomeie para Floor) e um CollisionShape2D com um RectangleShape2D para criar um chão. Estique o retângulo para que cubra a parte inferior da tela.
    • Adicione um ColorRect ou Sprite2D para representar visualmente o chão.
    • Adicione outro StaticBody2D (renomeie para Wall) e um CollisionShape2D com um RectangleShape2D para criar uma parede. Posicione-o para que o jogador possa colidir com ele.
    • Adicione um ColorRect ou Sprite2D para representar visualmente a parede.
  • Criar a Cena do Jogador:
    • Crie uma nova cena 2D (Node2D).
    • Mude o nó raiz para KinematicBody2D (clique com o botão direito no Node2D e selecione Change Type). Renomeie-o para Player.
    • Adicione um Sprite2D como filho do Player. Use o ícone padrão do Godot (icon.svg) ou importe sua própria imagem.
    • Adicione um CollisionShape2D como filho do Player.
      • No Inspetor, em Shape, crie um RectangleShape2D ou CapsuleShape2D.
      • Ajuste o tamanho do shape para que ele cubra o Sprite2D do seu personagem.
    • Salve esta cena como Player.tscn.
  • Instanciar o Jogador:
    • Na cena Main.tscn, arraste Player.tscn da aba FileSystem para a cena.
    • Posicione o jogador acima do chão.
  • Configurar o Script do Jogador:
    • No nó Player da cena Player.tscn, anexe um novo script GDScript (use o nome Player.gd).
    • Copie e cole o código do exemplo oficial fornecido acima (Player.gd) no seu script.
    • Ajuste as variáveis @export (speed, jump_velocity, acceleration) no Inspetor do nó Player na cena Main.tscn para encontrar valores que você goste.
  • Configurar o Input Map:
    • Vá em Project -> Project Settings... -> Input Map.
    • Adicione as ações move_left (tecla A), move_right (tecla D) e jump (tecla Space).
  • Testar o Jogo:
    • Execute a cena Main.tscn (F6).
    • Teste o movimento horizontal, a gravidade e o pulo.
    • Observe como o personagem desliza na parede e para no chão.

Desafios Adicionais (Opcional): 💡

  1. Animação Básica:
    • Adicione um AnimationPlayer como filho do seu Player.
    • Crie animações simples para "idle" (parado) e "run" (correndo) alterando a frame ou hframes/vframes do seu Sprite2D (se você tiver uma spritesheet).
    • Modifique o script Player.gd para reproduzir a animação correta com base na _velocity.x e is_on_floor().
  2. Pulo Variável:
    • Implemente um pulo variável: Se o botão de pulo for solto antes do ápice do pulo, o personagem deve começar a cair mais cedo. Isso geralmente envolve verificar Input.is_action_just_released("jump") e ajustar _velocity.y.
  3. Plataformas Móveis:
    • Crie uma nova cena para uma plataforma móvel (KinematicBody2D ou AnimatableBody2D).
    • Faça com que ela se mova para frente e para trás usando move_and_collide() ou tween.
    • Posicione a plataforma na sua cena Main.tscn e veja como seu jogador interage com ela. (Dica: move_and_slide() do jogador já lida bem com plataformas móveis se a plataforma for um KinematicBody2D movido por move_and_slide() ou um AnimatableBody2D).

5. Resumo e Próximos Passos 🎯

Parabéns! 🎉 Você aprendeu a base para o movimento de personagens 2D no Godot usando KinematicBody2D.

Nesta aula, você viu:

  • A diferença entre KinematicBody2D e outros corpos físicos.
  • Como usar move_and_slide() para um movimento suave e com detecção de colisão.
  • Como implementar gravidade, input de movimento horizontal e pulo.
  • A importância do up_direction e dos métodos is_on_floor().
  • Uma breve introdução ao move_and_collide() para colisões mais controladas.

Com esses fundamentos, você pode criar a base para qualquer jogo de plataforma ou aventura 2D.

Próximos Passos:

  • Animações Avançadas: Explore o nó AnimationTree para gerenciar transições complexas entre animações de forma mais robusta.
  • Máquinas de Estado: Para personagens com muitos comportamentos (andar, pular, atacar, agachar, etc.), uma máquina de estado (State Machine) é uma ferramenta poderosa para organizar seu código.
  • Interação com Inimigos: Use KinematicBody2D para criar inimigos que se movem e interagem com o jogador.
  • Mecânicas de Jogo: Comece a pensar em como você pode usar esses movimentos básicos para criar mecânicas de jogo interessantes, como escalar paredes, dash, etc.

Continue praticando e experimentando! A melhor forma de aprender é construindo. 💪

© 2025 Escola All Dev. Todos os direitos reservados.

Movimento de Personagens 2D: KinematicBody2D - Fundamentos do Godot: Desenvolvimento de games para iniciantes | escola.all.dev.br