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

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

У кожному наведеному нижче прикладі використовується однакова настройка сцени. Почніть із CharacterBody2D з двома дочірніми елементами: Sprite2D і CollisionShape2D. Ви можете використовувати піктограму Годо ("icon.png") для текстури Sprite2D або використовувати будь-яке інше двовимірне зображення, яке у вас є.

Відкрийте Проєкт -> Параметри проєкта та виберіть вкладку Карта введення. Додайте такі дії (щоб дізнатися більше дивіться Події Вводу):

../../_images/movement_inputs.webp

8-бічний рух

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

../../_images/movement_8way.gif

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

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 на Векторна математика.

Примітка

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

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

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

../../_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()

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

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

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

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

../../_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()

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

rotation = get_global_mouse_position().angle_to_point(position)

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

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

../../_images/movement_click.gif
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