Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Movimiento en 2D

Introducción

Todos los principiantes han pasado por esto: "¿Cómo muevo mi personaje?" Dependiendo del estilo de juego que estés haciendo, puedes tener requerimientos especiales pero, en general, el movimiento en la mayoría de los juegos 2D está basado en una pequeña cantidad de estilos.

We'll use CharacterBody2D for these examples, but the principles will apply to other node types (Area2D, RigidBody2D) as well.

Organización

Each example below uses the same scene setup. Start with a CharacterBody2D with two children: Sprite2D and CollisionShape2D. You can use the Godot icon ("icon.png") for the Sprite2D's texture or use any other 2D image you have.

Abre Projecto -> Ajustes del Proyecto y selecciona la pestaña Mapa de entradas. Agrega las siguientes acciones (ver InputEvent para más detalles):

../../_images/movement_inputs.webp

Movimiento en 8 sentidos

En este escenario, quieres que el usuario pueda presionar las cuatro teclas direccionales (arriba/izquierda/abajo/derecha o W/A/S/D) y se mueva en la dirección indicada. El nombre "movimiento en 8 sentidos" (o 8-way movement en inglés) viene del hecho de que el jugador se puede mover diagonalmente al presionar dos teclas al mismo tiempo.

../../_images/movement_8way.gif

Add a script to the character body and add the following code:

extends CharacterBody2D

@export var speed = 400

func get_input():
    var input_direction = Input.get_vector("left", "right", "up", "down")
    velocity = input_direction * speed

func _physics_process(delta):
    get_input()
    move_and_slide()

In the get_input() function, we use Input get_vector() to check for the four key events and sum return a direction vector.

We can then set our velocity by multiplying this direction vector, which has a length of 1, by our desired speed.

Truco

Si nunca antes has usado cálculo vectorial (operaciones matemáticas entre vectores) o necesitas un recordatorio, puedes ver la explicación del uso en Godot en Matemáticas vectoriales.

Nota

Si el código anterior no hace nada cuando presionas las teclas, vuelve a revisar que has configurado las acciones de entrada correctamente como se describió en la parte Organización de este tutorial.

Rotación + movimiento

Este tipo de movimientos es a veces llamado "estilo Asteroids" porque recuerda al funcionamiento del juego clásico de ese nombre. Presionando izquierda/derecha rota el personaje, mientras que arriba/abajo lo mueve hacia adelante y hacia atrás acorde a la dirección a la que apunta.

../../_images/movement_rotate1.gif
extends CharacterBody2D

@export var speed = 400
@export var rotation_speed = 1.5

var rotation_direction = 0

func get_input():
    rotation_direction = Input.get_axis("left", "right")
    velocity = transform.x * Input.get_axis("down", "up") * speed

func _physics_process(delta):
    get_input()
    rotation += rotation_direction * rotation_speed * delta
    move_and_slide()

Here we've added two variables to track our rotation direction and speed. The rotation is applied directly to the body's rotation property.

To set the velocity, we use the body's transform.x which is a vector pointing in the body's "forward" direction, and multiply that by the speed.

Rotación + movimiento (ratón)

Este estilo de movimiento es una variante del anterior. Ahora, la dirección es indicada por la posición del ratón en lugar del teclado. El personaje siempre "mirará hacia" el puntero del ratón. El movimiento hacia adelante y hacia atras se mantiene igual.

../../_images/movement_rotate2.gif
extends CharacterBody2D

@export var speed = 400

func get_input():
    look_at(get_global_mouse_position())
    velocity = transform.x * Input.get_axis("down", "up") * speed

func _physics_process(delta):
    get_input()
    move_and_slide()

Here we're using the Node2D look_at() method to point the player towards the mouse's position. Without this function, you could get the same effect by setting the angle like this:

rotation = get_global_mouse_position().angle_to_point(position)

Clic y mover

Este último ejemplo utiliza sólo el ratón para controlar el personaje. Haciendo clic en la pantalla ocasiona que el jugador se mueva a la posición indicada.

../../_images/movement_click.gif
extends CharacterBody2D

@export var speed = 400

var target = position

func _input(event):
    if event.is_action_pressed("click"):
        target = get_global_mouse_position()

func _physics_process(delta):
    velocity = position.direction_to(target) * speed
    # look_at(target)
    if position.distance_to(target) > 10:
        move_and_slide()

Nota la comprobación distance_to() que se hace antes del movimiento. Sin esto, el cuerpo podría "temblar" al llegar al destino, ya que el movimiento puede pasarse un poco e intentará moverse hacia atrás, pasándose de largo nuevamente y repitiendo el proceso.

Quitando los comentarios en la línea que dice look_at() hará también que el cuerpo apunte a la dirección del movimiento.

Truco

Esta técnica también puede utilizarse como base para un personaje "persecutorio". La posición del objetivo puede ser la de cualquier objeto al que quieras moverte.

Sumario

Estos ejemplos pueden ser útiles como punto de partida para tus propios proyectos. Siéntete libre de usarlos y experimentar con ellos para ver lo que puedes hacer.

You can download this sample project here: 2d_movement_starter.zip