Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Огляд руху в 2D просторі

Вступ

Кожен початківець стикався з питанням: "Як я буду переміщувати свого персонажа?" Залежно від стилю гри, яку ви робите, ви можете мати особливі вимоги, але загалом рух у більшості 2D-ігор базується на невеликій кількості конструкцій.

Ми будемо використовувати CharacterBody2D для цих прикладів, але принципи також стосуватимуться інших типів вузлів (Area2D, RigidBody2D).

Налаштування

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.svg) for the Sprite2D's texture or use any other 2D image you have.

Відкрийте Проект -> Налаштування проекту та виберіть вкладку "Мапа вводу". Додайте наступні дії вводу (докладніше див. InputEvent):

../../_images/movement_inputs.webp

8-бічний рух

У цьому випадку ви хочете, щоб користувач користувався чотирма клавішами (стрілками вгору/вліво/вниз/вправо, або W/A/S/D) для переміщення у вибраному напрямку. Назва «8-бічний рух» походить від того, що гравець може рухатися по діагоналі, натискаючи дві клавіші одночасно.

Додайте скрипт до тіла символу та додайте такий код:

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()

У функції get_input() ми використовуємо Input get_vector(), щоб перевірити наявність чотирьох ключових подій і підсумувати вектор напрямку.

Потім ми можемо встановити нашу швидкість, помноживши цей вектор напрямку, який має довжину 1, на бажану швидкість.

Порада

Якщо ви ніколи раніше не використовували векторну математику або вам потрібно освіжити знання, ви можете переглянути пояснення використання вектора у Godot на Векторна математика.

Примітка

Якщо вищенаведений код нічого не робить під час натискання клавіш, перевірте, чи правильно ви налаштували дії введення, як описано в частині Налаштування цього урока.

Обертання + рух

Цей тип руху іноді називають "Астероїдним стилем", оскільки він нагадує роботу цієї класичної аркадної гри. Натискання вліво/вправо обертає персонажа, тоді як вгору/вниз рухає його вперед, або назад, у будь-якому напрямку, до якого він спрямований.

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()

Тут ми додали дві змінні для відстеження нашого напрямку та швидкості обертання. Поворот застосовується безпосередньо до властивості обертання тіла.

Щоб встановити швидкість, ми використовуємо transform.x тіла, який є вектором, що вказує в напрямку тіла «вперед», і множимо його на швидкість.

Обертання + рух (мишкою)

Цей стиль руху є різновидом попереднього. Цього разу напрямок задається положенням мишки, замість клавіатури. Персонаж завжди буде "дивитись" на курсор мишки. Однак вхідні дані вперед/назад залишаються незмінними.

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()

Тут ми використовуємо метод Node2D look_at(), щоб вказати гравцеві на позицію миші. Без цієї функції ви могли б отримати той самий ефект, встановивши кут таким чином:

rotation = get_global_mouse_position().angle_to_point(position)

Клацай і рухайся

Цей останній приклад використовує лише мишку для управління персонажем. Натискання на екрані призведе до переміщення гравця до цільового місця.

extends CharacterBody2D

@export var speed = 400

var target = position

func _input(event):
    # Use is_action_pressed to only accept single taps as input instead of mouse drags.
    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()

Зверніть увагу на перевірку distance_to(), яку ми робимо перед переміщенням. Без цього тесту тіло буде "тремтіти", досягнувши цільового положення, коли воно просунеться трохи задалеко, спробує повернутися назад, знову проскочивши цільове положення, і так без кінця.

Знявши коментар з рядка look_at(), ви також повернете тіло в напрямку руху, якщо вам так більше подобається.

Порада

Цей метод також можна використовувати як основу для «наступного» символу. target позицією може бути будь-який об’єкт, до якого ви хочете переміститися.

Підсумок

Ці зразки коду можуть стати корисними в якості основи для ваших власних проєктів. Сміливо використовуйте їх і експериментуйте з ними, щоб побачити, що ви можете зробити.

Ви можете завантажити цей приклад проекту тут: 2d_movement_starter.zip