Движение в 8 направлениях в Godot

Проблема

Вам нужен двухмерный персонаж с движением в 8 направлениях, включая анимацию в Godot.

Решение

Для нашего примера мы будем использовать Изометрического Мини-Крестоносца, который содержит восемь направлений анимации для покоя, бега, атаки и нескольких других состояний.

Анимации организованы в папках, с отдельным изображением для каждого кадра. Мы будем использовать AnimatedSprite2D и мы назовем каждую анимацию в соответствии с ее направлением. Например, idle0 будет указывать вправо и двигаться по часовой стрелке до idle7.

Когда наш персонаж двигается, он выберет анимацию в зависимости от направления движения:

Мы будем использовать мышь для движения — персонаж всегда будет повернут к мыши и бежать в том направлении, когда мы нажимаем кнопку мыши.

Чтобы выбрать, какую анимацию проигрывать, нам нужно получить направление мыши и отобразить его в тот же диапазон от 0 до 7. get_local_mouse_position() дает нам положение мыши относительно персонажа. Затем мы можем использовать snappedf(), чтобы прижать угол вектора мыши к ближайшему кратному 45° (PI/4 радиан), что дает следующий результат:

Разделите каждое значение на 45° (PI/4 радиан):

Наконец, нам нужно отобразить полученный диапазон в диапазон от 0 до 7 с использованием функции wrapi(), чтобы у нас было правильные значения. Добавив это значение в конец имени анимации (“idle”, “run” и так далее), мы получим правильную анимацию:

func _physics_process(delta):
    current_animation = "idle"

    var mouse = get_local_mouse_position()
    angle = snappedf(mouse.angle(), PI/4) / (PI/4)
    angle = wrapi(int(angle), 0, 8)

    if Input.is_action_pressed("left_mouse") and mouse.length() > 10:
        current_animation = "run"
        velocity = mouse.normalized() * speed
        move_and_slide()
    $AnimatedSprite2D.animation = current_animation + str(a)

Если протестировать скрипт мы увидим следующее

Ввод с клавиатуры

Если вы используете управление с клавиатуры вместо мыши, вы можете получить угол движения на основе того, какие клавиши удерживаются. Остальная часть процесса работает так же.

func _process(delta):
    current_animation = "idle"
    var input_dir = Input.get_vector("left", "right", "up", "down")
    if input_dir.length() != 0:
        angle = input_dir.angle() / (PI/4)
        angle = wrapi(int(a), 0, 8)
        current_animation = "run"
    velocity = input_dir * speed
    move_and_slide()
    $AnimatedSprite2D.play(current_animation + str(angle))

Скачайте этот проект

Скачайте код проекта здесь: https://github.com/godotrecipes/8_direction_animation

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

3 + 9 =

Прокрутить вверх