Primul script și mișcarea personajului
Scrii primul cod în GDScript, înveți ce sunt variabilele și funcțiile, apoi faci personajul să se miște cu tastele săgeți.
La finalul fișei, elevul poate:
- atașeze un script unui nod și să explice rolul liniei extends
- folosească variabile și funcții în GDScript
- respecte indentarea, obligatorie în GDScript
- transforme apăsarea tastelor în mișcare pe ecran
Ai nevoie de:
- Godot 4
- Proiectul ColecteazaMonede, cu main.tscn și player.tscn din fișa 2
Până acum ai construit. De aici încolo dai instrucțiuni: personajul va face ce îi spui tu.
1. Ce este un script
Un script este o listă de instrucțiuni atașată unui nod. Nodul le execută în timp ce jocul rulează.
Limbajul se numește GDScript și seamănă mult cu Python.
extends CharacterBody2D
var speed: float = 200.0
func _ready():
print("Player pregătit")
| Linia | De unde vine | Ce înseamnă |
|---|---|---|
extends CharacterBody2D | cuvânt al limbajului | scriptul aparține unui nod de tip CharacterBody2D |
var | cuvânt al limbajului | anunță că urmează o variabilă |
speed | ales de tine | numele variabilei; puteai scrie viteza |
: float | tip din Godot | valoarea poate avea zecimale |
= 200.0 | ales de tine | valoarea de pornire |
func | cuvânt al limbajului | anunță că urmează o funcție |
_ready() | funcție a lui Godot | Godot o cheamă singur, o dată, la pornire |
print() | funcție a lui Godot | o chemi tu; scrie un mesaj în panoul Output |
2. Atașăm scriptul
- Deschide
player.tscnși selectează nodul rădăcinăPlayer. - Apasă butonul cu sulul și semnul plus 📜 din partea de sus a panoului Scene (Attach Script).
- Lasă numele propus,
player.gd, și apasă Create.
Editorul trece în modul Script. Godot a scris deja un schelet de cod.
- Șterge tot și scrie exact:
extends CharacterBody2D
var speed: float = 200.0
func _ready():
print("Player pregătit")
- Ctrl+S, apoi deschide
main.tscnși rulează cu F5. - Închide fereastra jocului și uită-te în panoul Output, jos.
Acolo scrie Player pregătit. Primul tău cod a rulat.
3. Mișcarea
_ready() rulează o singură dată. Pentru mișcare avem nevoie de ceva care rulează
în continuu.
Înlocuiește funcția _ready() cu:
extends CharacterBody2D
var speed: float = 200.0
func _physics_process(delta):
var directie = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
velocity = directie * speed
move_and_slide()
Salvează, deschide main.tscn și rulează cu F5. Apasă săgețile.
Personajul se mișcă în toate direcțiile.
4. Codul explicat
| Instrucțiunea | De unde vine | Ce face |
|---|---|---|
_physics_process(delta) | funcție a lui Godot | Godot o cheamă singur, de circa 60 de ori pe secundă |
delta | dat de Godot | timpul trecut de la cadrul anterior |
directie | ales de tine | variabilă nouă, în care păstrezi direcția |
Input.get_vector(...) | funcție a lui Godot | o chemi tu; citește cele patru săgeți și dă o direcție |
speed | ales de tine | variabila declarată mai sus |
velocity | proprietate moștenită | vine de la CharacterBody2D; viteza corpului |
move_and_slide() | funcție a lui Godot | o chemi tu; mută nodul și îl oprește la ciocniri |
Input.get_vector întoarce o pereche de numere între −1 și 1:
| Ce apeși | Direcția |
|---|---|
| nimic | (0, 0) |
| săgeata dreapta | (1, 0) |
| săgeata sus | (0, -1) |
| dreapta + sus | cam (0.7, -0.7) |
Despre delta: aici nu îl folosim direct, pentru că move_and_slide() ține singur cont de
timp. Îl păstrăm în paranteză pentru că Godot îl trimite automat, indiferent dacă îl folosim.
5. De unde vin numele din cod
Într-un script, numele vin din trei locuri diferite. Confuzia dintre ele e cea mai frecventă
la început — mai ales întrebarea: dacă eu nu chem _physics_process, cine o cheamă?
| Categoria | Cine scrie numele | Cine îl folosește | Exemple |
|---|---|---|---|
| Ales de tine | tu | tu | speed, directie |
| Dat de Godot | Godot | tu îl chemi | print(), move_and_slide(), velocity |
| Funcție specială | tu scrii conținutul | Godot o cheamă | _ready(), _physics_process() |
Ultima categorie e cea nouă. Tu scrii ce e înăuntrul funcției, dar nu o chemi niciodată. Godot știe dinainte cum se numesc aceste funcții și le cheamă singur, la momentul potrivit.
| Funcția | Când o cheamă Godot |
|---|---|
_ready() | o singură dată, când nodul intră în joc |
_process(delta) | la fiecare cadru desenat |
_physics_process(delta) | de circa 60 de ori pe secundă, pentru mișcare și fizică |
Exerciții
🔑 Rezolvare
| Valoarea | Cum se simte |
|---|---|
50.0 | foarte lent, plictisitor de jucat |
200.0 | control bun, echilibrat |
800.0 | prea rapid, greu de oprit unde vrei |
Nu există un răspuns corect unic. Reglarea acestor numere până când jocul „se simte bine” se numește game feel și e o parte reală din munca unui dezvoltator de jocuri.
🔑 Rezolvare
directie este (0, 0).
Înmulțit cu speed, rezultă tot (0, 0), deci velocity e zero. Funcția rulează în
continuare, move_and_slide() se execută de 60 de ori pe secundă — dar mută personajul cu
zero pixeli.
Codul lucrează tot timpul; doar rezultatul e „stai pe loc”.
🔑 Rezolvare
- „Expected indented block” sau codul iese din funcție — personajul nu se mai mișcă, pentru că linia nu mai face parte din funcție.
- Niciun mesaj de eroare, dar personajul nu se mișcă deloc. Godot cheamă automat doar
funcțiile cu nume exact;
_physics_procesnu înseamnă nimic pentru el, deci nu o cheamă niciodată. Aceasta e cea mai greu de găsit dintre cele trei. - Eroare de sintaxă, marcată cu roșu chiar în editor, la salvare.
De reținut: o eroare afișată e o veste bună. Cel mai greu de depanat e codul care „nu face nimic”, fără să se plângă.
🔑 Rezolvare
1. Spune cărui tip de nod aparține scriptul. De acolo moștenește velocity și
move_and_slide().
2. Pentru că în 2D axa Y crește în jos. Ca să urci, trebuie să scazi din Y.
3. _ready() rulează o singură dată, la pornire. _physics_process() rulează
în continuu, de circa 60 de ori pe secundă.
4. Personajul ar rămâne pe loc. velocity s-ar calcula corect, dar nimeni nu l-ar mișca:
move_and_slide() este cel care aplică viteza asupra nodului.
Ce ai învățat
- Un script se atașează unui nod;
extendsspune ce fel de nod este. varcreează o variabilă;funccreează o funcție.- Indentarea cu Tab decide ce e în interiorul unei funcții.
- Numele din cod vin din trei locuri: alese de tine, date de Godot (tu le chemi) și funcții speciale (Godot le cheamă).
- Regula liniuței de jos: funcțiile care încep cu
_sunt chemate de Godot, nu de tine. _ready()rulează o dată,_physics_process()rulează în continuu.Input.get_vectortransformă tastele în direcție;move_and_slide()mută personajul.
Personajul se mișcă — dar iese din ecran. În fișa următoare îi punem pereți.