Pular para o conteúdo
Jogos Digitais
Nesta página
  1. Objetivos de aprendizagem
  2. Pré-requisitos
  3. Materiais
  4. Conceitos
  5. Exemplos
  6. Tutorial passo a passo
  7. Imagens
  8. Indicação da interface
  9. O código completo
  10. Explicação do código
  11. Resultado esperado
  12. Problemas comuns
  13. Exercício guiado
  14. Desafio individual
  15. Desafio avançado (opcional)
  16. Critérios de avaliação
  17. Checklist de conclusão
  18. Extensão

Módulo 8 · Aula 8.3 · Mapa de Entrada e movimento

Carga horáriaDificuldadeFerramentaCompetências
10 h/a⭐⭐⭐Godot 4.7C2

Objetivos de aprendizagem

  1. Mover um desenho com as setas usando delta (velocidade igual em qualquer computador).
  2. Criar ações no Mapa de Entrada (esquerda, direita, cima, baixo) com mais de uma tecla cada.
  3. Mover um CharacterBody2D com velocity, move_and_slide() e Input.get_vector.
  4. Trocar a animação e virar o desenho conforme a direção.
  5. Seguir o mouse ou o dedo enquanto ele está apertado.

Pré-requisitos

Aula 8.2.

Materiais

Godot 4.7; laboratório (cenas/anda_com_setas.tscn); Sementes em Godot (cenas/jogador.tscn).

Conceitos

Velocidade × delta. position.x += 200 * delta anda 200 pixels por segundo. Sem delta, andaria 200 pixels por quadro: num computador de 60 quadros por segundo, voaria a 12.000 pixels por segundo.

Ação em vez de tecla. No código não se escreve "seta para a direita": escreve-se a ação "direita". No Mapa de Entrada cada ação recebe uma ou mais teclas (seta e letra D, por exemplo). Para trocar as teclas, não se mexe no código. É a mesma ideia da tecla trocável da Feira do Troco (Aula 7.6).

Ações prontas. O Godot já vem com ações ui_left, ui_right, ui_up, ui_down e ui_accept (aparecem ao ligar Mostrar Ações Integradas). O primeiro exemplo usa essas; o jogo usa as ações próprias, com nome em português.

Input.get_vector. Junta as quatro ações numa direção só, de tamanho no máximo 1. Assim, andar na diagonal não fica mais rápido do que andar reto. O teste do Sementes confere isso: reto ou na diagonal, uns 100 pixels em meio segundo.

CharacterBody2D. Corpo que o jogador controla. Põe-se a velocidade em velocity e chama-se move_and_slide(): ele anda e desliza nas paredes. Para jogo visto de cima, a propriedade Motion Mode fica em Floating (no Sementes já está).

_physics_process. Movimento com colisão vai aqui, e não no _process, porque a física roda sempre no mesmo ritmo.

Exemplos

GDevelop (Módulo 3)Godot
comportamento Movimento em TopDown, velocidade 200velocity = direcao * 200 + move_and_slide()
teclas do comportamentoações do Mapa de Entrada
inverter o objeto horizontalmentedesenho.flip_h = true
animação por nomedesenho.play("andando")

Tutorial passo a passo

Parte A. Primeiro movimento (90 min)

  1. Abra anda_com_setas.tscn no laboratório e execute a cena. Ande com as setas.
  2. Leia anda_com_setas.gd. Tire o * delta de uma linha e execute: o que aconteceu? Volte como estava.

Parte B. Mapa de Entrada (90 min)

  1. Menu Projeto → Configurações do Projeto..., aba Mapa de Entrada.
  2. Em Adicionar Nova Ação, escreva direita e clique em Adicionar. Faça o mesmo para esquerda, cima e baixo.
  3. No + de cada ação, aperte a tecla (seta) e confirme. Adicione também W, A, S, D.
  4. Compare com a captura do Sementes. As teclas aparecem como Right (Físico): "físico" quer dizer a posição da tecla no teclado, e assim funciona em teclados de outros idiomas.

Parte C. Corpo que anda (180 min)

  1. Cena nova com raiz CharacterBody2D chamada Jogador. Filhos: AnimatedSprite2D chamado Desenho e CollisionShape2D chamado Colisao.
  2. No Desenho, em Sprite Frames, crie um SpriteFrames com as animações parado (1 quadro) e andando (2 quadros), usando os desenhos do sertanejo.
  3. No Colisao, em Shape, escolha um retângulo do tamanho do corpo.
  4. No Jogador, Motion Mode = Floating. Anexe um script e escreva o código abaixo (sem a parte do toque, por enquanto).
  5. Coloque a cena do jogador dentro de uma cena de teste (arrastando o .tscn para a área 2D) e execute.

