DEV Community

Cover image for Een beat-em-up game maken met Godot - de speler
Bgie
Bgie

Posted on • Updated on

Een beat-em-up game maken met Godot - de speler

Terug naar deel 1

In deel 2 van deze reeks voegen we onze speler toe.

Maak een nieuwe scene.
Create new scene menu screenshot

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).
Create Characterbody2d scene for player screenshot

We krijgen nu een extra tabblad voor deze nieuwe 'Player' scene. Via de knoppen hieronder kan je wisselen tussen scenes die je open hebt.
Navigation buttons game scene - player scene screenshot

We voegen 2 nodes toe aan onze player:

  • een AnimatedSprite2D voor de graphics,
  • en een CollisionShape2D om botsingen te kunnen detecteren. Add nodes to player scene

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.
Add new spriteframes to player animatedsprite

De nieuwe SpriteFrames is nog leeg. Klik er op. Midden-beneden opent nu de editor voor de SpriteFrames in een paneel.
Click on spriteframes to open editor

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.
Spriteframes editor with navigation button

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.
Add animations

Spriteframes editor buttons used

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)

Add pngs as animation frames dialog

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.
Attach new script to player scene root node

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.
Create new script from template

Script editor example screen

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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.

Drag player onto scene

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.

Script button screenshot

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
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
hapasc2 profile image
Sean

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!

Collapse
 
eeveeplays1234 profile image
eevee gentzis

hey het is ilianos dus waneer ga je de dingen dat ik moet voor godot stuuren