Godot do Zero: Colisões, shapes e camadas/máscaras

Capítulo 6

Tempo estimado de leitura: 8 minutos

+ Exercício

O que são colisões na Godot (corpo, forma e filtro)

Na Godot 2D, a colisão acontece quando um nó de física (por exemplo, CharacterBody2D, RigidBody2D, StaticBody2D ou Area2D) possui uma ou mais formas de colisão (shapes) e elas se sobrepõem conforme as regras de camadas (layers) e máscaras (masks).

  • Body: participa da simulação física (bloqueia, empurra, é bloqueado) ou detecta presença (no caso de Area2D).
  • Shape: define o “volume” 2D que colide (retângulo, cápsula, círculo etc.).
  • Layers/Masks: definem quem “existe” para quem. Você pode separar jogador, inimigos, cenário e hitboxes sem gambiarras.

Adicionando CollisionShape2D ao Player (alinhamento com Sprite)

Conceito: o Sprite não colide, a Shape colide

Um erro comum é achar que o Sprite2D “tem colisão”. Na prática, o sprite é só visual. Quem colide é o CollisionShape2D (ou CollisionPolygon2D) ligado ao nó de física.

Passo a passo (Player com CharacterBody2D)

  • Abra a cena do Player (raiz CharacterBody2D).
  • Adicione um filho: CollisionShape2D.
  • No Inspector do CollisionShape2D, em Shape, escolha uma forma adequada (ex.: CapsuleShape2D).
  • Ajuste o tamanho da shape (arrastando as alças no viewport) para cobrir o corpo do personagem.
  • Alinhe a shape ao sprite: selecione o CollisionShape2D e ajuste Position para que a cápsula fique centralizada no personagem (normalmente alinhada ao tronco, não incluindo “vazios” como cabelo/efeitos).

Formas comuns e quando usar

ShapeQuando usarVantagensCuidados
RectangleShape2DCaixas, inimigos quadrados, plataformas, objetos simplesSimples, rápido de ajustarEm personagens, cantos podem “prender” em quinas
CapsuleShape2DPersonagens que andam e encostam em paredesDesliza melhor em cantos e rampasEvite cápsula muito larga (piora a sensação em corredores)

Dica de alinhamento (para evitar sensação de “flutuar”)

Deixe a shape encostar no “pé” do sprite (base do personagem). Se a cápsula ficar alta demais, o personagem aparenta flutuar; se ficar baixa demais, pode “afundar” visualmente no chão.

Colisão no cenário: StaticBody2D + CollisionShape2D

Conceito: cenário sólido normalmente é StaticBody2D

Para paredes, chão e plataformas sólidas, use StaticBody2D com CollisionShape2D. Ele não se move por física, mas bloqueia outros corpos.

Passo a passo (chão simples)

  • Crie uma cena ou nó para o chão: StaticBody2D.
  • Adicione um filho CollisionShape2D.
  • Escolha RectangleShape2D e dimensione como uma plataforma.
  • Se houver um visual (ex.: Sprite2D ou TileMap), alinhe a shape para coincidir com a área sólida real (não necessariamente com toda a arte).

Observação sobre TileMap

Se você estiver usando TileMap, as colisões podem ser definidas nos tiles (no editor de tiles). Mesmo assim, o raciocínio de shapes e layers/masks continua o mesmo: o TileMap gera colisores para o cenário.

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

Camadas e máscaras: separando jogador, inimigos, cenário e hitboxes

Conceito: Layer é “onde eu estou”, Mask é “o que eu enxergo”

  • Collision Layer: em quais camadas este objeto existe.
  • Collision Mask: com quais camadas este objeto interage (colide/detecta).

Exemplo prático: o Player pode estar na camada “Player” e ter máscara “World” e “Enemies”. Assim ele colide com cenário e inimigos, mas ignora hitboxes específicas se você separar em outra camada.

Plano de camadas sugerido (exemplo)

Camada (Layer)NúmeroUso
World1Chão, paredes, obstáculos sólidos
Player2Corpo do jogador
Enemy3Corpo dos inimigos
PlayerHitbox4Área de ataque do jogador (dano)
EnemyHurtbox5Área que recebe dano no inimigo

Configuração recomendada (exemplo)

  • Player (CharacterBody2D): Layer = Player (2). Mask = World (1) + Enemy (3). (Opcional: também colidir com EnemyHurtbox se você quiser empurrar, mas geralmente não.)
  • Enemy (CharacterBody2D ou RigidBody2D): Layer = Enemy (3). Mask = World (1) + Player (2).
  • World (StaticBody2D/TileMap): Layer = World (1). Mask = Player (2) + Enemy (3).
  • PlayerHitbox (Area2D): Layer = PlayerHitbox (4). Mask = EnemyHurtbox (5).
  • EnemyHurtbox (Area2D): Layer = EnemyHurtbox (5). Mask = PlayerHitbox (4).

Separar hitbox (quem causa dano) e hurtbox (quem recebe dano) evita que o corpo físico do inimigo “seja o dano” e dá controle fino para ataques, invencibilidade e múltiplas zonas de acerto.

Criando uma área de dano com Area2D (hitbox/hurtbox)

Conceito: Area2D detecta sobreposição, não bloqueia movimento

Area2D é ideal para detecção: dano, coleta de itens, zonas de perigo, sensores. Ela não impede o movimento como um body sólido; ela apenas emite sinais quando algo entra/sai.

