2D-liikkumisen yleiskatsaus¶
Johdanto¶
Jokainen aloitteleva pelintekijä on kysynyt samaa: "Kuinka liikutan pelihahmoani?" Riippuen pelisi tyylistä, sinulla voi olla erityisvaatimuksia, mutta yleisesti ottaen liikkuminen useimmissa 2D-peleissä pohjautuu muutamaan perusmalliin.
Käytämme esimerkeissä KinematicBody2D solmua, mutta periaatteet pätevät muihinkin solmutyyppeihin (Area2D, RigidBody2D).
Järjestely¶
Jokainen alla oleva esimerkki käyttää samaa skenejärjestelyä. Aloita KinematicBody2D
solmulla, jolla on kaksi alisolmua: Sprite
ja CollisionShape2D
. Spriten tekstuurina voit käyttää Godot-ikonia ("icon.png") tai mitä tahansa 2D-kuvaa.
Avaa valikosta Projekti -> Projektin asetukset...
ja valitse "Syötekartta"-välilehti. Lisää siihen seuraavat syötetoiminnot (ks. InputEvent tarkempia tietoja varten):

8-suuntainen liikkuminen¶
Tässä esimerkkitilanteessa haluat käyttäjän painavan neljää suuntanäppäintä (ylös/vasemmalle/alas/oikealle tai W/A/S/D) ja liikkuvan valittuun suuntaan. Nimi "8-suuntainen liikkuminen" tulee siitä, että pelaaja voi liikkua viistosti painamalla kahta näppäintä yhtä aikaa.

Lisää kinemaattiselle kappaleelle skripti ja lisää siihen seuraava koodi:
extends KinematicBody2D
export (int) var speed = 200
var velocity = Vector2()
func get_input():
velocity = Vector2()
if Input.is_action_pressed("right"):
velocity.x += 1
if Input.is_action_pressed("left"):
velocity.x -= 1
if Input.is_action_pressed("down"):
velocity.y += 1
if Input.is_action_pressed("up"):
velocity.y -= 1
velocity = velocity.normalized() * speed
func _physics_process(delta):
get_input()
velocity = move_and_slide(velocity)
using Godot;
using System;
public class Movement : KinematicBody2D
{
[Export] public int speed = 200;
public Vector2 velocity = new Vector2();
public void GetInput()
{
velocity = new Vector2();
if (Input.IsActionPressed("right"))
velocity.x += 1;
if (Input.IsActionPressed("left"))
velocity.x -= 1;
if (Input.IsActionPressed("down"))
velocity.y += 1;
if (Input.IsActionPressed("up"))
velocity.y -= 1;
velocity = velocity.Normalized() * speed;
}
public override void _PhysicsProcess(float delta)
{
GetInput();
velocity = MoveAndSlide(velocity);
}
}
get_input()
funktiossa tarkistamme neljä näppäintapahtumaa ja laskemme ne yhteen saadaksemme nopeusvektorin. Tästä on se etu, että kaksi vastakkaista näppäintä kumoavat toisensa, mutta se johtaa myös siihen, että viistottainen liike on nopeampaa, koska kaksi suuntaa on laskettu yhteen.
Voimme estää sen normalisoimalla nopeuden, mikä tarkoittaa, että asetamme sen pituudeksi 1
ja kerromme sen halutulla nopeudella.
Vihje
Mikäli et ole käyttänyt vektorimatematiikkaa aiemmin tai tarvitset kertausta, voit lukea selostuksen vektoreiden käytöstä Godotissa sivulta Vector math.
Muista
Jos yllä oleva koodi ei tee mitään painaessasi näppäimiä, tarkista että olet asettanut syötetoiminnot oikein tämän oppaan Järjestely osiossa kuvatulla tavalla.
Kiertyminen + liikkuminen¶
Tämän tyyppistä liikkumista kutsutaan joskus "Asteroids-tyyliksi", koska se muistuttaa kyseisen klassisen arcade-pelin toimintatapaa. Painamalla vasemalle/oikealle kiertää pelihahmoa, kun taas ylös/alas liikuttaa sitä eteenpäin tai taaksepäin siinä suunnassa johon se osoittaa.