Parte D. Mouse e dedo (90 min)

  1. Acrescente alvo_toque e a função _unhandled_input do código completo. Segure o mouse num ponto: o sertanejo vai até lá.
  2. Teste: o que acontece quando o sertanejo chega no ponto? Por que existe o > 8?

Imagens

  • ../../../recursos/imagens/godot/captura-godot-mapa-de-entrada.png: Mapa de Entrada com as ações do Sementes.
  • ../../../recursos/imagens/godot/captura-godot-script-jogador.png: o script do jogador no editor.
  • ../../../recursos/imagens/godot/captura-godot-cena-jogador-inspetor.png: a cena do jogador.

Indicação da interface

ItemNome na tela
ações e teclasConfigurações do Projeto... → aba Mapa de Entrada: Adicionar Nova Ação, Adicionar, Mostrar Ações Integradas, coluna Zona Morta
janela de escolher a teclaConfiguração de Evento (opções "Keycode Físico (Posição no teclado QWERTY dos EUA)" e "Keycode (Equivalente Latino)")
quadros da animaçãopropriedade Sprite Frames do AnimatedSprite2D; o painel de quadros abre embaixo
forma de colisãopropriedade Shape do CollisionShape2D

O passo a passo do painel de quadros (botões para adicionar quadros de arquivo) não foi fotografado nesta versão; o professor deve fazer uma vez antes da aula.

O código completo

projetos/sementes-godot/scripts/jogador.gd:

extends CharacterBody2D

const VELOCIDADE := 200.0

## Ponto que o jogador está apertando com o mouse ou o dedo. null quando ninguém aperta.
var alvo_toque = null

@onready var desenho: AnimatedSprite2D = $Desenho


func _unhandled_input(event: InputEvent) -> void:
	# O toque na tela chega como clique de mouse (opção padrão do Godot).
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		alvo_toque = event.position if event.pressed else null
	elif event is InputEventMouseMotion and alvo_toque != null:
		alvo_toque = event.position


func _physics_process(_delta: float) -> void:
	var direcao := Input.get_vector("esquerda", "direita", "cima", "baixo")
	if direcao == Vector2.ZERO and alvo_toque != null and position.distance_to(alvo_toque) > 8:
		direcao = position.direction_to(alvo_toque)

	velocity = direcao * VELOCIDADE
	move_and_slide()
	# Não deixa o sertanejo sair da tela de 800 x 600.
	position = position.clamp(Vector2(16, 24), Vector2(784, 576))

	if direcao.x != 0:
		desenho.flip_h = direcao.x < 0
	if direcao == Vector2.ZERO:
		desenho.play("parado")
	else:
		desenho.play("andando")

Explicação do código

  • @onready var desenho = $Desenho: $Desenho é o nó filho chamado Desenho. @onready espera a cena ficar pronta para buscar.
  • move_and_slide() já usa o delta por dentro; por isso a função recebe _delta (o traço diz "não uso").
  • Vector2 é um par (x, y). clamp prende a posição dentro de um retângulo.
  • O toque: segurando, alvo_toque guarda o ponto; soltando, vira null e o sertanejo para. As setas têm prioridade.
  • Só vira o desenho quando há movimento para o lado; parado, fica virado para onde estava.

Resultado esperado

Personagem com ações próprias, velocidade igual na diagonal, animação e virada certas, preso na tela, seguindo o mouse ou o dedo.

Problemas comuns

SintomaCausaSolução
o personagem não andanome da ação no código diferente do Mapa de Entradaconferir letra por letra ("direita")
anda devagar demais ou rápido demaisvelocidade sem delta (com position +=)multiplicar por delta, ou usar velocity + move_and_slide()
erro "Node not found: Desenho"o filho tem outro nomerenomear o nó ou mudar o $
o desenho não mudaanimação com nome diferente"andando" e "parado" iguais no SpriteFrames e no código
na diagonal fica mais rápidosomou as direções à mãoInput.get_vector

Exercício guiado

Com velocidade 200 e get_vector, quanto o jogador anda em 0,5 s para a direita? E na diagonal? (Resposta: uns 100 pixels nos dois casos. O teste mediu 103,3 nos dois, por causa do arredondamento dos quadros.)

Desafio individual

Acrescente uma ação correr (tecla Shift) que dobra a velocidade enquanto está apertada.

Desafio avançado (opcional)

Faça o personagem acelerar aos poucos até a velocidade máxima, usando velocity = velocity.move_toward(direcao * VELOCIDADE, 800 * delta).

Critérios de avaliação

  • Ações próprias no Mapa de Entrada, com duas teclas cada.
  • Movimento com get_vector e move_and_slide.
  • Animação e virada coerentes.

Checklist de conclusão

Extensão

Física: velocidade é distância dividida por tempo. Cronometre o personagem atravessando a tela de 800 pixels. Bate com 200 pixels por segundo?