In deel 2 van deze reeks voegen we onze speler toe.
De node
die we aanmaken moet van het type CharacterBody2D
zijn. Dit is een soort node
die wel meedoet met fysica simulatie (vallen en botsen) maar waar we volledige controle over hebben.
Als naam van de scene
gebruiken we gewoon 'Player' (dit is vrij te kiezen).
We krijgen nu een extra tabblad voor deze nieuwe 'Player' scene. Via de knoppen hieronder kan je wisselen tussen scenes die je open hebt.
We voegen 2 nodes toe aan onze player:
- een
AnimatedSprite2D
voor de graphics, - en een
CollisionShape2D
om botsingen te kunnen detecteren.
Om de graphics van de AnimatedSprite2D
te kiezen, moeten we eerst zorgen dat ie links geselecteerd is. Dan kunnen we rechts bij Sprite Frames
via het uitklap menu een nieuwe SpriteFrames
toevoegen.
De nieuwe SpriteFrames
is nog leeg. Klik er op. Midden-beneden opent nu de editor voor de SpriteFrames
in een paneel.
De Godot ontwikkelomgeving zit vol met panelen en tabbladen... Hieronder zie je de knop die hoort bij het SpriteFrames
paneel, waaraan je ziet dat dit paneel open staat.
We gaan onze animaties toevoegen: in het SpriteFrames
paneel heb je onder 'Animations' wat knoppen en een lijstje met animaties die in de SpriteFrames
zitten.
Met de Add Animation
knop voegen we de volgende animaties toe: attack
, die
, hurt
, idle
en walk
(default
mag weg).
De naam veranderen van een animatie kan door 2 keer (langzaam) te klikken met de linkermuisknop.
De volgende knoppen gaan we gebruiken om alle animaties correct in te stellen. Van links naar rechts:
- de
animation looping
knop - FPS = snelheid van de animatie (frames per seconde)
-
play
knop om een voorbeeld te zien -
add frame from file
knop om losse afbeeldingen toe te voegen.
Klik op de add frame from file
. In de dialoog die volgt, zoek de map met de juiste afbeeldingen en gebruik shift-muisklik om ze allemaal te selecteren.
(Klik op de eerste afbeelding, houdt dan SHIFT
ingedrukt en klik op de laatste afbeelding)
Voeg de juiste beelden toe aan alle animaties, en stel de juiste opties in:
- alle animaties spelen aan 30 FPS.
- 'idle' en 'walk' hebben
animation looping
AAN staan (knop icoon is blauw) - 'attack', 'hurt', 'die' hebben het UIT staan (knop icoon heeft zelfde kleur als andere knoppen). Deze animaties spelen maar 1 keer, tot we via code een nieuwe animatie starten.
Nu gaan we voor de eerste keer code gebruiken, om onze 'Player' tot leven te brengen!
In het linkerpaneel zorgen we dat de 'Player' geselecteerd is, en klikken we op de knop Attach script
.
We krijgen een dialoog, waar we een template (voorbeeld) kunnen kiezen, en een naam voor het script. Omdat we onze node 'Player' hebben genoemd, krijgen we automatisch de naam 'Player.gd' als standaard, wat prima is. Klik Create
.
Je krijgt van Godot nu wat voorbeeldcode voor een platformer, met springen. We hebben springen niet nodig. Je mag alle code wegdoen, behalve de eerste 2 regels:
extends CharacterBody2D
const SPEED = 300.0
Omdat we dit script verbinden met onze player node
, en dat een CharacterBody2D
is, start het script met de regel extends CharacterBody2D
.
De tweede regels is de definitie van een constante: we gaan het woord 'SPEED' later in ons script gebruiken, en daar wordt overal de waarde '300' ingevuld. Dit is de loop-snelheid van onze speler. We maken er '400' van.
const SPEED = 400.0
We willen dat de speler onze 'held' kan laten bewegen. Hij moet kunnen links-rechts en boven-onder bewegen met de pijltoetsen. Deze logica gaan we in de _physics_process
functie steken: dit is een functie die de Godot engine oproept voor elke game tick
. Standaard is dit 60 maal per seconde. Deze snelheid is vast en hangt niet af van de kracht van je grafische kaart. We willen dat onze speler overal even snel loopt, of je nu een krachtige grafische kaart hebt of niet.
func _physics_process(_delta):
velocity.x = Input.get_axis("ui_left", "ui_right") * SPEED
velocity.y = Input.get_axis("ui_up", "ui_down") * SPEED
move_and_slide()
We kunnen dit al testen.
Ga terug naar de game scene en sleep de player.tscn
naar de 'Arena' node, als kind van de node.
Klikken we nu op Run Project
rechtsboven, dan opent onze game en kunnen we met de pijltoetsen onze speler bewegen!
Er zijn nog een paar basis zaken die ontbreken:
- het personage zelf beweegt niet
- het personage kijkt altijd naar dezelfde kant
- het personage kan 'buiten beeld' lopen.
De eerste 2 punten kunnen we snel oplossen met wat extra code.
Ga terug naar het script via de Script
knop boven-midden.
We hebben daarstraks de animaties reeds gemaakt, nu moeten we enkel nog de juiste animatie starten vanuit onze code. Wanneer de speler loopt, spelen we de 'walk' animatie. Als hij stilstaat, spelen we 'idle'.
De animaties worden getoond door de AnimatedSprite2D
die we aan onze player scene
hebben gehangen. In onze code gaan wie deze node
zoeken en opslaan in een variabele die we 'sprite' noemen. Dit stukje code komt vlak onder onze constante SPEED te staan, en wordt eenmaal uitgevoegd als het spel start:
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
In onze _physics_process
functie kunnen we nu de variabele sprite
gebruiken om een animatie te starten.
We vervangen het stukje move_and_slide()
door deze blok code:
if velocity:
move_and_slide()
sprite.play("walk")
else:
sprite.play("idle")
Onze code ziet er dan zo uit:
extends CharacterBody2D
const SPEED = 400.0
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
func _physics_process(_delta):
velocity.x = Input.get_axis("ui_left", "ui_right") * SPEED
velocity.y = Input.get_axis("ui_up", "ui_down") * SPEED
if velocity:
move_and_slide()
sprite.play("walk")
else:
sprite.play("idle")
Test of het werkt via die Run Project
knop of de F5
toets.
Het is vaak een goed idee je code te testen na elke kleine wijziging.
De kijkrichting van de speler wijzigen doen we via een trukje. Je kan de schaal (grootte) van een afbeelding wijzigen, en zelfs de hoogte (y) en breedte (x) apart. Schaal 1 is de originele grootte. Schaal 2 is dan dubbel zo groot. Maar schaal -1 is originele grootte, maar gespiegeld. Als we de sprite schaal voor x veranderen van 1 naar -1 wordt de sprite gespiegeld in de breedte.
Aan onze _physics_process
functie voegen we het volgende stukje code toe (onder de regels waar velocity.x
en velocity.y
worden ingesteld via Input.get_axis
):
if velocity.x < 0:
sprite.scale.x = -1
elif velocity.x > 0:
sprite.scale.x = 1
De hele code ziet er nu zo uit:
extends CharacterBody2D
const SPEED = 400.0
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
func _physics_process(_delta):
velocity.x = Input.get_axis("ui_left", "ui_right") * SPEED
velocity.y = Input.get_axis("ui_up", "ui_down") * SPEED
if velocity.x < 0:
sprite.scale.x = -1
elif velocity.x > 0:
sprite.scale.x = 1
if velocity:
move_and_slide()
sprite.play("walk")
else:
sprite.play("idle")
Als je het project test, merk je dat het personage nu ook kijkt in de juiste richting als hij loopt.
Er voor zorgen dat onze speler niet 'buiten beeld' kan lopen doen we in het volgende deel.
Top comments (2)
Beste tutorial die ik tot nu toe heb gezien na een paar dagen zoeken, er lijken maar weinig tutorials te zijn voor 2D beat em up spellen. Heel erg bedankt!
hey het is ilianos dus waneer ga je de dingen dat ik moet voor godot stuuren