Passo a passo: Hitbox de ataque do Player

  • No Player, adicione um filho Area2D chamado Hitbox.
  • Dentro de Hitbox, adicione CollisionShape2D.
  • Escolha uma shape (geralmente RectangleShape2D para um golpe “em caixa”, ou CapsuleShape2D para um golpe mais “arredondado”).
  • Posicione a hitbox à frente do personagem (ex.: no lado direito). Se o personagem virar, você pode espelhar a posição (ver exemplo de código abaixo).
  • Configure Layers/Masks: Hitbox na layer PlayerHitbox e mask EnemyHurtbox.
  • Desative a hitbox por padrão para não causar dano o tempo todo (ex.: monitoring = false ou disabled na shape).

Passo a passo: Hurtbox no inimigo

  • No inimigo, adicione um filho Area2D chamado Hurtbox.
  • Adicione CollisionShape2D e ajuste para cobrir a parte “atingível”.
  • Configure Layers/Masks: Hurtbox na layer EnemyHurtbox e mask PlayerHitbox.

Conectando sinais para detectar contato (body_entered e area_entered)

Qual sinal usar?

  • body_entered(body: Node): quando um PhysicsBody2D entra na Area2D (ex.: Player entrando numa zona de perigo).
  • area_entered(area: Area2D): quando uma Area2D entra em outra Area2D (ex.: Hitbox do player encostando na Hurtbox do inimigo).

Exemplo: Hurtbox do inimigo detectando a Hitbox do player (area_entered)

No nó Hurtbox (Area2D do inimigo), conecte o sinal area_entered para o script do inimigo (ou do próprio Hurtbox). Exemplo em GDScript:

extends Area2D @export var damage_receiver_path: NodePath var damage_receiver: Node func _ready() -> void: if damage_receiver_path != NodePath(): damage_receiver = get_node(damage_receiver_path) func _on_area_entered(area: Area2D) -> void: # Filtragem extra por grupo é opcional, mas ajuda na depuração if not area.is_in_group("player_hitbox"): return var dmg := 1 if area.has_method("get_damage"): dmg = area.get_damage() if damage_receiver and damage_receiver.has_method("apply_damage"): damage_receiver.apply_damage(dmg)

Para isso funcionar bem:

  • Adicione a Hitbox do player ao grupo player_hitbox (Node > Groups).
  • Garanta que Layers/Masks estejam corretas (Hitbox enxerga Hurtbox e vice-versa).

Exemplo: Hitbox do player com dano configurável

No script da Hitbox (Area2D):

extends Area2D @export var damage: int = 1 func get_damage() -> int: return damage

Ativando a hitbox apenas durante o ataque

Uma abordagem simples é ligar/desligar o monitoramento da área:

# No script do Player (exemplo) @onready var hitbox: Area2D = $Hitbox func start_attack() -> void: hitbox.monitoring = true func end_attack() -> void: hitbox.monitoring = false

Se preferir, você pode desabilitar a shape em vez do monitoring:

@onready var hitbox_shape: CollisionShape2D = $Hitbox/CollisionShape2D func start_attack() -> void: hitbox_shape.disabled = false func end_attack() -> void: hitbox_shape.disabled = true

Espelhando a posição da hitbox quando o player vira

Se você usa uma variável de direção (ex.: facing = 1 para direita e -1 para esquerda), pode reposicionar a hitbox:

@onready var hitbox: Area2D = $Hitbox @export var hitbox_offset: Vector2 = Vector2(18, 0) var facing: int = 1 func update_hitbox_side() -> void: hitbox.position = Vector2(hitbox_offset.x * facing, hitbox_offset.y)

Recomendações de depuração (colisões, máscaras e testes)

1) Visualizar colisões no editor e em execução

  • No editor 2D, selecione o nó e confira se a shape está realmente cobrindo a área correta.
  • Durante o jogo, ative a visualização de colisões: em geral, você pode usar o menu Debug para habilitar a exibição de shapes/colisores (a opção exata pode variar por versão, mas procure por algo como “Visible Collision Shapes”).

2) Checar Layers/Masks (o erro mais comum)

  • Se nada colide/detecta: verifique se a máscara inclui a camada do outro objeto.
  • Se está colidindo com coisa errada: reduza a máscara para apenas o necessário.
  • Em hitbox/hurtbox: confirme que você está usando area_entered (Area com Area) e não body_entered.

3) Testes com múltiplos objetos

  • Coloque 2 ou 3 inimigos próximos e teste se a hitbox acerta todos (ou apenas um, se essa for a regra do seu jogo).
  • Teste hitbox encostando no cenário: ela não deveria “bater” no World se a máscara não incluir World.
  • Teste tamanhos extremos: hitbox muito grande pode causar dano sem intenção; muito pequena pode falhar em contatos rápidos.

4) Logs rápidos para confirmar eventos

Durante a depuração, use prints temporários para confirmar se o sinal está disparando e qual objeto entrou:

func _on_area_entered(area: Area2D) -> void: print("Hurtbox tocada por: ", area.name, " layer/mask ok?")

Se o print nunca aparece, o problema quase sempre é: shape ausente/desabilitada, monitoring desligado, ou layers/masks incompatíveis.

Agora responda o exercício sobre o conteúdo:

Ao criar um sistema de ataque com Hitbox e Hurtbox usando Area2D, qual configuração garante que o dano seja detectado sem bloquear o movimento, e apenas quando o ataque estiver ativo?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Area2D detecta sobreposição e não bloqueia movimento. Para dano entre áreas, use area_entered (Area2D com Area2D), configure Layers/Masks corretamente e ative a hitbox só durante o ataque via monitoring ou disabled na shape.

Próximo capitúlo

Godot do Zero: TileMap e construção do cenário 2D jogável

Arrow Right Icon
Capa do Ebook gratuito Godot do Zero: Criando seu Primeiro Jogo 2D com GDScript
35%

Godot do Zero: Criando seu Primeiro Jogo 2D com GDScript

Novo curso

17 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.