|
| 1 | +--- |
| 2 | +contributors: |
| 3 | + - ["Wichamir", "https://github.com/Wichamir/"] |
| 4 | + - ["zacryol", "https://github.com/zacryol"] |
| 5 | +translators: |
| 6 | + - ["lele25811", "https://github.com/lele25811"] |
| 7 | +--- |
| 8 | + |
| 9 | +GDScript un linguaggio di scripting dinamicamente e staticamente |
| 10 | +tipizzato per il motore di gioco gratuito e open source Godot. La sua |
| 11 | +sintassi è vagamente simile a quella di Python. I suoi principali |
| 12 | +vantaggi sono la facilità d'uso e la stretta integrazione con il motore di gioco. |
| 13 | +È perfetto per lo sviluppo di giochi. |
| 14 | + |
| 15 | +## Basi |
| 16 | + |
| 17 | +```gdscript |
| 18 | +# I commenti a linea singola sono scritti usando il simbolo hash. |
| 19 | +""" |
| 20 | + Commenti |
| 21 | + su |
| 22 | + più |
| 23 | + linee |
| 24 | + sono |
| 25 | + scritti |
| 26 | + usando |
| 27 | + i triplici |
| 28 | + apici |
| 29 | + doppi |
| 30 | +""" |
| 31 | +
|
| 32 | +# I commenti del documento possono aggiungere una descrizione a classi e campi |
| 33 | +# che può essere visualizzato nella documentazione del engine. |
| 34 | +
|
| 35 | +## Questa classe è una dimostrazione di GDScript. |
| 36 | +
|
| 37 | +# Il file script è una classe e puoi opzionalmente definire un nome. |
| 38 | +class_name MyClass |
| 39 | +
|
| 40 | +# Eredita |
| 41 | +extends Node2D |
| 42 | +
|
| 43 | +# Variabili |
| 44 | +var x = 8 # int |
| 45 | +var y = 1.2 # float |
| 46 | +var b = true # bool |
| 47 | +var s = "Hello World!" # String |
| 48 | +var a = [1, false, "brown fox"] # Array - simile alle liste in Python, |
| 49 | + # può contenere diversi tipi |
| 50 | + # di variabili contemporaneamente. |
| 51 | +var d = { |
| 52 | + "key" : "value", |
| 53 | + 42 : true |
| 54 | +} # Dizionario - contiene coppie chiave-valore. |
| 55 | +var p_arr = PackedStringArray(["Hi", "there", "!"]) # Array impacchettato può |
| 56 | + # contenere solo un tipo di dato. |
| 57 | +
|
| 58 | +# Commenti della documentazione applicati alle proprietà. |
| 59 | +
|
| 60 | +## Quante volte questo oggetto ha saltato |
| 61 | +var jump_count = 0 |
| 62 | +
|
| 63 | +# Tipi vettoriali integrati: |
| 64 | +var v2 = Vector2(1, 2) |
| 65 | +var v3 = Vector3(1, 2, 3) |
| 66 | +
|
| 67 | +# Costanti |
| 68 | +const ANSWER_TO_EVERYTHING = 42 |
| 69 | +const BREAKFAST = "Spam and eggs!" |
| 70 | +
|
| 71 | +# Enumerazioni |
| 72 | +enum { ZERO, ONE , TWO, THREE } |
| 73 | +enum NamedEnum { ONE = 1, TWO, THREE } |
| 74 | +
|
| 75 | +# Le variabili esportate sono visibili nell'ispettore. |
| 76 | +# |
| 77 | +# oppure un tipo suggerimento (spiegato in seguito) o un valore predefinito che è necessario in seguito |
| 78 | +# l'editor suggerisce diverse opzioni |
| 79 | +@export var age: int |
| 80 | +@export var height: float |
| 81 | +@export var person_name = "Bob" |
| 82 | +# Ma entrambe sono accettate |
| 83 | +@export var favorite_color: String = "Green" |
| 84 | +@export var favorite_food := "Pizza" |
| 85 | +
|
| 86 | +# Funzioni |
| 87 | +func foo(): |
| 88 | + pass # pass è la parola chiave per passare al codice successivo |
| 89 | +
|
| 90 | +func add(first, second): |
| 91 | + return first + second |
| 92 | +
|
| 93 | +# Commenti documentazione sulle funzioni |
| 94 | +
|
| 95 | +## Incrementa il conteggio dei salti |
| 96 | +func jump(): |
| 97 | + jump_count += 1 |
| 98 | +
|
| 99 | +# Stampa valori |
| 100 | +func printing(): |
| 101 | + print("GDScript ", "is ", " awesome.") |
| 102 | + prints("These", "words", "are", "divided", "by", "spaces.") |
| 103 | + printt("These", "words", "are", "divided", "by", "tabs.") |
| 104 | + printraw("This gets printed to system console.") |
| 105 | +
|
| 106 | + # Funzioni Lambda |
| 107 | + var my_lambda = func(): print("hello from lambda!") |
| 108 | +
|
| 109 | + my_lambda.call() |
| 110 | +
|
| 111 | +# Matematica |
| 112 | +func doing_math(): |
| 113 | + var first = 8 |
| 114 | + var second = 4 |
| 115 | + print(first + second) # 12 |
| 116 | + print(first - second) # 4 |
| 117 | + print(first * second) # 32 |
| 118 | + print(first / second) # 2 |
| 119 | + print(first % second) # 0 |
| 120 | + # Ci sono anche +=, -=, *=, /=, %= etc., |
| 121 | + # Anche operatori ++ o --. |
| 122 | + print(pow(first, 2)) # 64 |
| 123 | + print(sqrt(second)) # 2 |
| 124 | + printt(PI, TAU, INF, NAN) # Costanti Integrate |
| 125 | +
|
| 126 | +# Controllo del flusso |
| 127 | +func control_flow(): |
| 128 | + x = 8 |
| 129 | + y = 2 # y era inizialmente un float, |
| 130 | + # ma possiamo cambiare il tipo in int |
| 131 | + # stiamo usando la potenza della programmazione dinamica! |
| 132 | +
|
| 133 | + if x < y: |
| 134 | + print("x is smaller than y") |
| 135 | + elif x > y: |
| 136 | + print("x is bigger than y") |
| 137 | + else: |
| 138 | + print("x and y are equal") |
| 139 | +
|
| 140 | + var a = true |
| 141 | + var b = false |
| 142 | + var c = false |
| 143 | + if a and b or not c: # in alternativa puoi utilizzare &&, || e ! |
| 144 | + print("This is true!") |
| 145 | +
|
| 146 | + for i in range(20): # L'intervallo di GDScript è simile a quello di Python |
| 147 | + print(i) # questo stamperà i numeri da 0 a 29 |
| 148 | +
|
| 149 | + for i in 20: # differentemente da Python puoi ciclare direttamente su un int |
| 150 | + print(i) # questo stamperà i numeri da 0 a 19 |
| 151 | +
|
| 152 | + for i in ["two", 3, 1.0]: # iterazione su un array |
| 153 | + print(i) |
| 154 | +
|
| 155 | + while x > y: |
| 156 | + printt(x, y) |
| 157 | + y += 1 |
| 158 | +
|
| 159 | + x = 2 |
| 160 | + y = 10 |
| 161 | + while x < y: |
| 162 | + x += 1 |
| 163 | + if x == 6: |
| 164 | + continue # 6 non verrà stampato causa la dichiarazione: continue |
| 165 | + prints("x is equal to:", x) |
| 166 | + if x == 7: |
| 167 | + break # il ciclo si fermerà a 7, quindi 8, 9 e 10 non verranno stampati |
| 168 | +
|
| 169 | + match x: |
| 170 | + 1: |
| 171 | + print("Match is similar to switch.") |
| 172 | + 2: |
| 173 | + print("However you don't need to put cases before each value.") |
| 174 | + 3: |
| 175 | + print("Furthermore each case breaks on default.") |
| 176 | + break # ERRORE! la dichiarazione break non è necessaria |
| 177 | + 4: |
| 178 | + print("If you need fallthrough use continue.") |
| 179 | + continue |
| 180 | + _: |
| 181 | + print("Underscore is a default case.") |
| 182 | +
|
| 183 | + # operatore ternario (la dichiarazione if-else è su una linea) |
| 184 | + prints("x is", "positive" if x >= 0 else "negative") |
| 185 | +
|
| 186 | +# Assegnazione delle parti (Casting) |
| 187 | +func casting_examples(): |
| 188 | + var i = 42 |
| 189 | + var f = float(42) # assegnazione utilizzando il costruttore di variabili |
| 190 | + var b = i as bool # oppure utilizzando la parola "as" |
| 191 | +
|
| 192 | +# Funzioni di sovraccarico (Override functions) |
| 193 | +# Per convenzione le funzione di Override iniziano con un trattino basso ( _ ), |
| 194 | +# ma in pratica puoi fare l'Override di qualsiasi funzione. |
| 195 | +
|
| 196 | +# _init è chiamata quando un oggetto viene inizializzato |
| 197 | +# È il costuttore del oggetto |
| 198 | +func _init(): |
| 199 | + # Inizializza le cose interne dell'oggetto |
| 200 | + pass |
| 201 | +
|
| 202 | +# _ready viene chiamato quando il nodo di script e |
| 203 | +# i suoi figli sono entrati nell'albero della scena. |
| 204 | +func _ready(): |
| 205 | + pass |
| 206 | +
|
| 207 | +# _process viene chiamato ogni frame |
| 208 | +func _process(delta): |
| 209 | + # L'argomento Delta passato a questa funzione è il numero di secondi |
| 210 | + # che passa tra l'ultimo frame e quello attuale. |
| 211 | + print("Delta time equals: ", delta) |
| 212 | +
|
| 213 | +# _physics_process viene chiamato ogni frame di fisica. |
| 214 | +# Ciò significa che delta dovrebbe essere una costante. |
| 215 | +func _physics_process(delta): |
| 216 | + # Semplice movimento mediante la somma vettoriale e la moltiplicazione. |
| 217 | + var direction = Vector2(1, 0) # oppure Vector2.RIGHT |
| 218 | + var speed = 100.0 |
| 219 | + self.global_position += direction * speed * delta |
| 220 | + # self si riferisce a se stesso nel attuale istanza di classe |
| 221 | +
|
| 222 | +# Quando si fa l'override di una funzione si può chiamare la funzione padre |
| 223 | +# tramite la funzione super() |
| 224 | +# come qui: |
| 225 | +func get_children(): |
| 226 | + # Fai cose in più qui. |
| 227 | + var r = super() # implementazione della chiamata alla funzione padre |
| 228 | + return r |
| 229 | +
|
| 230 | +# Classe annidata |
| 231 | +class InnerClass: |
| 232 | + extends Object |
| 233 | +
|
| 234 | + func hello(): |
| 235 | + print("Hello from inner class!") |
| 236 | +
|
| 237 | +func use_inner_class(): |
| 238 | + var ic = InnerClass.new() |
| 239 | + ic.hello() |
| 240 | + ic.free() # utilizza free per pulire la memoria |
| 241 | +``` |
| 242 | + |
| 243 | +## Accesso ad altri nodi nel albero di scena |
| 244 | + |
| 245 | +```gdscript |
| 246 | +extends Node2D |
| 247 | +
|
| 248 | +var sprite # La variabile conterrà il riferimento. |
| 249 | +
|
| 250 | +# Puoi ottenere le referenze per gli altri nodi in _ready. |
| 251 | +func _ready() -> void: |
| 252 | + # NodePath è utile per accedere ai nodi. |
| 253 | + # Crea NodePath passando il percorso al suo costruttore: |
| 254 | + var path1 = NodePath("path/to/something") |
| 255 | + # alternativamente puoi usare NodePath così: |
| 256 | + var path2 = ^"path/to/something" |
| 257 | + # NodePath esempi: |
| 258 | + var path3 = ^"Sprite" # percorso relativo, primo figlio dell'attuale nodo |
| 259 | + var path4 = ^"Timers/Firerate" # percorso relativo, figlio di suo figlio |
| 260 | + var path5 = ^".." # genitore del nodo corrente |
| 261 | + var path6 = ^"../Enemy" # fratello del nodo corrente |
| 262 | + var path7 = ^"/root" # percorso assoluto, equivalente a get_tree().get_root() |
| 263 | + var path8 = ^"/root/Main/Player/Sprite" # percorso assoluto alla sprite del giocatore |
| 264 | + var path9 = ^"Timers/Firerate:wait_time" # accesso alle proprietà |
| 265 | + var path10 = ^"Player:position:x" # accesso alle sottoproprietà |
| 266 | +
|
| 267 | + # Infine per ottenere un riferimento usa uno di questi: |
| 268 | + sprite = get_node(^"Sprite") as Sprite # sempre usata con il tipo di dati che ti aspetti |
| 269 | + sprite = get_node("Sprite") as Sprite # qui ottiene una stringa |
| 270 | + # implicitamente lanciato come NodePath |
| 271 | + sprite = get_node(path3) as Sprite |
| 272 | + sprite = get_node_or_null("Sprite") as Sprite |
| 273 | + sprite = $Sprite as Sprite |
| 274 | +
|
| 275 | +func _process(delta): |
| 276 | + # Ora possiamo riutilizzare il riferimento ad altri luoghi |
| 277 | + prints("Sprite has global_position of", sprite.global_position) |
| 278 | +
|
| 279 | +# Usiamo l'annotazione @onready per assegnare un valore |
| 280 | +# a una variabile prima del esecuzione di _ready. |
| 281 | +# Questa è la sintassi comunemente utilizzata. |
| 282 | +@onready var other_sprite = $Sprite as Sprite |
| 283 | +
|
| 284 | +# Puoi esportare NodePath, così da poterlo assegnare all'interno dell'ispettore. |
| 285 | +@export var nodepath = ^"" |
| 286 | +@onready var reference = get_node(nodepath) as Node |
| 287 | +
|
| 288 | +# oppure esportare un nodo direttamente |
| 289 | +@export var other_reference: Node |
| 290 | +``` |
| 291 | + |
| 292 | +## Segnali (Signals) |
| 293 | + |
| 294 | +Il sistema del segnali in Godot è una implementazione del pattern observer. |
| 295 | +Ecco un esempio: |
| 296 | + |
| 297 | +```gdscript |
| 298 | +class_name Player extends Node2D |
| 299 | +
|
| 300 | +var hp = 10 |
| 301 | +
|
| 302 | +# La documentazione può andare anche sui segnali |
| 303 | +
|
| 304 | +## Emesso quando il giocatore muore |
| 305 | +signal died() # definisci un segnale |
| 306 | +signal hurt(hp_old, hp_new) # il segnale prende un argomento |
| 307 | +
|
| 308 | +func apply_damage(dmg): |
| 309 | + var hp_old = hp |
| 310 | + hp -= dmg |
| 311 | + hurt.emit(hp_old, hp) # emette un segnale e passa un argomento |
| 312 | + if hp <= 0: |
| 313 | + died.emit() |
| 314 | +
|
| 315 | +func _ready(): |
| 316 | + # connette il segnale "died" alla funzione "_on_death" definita in automatico |
| 317 | + died.connect(_on_death) |
| 318 | + # Alternativamente |
| 319 | + # se l'oggetto target non è se stesso, ma un altro oggetto |
| 320 | + # died.connect(Callable(self, &"_on_death")) |
| 321 | +
|
| 322 | +func _on_death(): |
| 323 | + queue_free() # distrugge il giocatore alla morte |
| 324 | +``` |
| 325 | + |
| 326 | +## Tipi suggeriti (Type hints) |
| 327 | + |
| 328 | +GDScript opzionalmente può utilizzare la tipizzazione statica, sia per la chiarezza del codice che per i vantaggi delle prestazioni. |
| 329 | + |
| 330 | +```gdscript |
| 331 | +extends Node |
| 332 | +
|
| 333 | +var x: int # definizione del tipo di variabile |
| 334 | +var y: float = 4.2 |
| 335 | +var z := 1.0 # accenno del tipo per i valori di default usiamo l'operatore := |
| 336 | +
|
| 337 | +var a: Array[int] = [1, 2, 3] # gli array possono anche avere un tipo specifico per il contenuto |
| 338 | +
|
| 339 | +enum NamedEnum { ONE = 1, TWO, THREE } |
| 340 | +var n: NamedEnum = NamedEnum.ONE # l'enumerazione può essere usata anche come tipo |
| 341 | +
|
| 342 | +@onready var node_ref_typed := $Child as Node |
| 343 | +
|
| 344 | +@export var speed := 50.0 |
| 345 | +
|
| 346 | +const CONSTANT := "Typed constant." |
| 347 | +
|
| 348 | +signal example(arg: int) |
| 349 | +
|
| 350 | +func _ready() -> void: |
| 351 | + # funzione che ritorna nulla |
| 352 | + x = "string" # ERRORE! Il tipo non può essere cambiato |
| 353 | + a.append("q") # ERRORE! Array[int] non può contenere stringhe |
| 354 | + return |
| 355 | +
|
| 356 | +func join(arg1: String, arg2: String) -> String: |
| 357 | + # la funzione prende in input due stringhe e ritorna una stringa |
| 358 | + return arg1 + arg2 |
| 359 | +
|
| 360 | +func get_child_at(index: int) -> Node: |
| 361 | + # funzione prende in input un int e ritorna un nodo |
| 362 | + return get_children()[index] |
| 363 | +``` |
| 364 | + |
| 365 | +## Ulteriori letture |
| 366 | + |
| 367 | +* [Sito web di Godot](https://godotengine.org/) |
| 368 | +* [Documentazione Godot](https://docs.godotengine.org/en/stable/) |
| 369 | +* [Inizia con GDScript](https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/index.html) |
| 370 | +* [NodePath](https://docs.godotengine.org/en/stable/classes/class_nodepath.html) |
| 371 | +* [Signals](https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html) |
| 372 | +* [GDQuest](https://www.gdquest.com/) |
| 373 | +* [GDScript.com](https://gdscript.com/) |
0 commit comments