extends KinematicBody2D
export (int) var speed = 200
export (float) var rotation_speed = 1.5
var velocity = Vector2()
var rotation_dir = 0
func get_input():
rotation_dir = 0
velocity = Vector2()
if Input.is_action_pressed("right"):
rotation_dir += 1
if Input.is_action_pressed("left"):
rotation_dir -= 1
if Input.is_action_pressed("down"):
velocity = Vector2(-speed, 0).rotated(rotation)
if Input.is_action_pressed("up"):
velocity = Vector2(speed, 0).rotated(rotation)
func _physics_process(delta):
get_input()
rotation += rotation_dir * rotation_speed * delta
velocity = move_and_slide(velocity)
using Godot;
using System;
public class Movement : KinematicBody2D
{
[Export] public int speed = 200;
[Export] public float rotationSpeed = 1.5f;
public Vector2 velocity = new Vector2();
public int rotationDir = 0;
public void GetInput()
{
rotationDir = 0;
velocity = new Vector2();
if (Input.IsActionPressed("right"))
rotationDir += 1;
if (Input.IsActionPressed("left"))
rotationDir -= 1;
if (Input.IsActionPressed("down"))
velocity = new Vector2(-speed, 0).Rotated(Rotation);
if (Input.IsActionPressed("up"))
velocity = new Vector2(speed, 0).Rotated(Rotation);
velocity = velocity.Normalized() * speed;
}
public override void _PhysicsProcess(float delta)
{
GetInput();
Rotation += rotationDir * rotationSpeed * delta;
velocity = MoveAndSlide(velocity);
}
}
Tässä olemme lisänneet kaksi uutta muuttujaa kiertymissuunnan ja -nopeuden seuraamiseksi. Jälleen kerran, molempien näppäimien yhdenaikainen painaminen kumoaa toisensa, eikä kiertymistä tapahdu. Kiertyminen lisätään suoraan kappaleen rotation
ominaisuuteen.
Nopeuden asettamiseksi käytämme Vector2.rotated()
metodia niin, että se osoittaa samaan suuntaan kuin kappale. rotated()
on hyödyllinen vektorifunktio, jota voit käyttää useissa tilanteissa, joissa muutoin tarvitsisit trigonometrisia funktioita.
Kiertyminen + liikkuminen (hiirellä)¶
Tämä liikkumistyyli on muunnelma edellisestä. Tällä kertaa suuntaa asetetaan hiiren sijainnilla näppäimistön sijaan. Pelihahmo "katsoo" aina hiiren osoittimen suuntaan. Eteenpäin/taaksepäin syötteet pysyvät kuitenkin samana.

extends KinematicBody2D
export (int) var speed = 200
var velocity = Vector2()
func get_input():
look_at(get_global_mouse_position())
velocity = Vector2()
if Input.is_action_pressed("down"):
velocity = Vector2(-speed, 0).rotated(rotation)
if Input.is_action_pressed("up"):
velocity = Vector2(speed, 0).rotated(rotation)
func _physics_process(delta):
get_input()
velocity = move_and_slide(velocity)
using Godot;
using System;
public class Movement : KinematicBody2D
{
[Export] public int speed = 200;
public Vector2 velocity = new Vector2();
public void GetInput()
{
LookAt(GetGlobalMousePosition());
velocity = new Vector2();
if (Input.IsActionPressed("down"))
velocity = new Vector2(-speed, 0).Rotated(Rotation);
if (Input.IsActionPressed("up"))
velocity = new Vector2(speed, 0).Rotated(Rotation);
velocity = velocity.Normalized() * speed;
}
public override void _PhysicsProcess(float delta)
{
GetInput();
velocity = MoveAndSlide(velocity);
}
}
Tässä käytämme Node2D solmun look_at()
metodia osoittamaan pelaaja annettun sijainnin suuntaan. Ilman tätä funktiota, saisit saman aikaan asettamalla kulman tällä tavalla:
rotation = get_global_mouse_position().angle_to_point(position)
var rotation = GetGlobalMousePosition().AngleToPoint(Position);
Napsauta-ja-liiku¶
Tämä viimeinen esimerkki käyttää ainoastaan hiirtä hahmon ohjaamiseen. Ruudun napsauttaminen saa pelaajan siirtymään kohdepaikkaan.

extends KinematicBody2D
export (int) var speed = 200
onready var target = position
var velocity = Vector2()
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) > 5:
velocity = move_and_slide(velocity)
using Godot;
using System;
public class Movement : KinematicBody2D
{
[Export] public int speed = 200;
public Vector2 target;
public Vector2 velocity = new Vector2();
public override void _Ready()
{
target = Position;
}
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("click"))
{
target = GetGlobalMousePosition();
}
}
public override void _PhysicsProcess(float delta)
{
velocity = Position.DirectionTo(target) * speed;
// LookAt(target);
if (Position.DistanceTo(target) > 5)
{
velocity = MoveAndSlide(velocity);
}
}
}
Huomaa distance_to()
tarkistus, jonka teemme ennen liikkumista. Ilman tätä testiä, kappale "tärisisi" saavutettuaan kohdesijainnin sen liikkuessa hivenen sijainnin ohi ja yrittäessä liikkua takaisin, vain liikkuakseen liian pitkälle ja toistaakseen saman.
Kommentoinnin poistaminen look_at()
riviltä saa kappaleen kääntymään myös osoittamaan liikkumissuuntaansa, jos niin haluat.
Vihje
Tätä tekniikaa voi myös käyttää pohjana "seuraavalle" hahmolle. target
sijainti voi olla minkä tahansa objektin, jota haluat liikuttaa.
Yhteenveto¶
Nämä koodiesimerkit saattavat olla hyödyllisiä aloituspisteitä omiin projekteihisi. Voit vapaasti käyttää niitä ja kokeilla mitä voisit saada aikaiseksi.
Voit ladata tämän esimerkkiprojektin täältä: 2D_movement_demo.zip