Up to date

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

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

Вступ

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

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

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

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.

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

../../_images/movement_inputs.webp

8-бічний рух

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

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

Порада

Якщо ви ніколи раніше не використовували векторну математику або вам потрібно освіжити знання, ви можете переглянути пояснення використання вектора у 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()

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.

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

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

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

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

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

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

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

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

Порада

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

Підсумок

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

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