Construeix un joc de plataformes 2D complet amb

Godot

UNA GUIA PRÀCTICA - 1ª EDICIÓ

Daniel Buckley Pablo Farias

academy.zenva.com youtube.com/c/zenva linkedin.com/company/zenva

©2026 Zenva Pty Ltd, tots els drets reservats

Taula de continguts

Introducció 7

Com utilitzar aquest llibre 7

Introducció i configuració de l'entorn 8

Requisits previs 8

Fitxers del projecte 9

Què construirem 10

Estructura del llibre 10

Instal·lació de Godot i versió 11

Com instal·lar la versió 4.6 11

Inicialització del projecte 13

Visió general del disseny del joc 13

Controls i moviment del jugador 13

Enemics i sistema de danys 14

Monedes i objectes de col·lecció 16

Progressió de nivell 17

Menú Play 18

Configuració del projecte 19

Importació d'actius 19

Creació de carpetes de projectes 22

Configuració de la primera escena 25

Construir el món amb mapes de mosaic 29

Creació d'un TileMapLayer 29

Configuració del TileSet 32

Ajustar les dimensions de les rajoles 37

Afegir propietats de col·lisió 39

Pintura de rajoles a l'escena 41

Arreglar Sprites borrosos 43

Dissenya el teu nivell 45

Configuració del fons 45

Correcció d'errors habituals de TileSet 47

Creació de l'escena del jugador 49

Entendre l'escena del jugador 49

Creació del node del reproductor 49

Afegir elements visuals 53

Definició de la física 57

Configuració de la càmera 59

Afegir nodes d'utilitat 62

Configuració del mapa d'entrada 65

Per què utilitzar les accions d'entrada? 65

Configuració d'accions 66

Assignació de claus 67

Implementació del moviment del jugador 71

Configuració de l'script del reproductor 71

Definició de variables de moviment 73

Implementació del moviment bàsic 73

Aplicació de la gravetat 75

Implementació del salt 76

Moviment suavitzant 78

Visuals: Flipping the Sprite 80

Sistema d'animació del jugador 83

Entendre les animacions a Godot 83

Configuració del reproductor d'animació 83

Creació de l'animació inactiva 84

Afegir la pista de textura 86

Configuració de fotogrames clau 88

Entendre les pistes de RESET 89

Creació de l'animació de moviment 89

Afegir quadres de moviment 91

Loop i cronometratge 94

Creació de l'animació de salt 95

Escriptura de la lògica d'animació 98

Prova el joc 100

Creació d'enemics 103

Configuració de l'escena enemiga 103

Creació dels nodes 104

Programació del moviment de l'enemic 113

Prova del moviment 115

Detecció del jugador 118

Ús de grups 121

Prova de col·lisió 122

Animant l'enemic 122

Reproducció de l'animació 128

Mecànica bàsica: salut i puntuació 130

El sistema de danys 130

Configuració de la salut del jugador 130

Creació de la funció Take Damage 130

Implementant Game Over 131

Actualització de l'script Enemy 131

Gestió de les devolució de trucades de física 132

Prova i desa 133

Creació de col·leccionables 136

Configuració de l'escena de la moneda 136

Programació de l'animació de la moneda 141

Recollida de monedes 144

Actualització de l'script del reproductor 144

Tractament de la col·lisió 145

Prova i desa 147

Puntuació persistent 150

Creació d'un script de càrrega automàtica 150

Implementació del Global Score 154

Actualització de l'script del reproductor 154

Prova de persistència 154

Lògica de superació del nivell 156

Organització de la jerarquia de l'escena 156

Creació de la bandera final 161

Escriptura de la bandera final 166

Connexió del senyal 167

Implementació de la transició d'escena 169

Prova de la bandera final 170

Construcció de la interfície d'usuari 173

Configuració del CanvasLayer 173

Creació de la pantalla de salut 175

Afegir la textura del cor 175

Ús de contenidors per al disseny 180

Creació del text de la partitura 184

Connexió de la lògica amb senyals 190

Actualització de l'script del reproductor 190

Creació de l'script de la IU 191

Implementació de funcions d'actualització 193

Connectant-ho tot a _ready 193

Prova de la IU 194

Efectes visuals i àudio 196

Visuals de danys 196

Implementació de Damage Flash 196

Implementació de Screen Shake 198

Evitar la caiguda infinita 200

Parallax de fons 201

Redimensionament i posicionament 201

Creació d'un fons de mosaic 202

Organització dels nodes de fons 203

Implementació de l'script Parallax 207

Àudio 209

Inspecció d'actius d'àudio 209

Actualització de l'script del reproductor 211

Activació dels sons 212

Prova d'àudio 213

Disseny de nivell 214

Creació de nous nivells 214

Duplicant el primer nivell 214

Modificació del fons 216

Edició del mapa de rajoles 218

Elements del joc de posicionament 221

Bandera final 221

Monedes 222

Enemics 223

Canviar els colors de fons 225

Repte: alterar la bandera final 229

Solució del repte 230

Creació del menú principal 232

Creació de l'escena del menú 232

Afegir una imatge de fons 234

Afegeix un títol 239

Afegir botons 247

Escriptura del menú 253

Integració del menú al bucle de joc 257

Prova del menú 257

Nivells de connexió 257

Actualització de lògica de Game Over 259

Paraules de tancament 260

El que has aconseguit 260

On anar des d'aquí 261

  1. Amplieu aquest projecte 261
  2. Uneix-te a un Game Jam 261
  3. Exploreu la documentació 261
  4. Reconstrueix sense el llibre 262
  5. Continueu el vostre aprenentatge 262

Pensaments finals 262

Referència completa del codi font 263

background_parallax.gd 263

camera_shake.gd 263

coin.gd 264

end_flag.gd 265

enemy.gd 266

menu.gd 266

player.gd 267

player_stats.gd 269

player_ui.gd 270

Introducció

Benvingut al teu viatge cap al desenvolupament de jocs amb Godot. Tant si sempre has somiat amb construir els teus propis mons o simplement vols entendre la màgia que hi ha darrere dels teus jocs preferits, estàs al lloc correcte.

El desenvolupament de jocs és una combinació única de lògica i creativitat. Requereix que penseu com un programador, un artista i un dissenyador alhora. Això pot semblar intimidatori, però Godot està dissenyat per fer que aquest procés sigui el més intuïtiu possible. S'encarrega de la càrrega pesada de renderitzar gràfics i calcular la física perquè pugueu centrar-vos en allò que importa: fer que el vostre joc sigui divertit.

La millor manera d'aprendre a desenvolupar jocs és fent. En aquest llibre, no només llegirem sobre codi ni memoritzarem botons de la interfície. Construirem un joc de plataformes en 2D real i jugable des de zero.

Al llarg dels capítols següents, abordarem totes les parts del projecte, des del moviment i la física fins a les interfícies d'usuari i els bucles de joc.

Cada capítol es basa en l'últim per ampliar el vostre conjunt d'eines i, al final, tindreu un joc complet que podreu mostrar i ampliar pel vostre compte.

Com utilitzar aquesta guia

Per treure el màxim profit d'aquesta experiència, tracta aquest llibre com un taller més que com una conferència. Aquí teniu alguns consells per ajudar-vos a tenir èxit:

El motor està esperant i el teu primer projecte està a la volta de la cantonada. Passem pàgina i configurem el vostre entorn de desenvolupament.

Introducció i configuració de l'entorn

Benvingut a aquesta guia per crear un joc de plataformes en 2D amb el motor Godot. Junts, construirem un joc de plataformes 2D complet des de zero, incorporant mecàniques de joc essencials i elements de poliment perquè el joc sigui atractiu i emocionant.

Requisits previs

Per garantir una experiència d'aprenentatge fluida, es requereix una comprensió bàsica del motor Godot i GDScript. Hauríeu d'estar familiaritzat amb els següents conceptes fonamentals:

Si alguns d'aquests conceptes us són nous, us recomanem que consulteu els recursos següents per posar-vos al dia:

Aprèn Godot des de zero

(https://academy.zenva.com/product/intro-to-godot-ebook/)

Miniprojectes amb Godot

(https://academy.zenva.com/product/godot-mini-projects-ebook/) Alternativament, si preferiu cursos de vídeo:

Godot 4 Mini-Projectes

(https://academy.zenva.com/product/godot-4-mini-projects/)

Dit això, seguirem cada pas amb cura mentre treballem a l'editor i escrivim codi junts.

Fitxers del projecte

Per seguir els tutorials, necessitareu els actius del projecte. També hem proporcionat el projecte complet com a referència. Podeu descarregar-los mitjançant els enllaços següents:

Fitxers d'actius:

(https://academy.zenva.com/wp-content/uploads/2026/02/Assets-Go dot-2D-Platformer.zip)

Projecte complet:

(https://academy.zenva.com/wp-content/uploads/2026/02/Complete-Project-Godot-2D-Platformer-v4.6.zip)

Llicències d'actius de tercers

Alguns dels actius proporcionats en aquest curs estan subjectes a llicències de tercers:

Actius de Kenney URL de sprites i fons: https://kenney.nl/

Llicència: Creative Commons CC0 (https://creativecommons.org/publicdomain/zero/1.0/)

Actius creats per Zenva

Totes les altres obres d'art i recursos multimèdia inclosos als fitxers del projecte que no s'enumeren més amunt han estat creats per Zenva i es publiquen sota:

Creative Commons CC0 (domini públic)

https://creativecommons.org/publicdomain/zero/1.0/

El codi font creat per Zenva inclòs als fitxers del projecte d'aquest curs es publica sota la llicència MIT (https://opensource.org/license/MIT).

Les biblioteques i dependències de tercers romanen sota les seves respectives llicències.

Que construirem

En aquest projecte, crearem un joc de plataformes funcional amb diverses funcions clau. Al final d'aquest llibre, sabràs com:

Estructura de la guia

Aquí teniu una visió general dels temes inclosos en aquesta guia:

  1. Inicialització del projecte: Visió general del disseny del joc, importació d'actius i creació de la primera escena.
  2. Construint el món amb mapes de mosaic: pintar rajoles, afegir col·lisions i configurar el fons.
  3. Creació de l'escena del jugador: Construcció del CharacterBody2D, forma de col·lisió, càmera i mapa d'entrada.
  4. Implementació del moviment del jugador: Gravetat, salts, acceleració suau i volteig de sprites.
  5. Sistema d'animació del jugador: animacions inactius, moure i saltar amb AnimationPlayer.
  6. Creant enemics: patrulla d'enemics basats en Area2D, detecció de senyals i grups.
  7. Mecànica bàsica: salut i puntuació: danys, finalització del joc, monedes col·leccionables i persistència de càrrega automàtica.
  8. Lògica de finalització de nivell: organització de l'escena i la transició EndFlag.
  9. Construcció de la interfície d'usuari: CanvasLayer HUD amb cors i una etiqueta de puntuació.
  10. Efectes visuals i àudio: Flaix danyat, sacsejada de la pantalla, fons de paral·laxi i efectes de so.
  11. Disseny de nivells i reptes finals: Creació del nivell 2 i correcció d'alguns errors.
  12. Creació del menú principal: botons de reproducció i sortida, ancoratges i el bucle complet del joc.

Instal·lació dels versos de Godot

Aquest llibre fa servir Godot versió 4.6, l'últim llançament estable en el moment d'escriure.

És important utilitzar aquesta versió específica per assegurar-se que el codi i els fitxers de projecte proporcionats funcionen com s'esperava. Les versions més noves poden introduir canvis que podrien trencar la compatibilitat amb les instruccions d'aquesta guia.

Com instal·lar la versio 4.6

Podeu descarregar la versió 4.6 del motor visitant l'arxiu oficial de descàrregues de Godot (https://godotengine.org/download/archive/4.6-stable/).

En aquesta pàgina, seleccioneu l'opció Estàndard que coincideixi amb el vostre sistema operatiu. Tingueu en compte que les instruccions proporcionades en aquest llibre electrònic només estan pensades per a ordinadors de sobretaula.

La pàgina web de Godot 4.6 amb les opcions estàndard per a les versions d'escriptori encerclades

Un cop descarregat el fitxer, descomprimiu-lo a la ubicació que vulgueu. Godot no requereix un procés d'instal·lació tradicional; simplement feu doble clic al fitxer de l'aplicació per iniciar el motor.

Inicialitzacio del projecte

En aquest capítol, establirem les bases del nostre joc de plataformes 2D. Abans d'escriure qualsevol codi o col·locar nodes, és fonamental tenir una visió clara del joc que estem construint. Començarem revisant el disseny i la mecànica del joc per entendre l'abast del projecte.

Un cop tinguem un pla clar, procedirem a engegar el projecte Godot. Això implica importar els recursos artístics i d'àudio necessaris, organitzar l'estructura del fitxer i crear l'escena inicial per al nostre primer nivell.

Visio general del disseny del joc

El nostre objectiu és crear un joc de plataformes en 2D clàssic on el jugador navegui pels nivells, reculli monedes, eviti enemics i assoleixi un objectiu final. Entendre aquests components ara ens ajudarà a estructurar els nostres nodes i scripts de manera eficaç en capítols posteriors.

Controls i moviment del jugador

El personatge del jugador serà el punt focal del joc. Implementarem controls de teclat per gestionar el moviment:

Per assegurar-nos que el joc se sent responsiu i polit, no utilitzarem moviments bàsics i rígids. En lloc d'això, implementarem la mecànica basada en la física:

Aquestes addicions creen una sensació de pes i impuls, fent que l'experiència de plataformes sigui molt més satisfactòria que un simple moviment de píxels perfecte.

Aquesta imatge d'art de píxels il·lustra una escena de plataformes en 2D fonamental del tutorial de Godot, que mostra un personatge de jugador verd amb un casc blanc dempeus sobre una plataforma de terra amb gespa, enfrontant-se a un petit enemic semblant a un ratpenat a l'aire entre plataformes i una moneda daurada que gira a la plataforma adjacent, que representa visualment els elements bàsics del joc: el moviment del jugador, la col·lisió de l'enemic i la col·lecció de monedes descrits a la lliçó.

Enemics i sistema de dany

Per afegir desafiaments, el joc comptarà amb enemics que patrullen zones específiques. Dissenyarem un sistema on els enemics es moguin d'anada i tornada entre dos punts definits, requerint que el jugador cronometra els seus moviments amb cura.

Aquesta imatge d'art de píxels il·lustra la mecànica de moviment vertical del personatge del jugador al tutorial de plataformes 2D de Godot, que mostra un petit jugador semblant a un robot a l'aire entre dues plataformes de terra amb un fons de palmera; una fletxa vermella de doble punta a sobre del jugador emfatitza visualment el moviment de salt i caiguda que s'està implementant, mentre que una moneda daurada que gira a la plataforma dreta reforça el sistema de col·leccionisme descrit a la lliçó.

La interacció amb els enemics activarà un sistema de danys. Quan el jugador xoca amb un enemic:

  1. La salut del jugador disminuirà en un.
  2. La interfície d'usuari s'actualitzarà per eliminar un cor.
  3. La pantalla parpellejarà en vermell i tremolarà per proporcionar comentaris visuals.
  4. Es reproduirà un efecte de so.

Aquest bucle de retroalimentació multisensorial garanteix que el jugador entengui clarament quan ha patit danys.

Aquesta imatge mostra la interfície d'usuari de la salut i la puntuació del joc del tutorial de plataformes Godot 2D: tres cors vermells amb art de píxels a la part superior indiquen la salut total del jugador i, a sota, el text blanc diu "Puntuació: 0", que representa la puntuació inicial abans de recollir les monedes, il·lustrant directament el sistema de danys (reducció de salut mitjançant l'eliminació del cor) i la mecànica de puntuació descrita a la lliçó.

Monedes i col·leccionables

L'exploració es recompensa amb objectes de col·lecció. Col·locarem monedes al llarg dels nivells que augmenten la puntuació del jugador quan es recullin. Perquè destaquin, afegirem un poliment visual:

Aquesta imatge d'art de píxels del tutorial de plataformes 2D de Godot representa una única moneda col·leccionable flotant per sobre d'una plataforma de terra i herba, que representa visualment el sistema de monedes descrit a la lliçó; quan es recull, augmenta la puntuació del jugador en un i activa efectes visuals/àudio com la rotació i el balanceig; aquesta visió aïllada emfatitza la moneda com un objecte de joc autònom que s'ha d'implementar amb comportaments com l'animació basada en ones sinusoïdals per al moviment i la reproducció de so a la col·lecció.

Progressio de nivells

L'objectiu de cada etapa és arribar a la bandera final. Aquest objecte actuarà com a portal; quan el jugador entri a la seva àrea, el joc carregarà automàticament l'escena del següent nivell.

Aquesta imatge d'art de píxels del tutorial de plataformes en 2D de Godot il·lustra la mecànica de finalització de nivell: un personatge de jugador verd amb un casc blanc es troba sobre una plataforma de terra i herba al costat d'una bandera vermella muntada en un pal gris, que representa visualment l'objectiu descrit a la lliçó. Quan el jugador arriba a aquesta bandera, es teletransporta al següent nivell, que serveix com a punt de transició entre les etapes.

Menú principal

Finalment, crearem una interfície d'usuari senzilla per gestionar l'estat del joc. Un menú principal saludarà el jugador amb opcions per iniciar el joc o sortir de l'aplicació.

Aquesta imatge mostra l'escena del menú principal del joc de plataformes 2D que s'està construint al tutorial de Godot, amb el títol "Joc de plataformes 2D" en text groc centrat a la part superior, amb dos botons rectangulars grisos etiquetats "Jugar" i "Surt" apilats verticalment a sota, que representen la interfície d'usuari inicial per iniciar o sortir del joc tal com es descriu a la secció del menú de la lliçó.

Tenint en compte aquest disseny, ara podem passar a Godot i començar a configurar el nostre projecte.

Configuracio del projecte

En aquesta secció, inicialitzarem el projecte, importarem els nostres actius i organitzarem el sistema de fitxers. Una organització adequada des del principi fa que sigui molt més fàcil gestionar un projecte de joc en creixement, ja que afegim escenes, guions i recursos en capítols posteriors.

Importacio dels recursos

El nostre joc es basa en fitxers d'art i de so prefabricats, de manera que el primer pas és introduir-los al motor. Si encara no ho heu fet, descarregueu el fitxer zip de l'actiu

previst en el Introducció capítol. Extraieu el contingut del fitxer zip a una ubicació convenient de l'ordinador.

Hauríeu de veure dues carpetes:

La imatge mostra el moll FileSystem del projecte Godot 2D Platformer, mostrant dues carpetes importades: "Audio" i "Sprites", que corresponen a les carpetes d'actius descrites a la lliçó per emmagatzemar efectes de so i actius visuals respectivament; aquestes són les carpetes inicials importades abans de crear carpetes addicionals "Guions" i "Escenes" segons les instruccions.

Per importar-los a Godot, simplement arrossegueu i deixeu anar les carpetes d'àudio i sprites del vostre explorador de fitxers directament a Sistema de fitxers moll dins de l'editor Godot.

Aquesta imatge il·lustra el procés d'importació de carpetes d'actius al moll del sistema de fitxers de Godot: les carpetes "Àudio" i "Sprites", extretes dels materials del curs, s'arrosseguen des d'una finestra de l'Explorador de fitxers de Windows al tauler Sistema de fitxers de l'editor Godot (situat a res://), tal com indiquen la fletxa puntejada vermella i les icones de carpeta ressaltades; aquest pas segueix la descàrrega i l'extracció del fitxer zip proporcionat i precedeix la creació de noves carpetes de projecte com "Guions" i "Escenes", tal com es descriu a la lliçó.

Godot importarà automàticament els fitxers. Preneu-vos un moment per verificar que les carpetes apareixen al moll del sistema de fitxers i continguin els actius esperats.

La imatge mostra el dock del sistema de fitxers de Godot amb el directori arrel "res://" ampliat, mostrant dues carpetes d'actius importats: "Audio" i "Sprites", que es destaquen amb un quadre vermell i una fletxa per emfatitzar la seva importació correcta tal com s'indica a la lliçó; aquestes carpetes contenen efectes de so i actius visuals respectivament, formant l'estructura fonamental abans de crear carpetes addicionals com Scripts i Scenes.

Creacio de carpetes del projecte

Per mantenir el nostre projecte organitzat, hauríem de separar els nostres fitxers de lògica i d'escena dels nostres actius en brut. Crearem dues carpetes noves:

Per crear-los, feu clic amb el botó dret a la carpeta arrel (res://) al fitxer Sistema de fitxers acobla i selecciona Carpeta nova.

La imatge mostra el dock del sistema de fitxers de Godot amb el directori arrel "res://" ampliat, mostrant les carpetes importades "Audio" i "Sprites", juntament amb un fitxer anomenat "icon.svg". Una fletxa vermella apunta al menú contextual que s'obre fent clic amb el botó dret a l'àrea FileSystem, ressaltant l'opció "Nova carpeta...", que s'està seleccionant per crear nous directoris de projecte tal com s'indica a la lliçó: específicament, les carpetes "Scripts" i "Escenes" necessàries per organitzar fitxers de codi i escenes.

Introduïu el nom Scripts i feu clic D'acord, després repetiu aquest procés per crear una carpeta anomenada Escenes.

Aquesta imatge mostra el diàleg "Crea una carpeta" de Godot, on l'usuari anomena una carpeta nova; el camp de text sota "Nom" conté "carpeta nova" i un missatge verd a continuació confirma que "El nom de la carpeta és vàlid". La ruta base del diàleg s'estableix a "res://", que indica l'arrel del projecte. Es destaquen dues notes vermelles numerades: (1) el camp d'entrada del nom i (2) el botó "D'acord" per finalitzar la creació de carpetes, il·lustrant el pas de la lliçó en què els usuaris creen carpetes com "Guions" i "Escenes" introduint un nom i confirmant amb D'acord.

El vostre sistema de fitxers hauria de semblar ara a la imatge següent, amb quatre carpetes diferents.

Aquesta imatge mostra el moll del sistema de fitxers de Godot amb l'arrel del projecte "res://" expandida, mostrant les carpetes recentment creades "Escenes" i "Scripts", que es destaquen amb un quadre vermell i una fletxa per indicar la seva creació correcta tal com s'indica a la lliçó; aquestes carpetes es col·loquen a sota de les carpetes "Audio" i "Sprites" importades anteriorment i per sobre del fitxer "icon.svg", establint l'estructura de directoris fonamental per organitzar els fitxers d'escena i els fitxers de script respectivament.

Configuració de la primera escena

Amb les nostres carpetes al seu lloc, és hora de crear l'escena que mantindrà el nostre primer nivell. Una escena a Godot és l'element bàsic per organitzar el vostre joc, de manera que entendre com funcionen les escenes i els nodes us ajudarà durant la resta del llibre.

Nota de Godot: l'arbre de l'escena i els nodes

A Godot, cada objecte del joc és un "node" i els nodes s'organitzen en una jerarquia d'arbre. Una escena és simplement una branca guardada d'aquest arbre que es pot reutilitzar. El Node2D que acabem de crear és el tipus base per a tots els objectes 2D. Proporciona una posició, rotació i escala en l'espai 2D, i qualsevol node secundari hereta la seva transformació.

Això vol dir que quan moveu un node pare, tots els seus fills es mouen amb ell. Aquesta relació pare-fill és la base per construir objectes de joc complexos a partir de parts simples.

Més informació: Node2D (https://docs.godotengine.org/en/4.6/classes/class_node2d.html)

En el Escena acoblar (cantonada superior esquerra), feu clic Escena 2D. Això crea una nova escena amb Node2D com a arrel.

A la base d'escenes de Godot, la secció "Crea un node arrel" mostra una llista de tipus de nodes per inicialitzar una escena nova; l'opció "Escena 2D" està seleccionada i destacada amb un quadre vermell i una fletxa, que indica que és l'opció correcta per configurar la primera escena de nivell 2D tal com s'indica a la lliçó.

Canvieu el nom del node arrel a Principal fent-hi doble clic. Això ens ajuda a identificar el propòsit de l'escena.

Al moll d'escenes de Godot, la pestanya "Importa" està activa, mostrant una llista d'escenes amb "Principal" seleccionat com a node arrel, indicat per un botó de ràdio ple; això reflecteix el pas en què l'usuari anomena el node arrel "Principal" després de crear una nova escena 2D per al nivell 1, tal com s'indica a la lliçó.

Finalment, salvem l'escena. Premeu Ctrl + S (o Cmd + S a macOS) o aneu a Escena > Desa l'escena. Navegueu a la carpeta Scenes que acabeu de crear i poseu un nom al fitxer level_1.tscn.

Aquesta imatge mostra el diàleg "Desa l'escena com a..." de Godot, on l'usuari està desant un fitxer d'escena nou; el camp Path mostra "res://Scenes", indicant que l'escena es desarà dins de la carpeta Escenes acabada de crear, i el camp Fitxer conté el nom del fitxer "level_1.tscn", que coincideix amb les instruccions de la lliçó per anomenar l'escena del primer nivell en conseqüència, amb una fletxa vermella que connecta visualment el camí amb el nom del fitxer per emfatitzar la seva relació en l'operació de desar.

Ara podeu veure la vostra escena desada dins de la carpeta Escenes al moll del sistema de fitxers.

La imatge mostra el moll del sistema de fitxers de Godot amb l'arrel del projecte "res://" ampliada, destacant la carpeta "Escenes" acabada de crear i el seu fitxer contingut "level_1.tscn", tots dos tancats en un quadre vermell amb una fletxa vermella que apunta al fitxer, que indica que l'escena de nivell 1 s'ha desat correctament dins de la carpeta Escenes tal com s'ha indicat per a una organització de gestió futura correcta.

Amb la nostra estructura de projecte al seu lloc i la nostra escena de primer nivell creada, estem preparats per començar a construir el món del joc. En el següent capítol, començarem a construir l'entorn per al nivell 1 mitjançant TileMaps i fons.

Construccio del mon amb TileMaps

En aquest capítol, ens centrarem a crear l'entorn per al nostre nivell de joc. Un joc de plataformes necessita un terreny on el jugador es mantingui i obstacles per navegar. Per aconseguir-ho de manera eficient, utilitzarem a TileMap.

Un TileMap és essencialment una quadrícula on podeu "pintar" fitxes individuals (com ara herba, terra o pedra), que us permet dissenyar dissenys de nivell complexos ràpidament sense col·locar centenars de nodes de sprite individuals. També afegirem un fons per donar profunditat i ambient a la nostra escena.

Creació d'un TileMapLayer

Per començar, necessitem un node que gestioni la graella de rajoles. A Godot 4, el node recomanat per a això és el TileMapLayer.

Nota de Godot: TileMapLayer vs TileMap

Godot 4 va introduir TileMapLayer com a reemplaçament del node TileMap més antic. Cada TileMapLayer representa una única capa de fitxes, cosa que facilita la gestió de múltiples capes superposades (per exemple, una capa de terra i una capa de decoració). El node TileMap més antic gestionava totes les capes internament, cosa que era menys flexible.

Si veieu tutorials que fan referència a TileMap, és probable que facin servir un flux de treball anterior. Per a projectes nous, utilitzeu sempre TileMapLayer.

Més informació: TileMapLayer (https://docs.godotengine.org/en/4.6/classes/class_tilemaplayer.html)

Comencem afegint aquest node a la nostra escena. En el Escena dock, assegureu-vos que el vostre node principal estigui seleccionat i feu clic a + botó (o premeu Ctrl + A) per afegir un nou node fill.

La imatge destaca el botó "+" al tauler Escena de Godot, que s'utilitza per crear un nou node, concretament, per afegir un TileMapLayer tal com s'indica a la lliçó. Una fletxa vermella assenyala aquest botó, emfatitzant el seu paper a l'hora d'iniciar el procés de configuració del mapa de rajoles. La interfície d'usuari que l'envolta mostra la pestanya "Escena" activa i el node "Principal" que apareix a continuació, indicant que l'usuari està en el pas d'afegir un nou node de capa per començar a pintar fitxes per al nivell de joc.

A la finestra de creació, cerqueu i seleccioneu TileMapLayeri, a continuació, feu clic Crear.

Nota: És possible que vegeu un node simplement anomenat TileMap. Això es considera obsolet a les versions més noves de Godot a favor de TileMapLayer, que ofereix un millor rendiment i flexibilitat. Assegureu-vos de seleccionar TileMapLayer.

Aquesta imatge mostra el diàleg "Crea un node nou" de Godot, on l'usuari ha cercat "mapa de mosaic" i seleccionat el node "TileMapLayer" de la llista de coincidències, un pas necessari per crear un mapa basat en rajoles 2D tal com s'indica a la lliçó. Una fletxa vermella apunta des de l'entrada ressaltada "TileMapLayer" fins al botó "Crea", indicant l'acció per confirmar l'addició d'aquest node. El tauler de descripció següent confirma que és una "Class TileMapLayer < Node2D < CanvasItem" que s'utilitza per als mapes basats en mosaics 2D, reforçant que aquest és el node correcte i no obsolet que s'ha d'utilitzar (a diferència de "TileMap", contra el qual adverteix la lliçó). Aquesta imatge guia l'usuari a través de la selecció i la instanciació del node adequat per començar a pintar fitxes al seu nivell de joc.

Configuració del TileSet

Un TileMapLayer necessita un TileSet recurs per funcionar. El TileSet defineix quines imatges estan disponibles per pintar i com es comporten (per exemple, la seva mida i propietats de col·lisió). Abans de poder pintar qualsevol fitxa, hem de crear aquest recurs i omplir-lo amb el nostre full de sprites.

Crearem aquest recurs al nostre sistema de fitxers per mantenir-lo organitzat. En el Sistema de fitxers dock, navegueu a la carpeta Sprites i, a continuació, obriu la carpeta Tiles. Feu clic amb el botó dret a la carpeta Tiles i seleccioneu Crea nou > Recurs.

Aquesta imatge mostra el tauler FileSystem de Godot amb la carpeta "Tiles" seleccionada; una fletxa vermella apunta des del botó "Crea nou" a l'opció "Recurs..." al seu menú contextual, il·lustrant el pas per crear un nou recurs TileSet per definir els actius de mosaic. El camí de la carpeta "Reds" ressaltat és "res://Sprites/Tiles", i el menú contextual també mostra altres opcions com "Carpeta...", "Escena..." i "Script...", però el focus és seleccionar "Recurs..." per continuar amb la configuració del conjunt de fitxes tal com es descriu a la lliçó.

A la finestra de creació de recursos, cerqueu TileSet i seleccioneu-lo.

A la finestra "Crea un recurs nou" de Godot, l'usuari ha escrit "conjunt de quadres" a la barra de cerca i el recurs "Conjunt de fitxes" que coincideix es ressalta a la secció "Concordances"; una fletxa vermella apunta des d'aquesta selecció fins al botó "Crea" a la part inferior, que indica el següent pas per crear una instancia del recurs TileSet per definir els actius de mosaic utilitzats en un TileMapLayer. El tauler de descripció següent confirma que "Class TileSet" és una biblioteca de fitxes per a un TileMapLayer, reforçant el seu paper en el disseny de nivells basat en fitxes, tal com es descriu a la lliçó.

Anomena el fitxer new_tile_set.tres (o un nom que escolliu) i deseu-lo a la carpeta Tiles.

Aquesta imatge mostra el diàleg "Desa el recurs com a..." de Godot, on l'usuari està desant un recurs TileSet acabat de crear; el camp Path mostra "res://Sprites/Tiles", que indica la carpeta de destinació del conjunt de fitxes, i el camp Fitxer conté el nom del fitxer "new_tile_set.tres", amb una fletxa vermella que apunta des del camí cap avall fins al botó Desa per emfatitzar el pas final de desar el recurs al disc tal com s'indica a la lliçó.

Ara hem d'afegir el nostre full de sprites a aquest TileSet perquè sàpiga quines imatges utilitzar. Feu doble clic al vostre nou fitxer new_tile_set.tres per obrir el fitxer TileSet panell de l'editor a la part inferior de la pantalla. A continuació, arrossegueu el fitxer tiles_packed.png del FileSystem al fitxer Fonts de rajoles secció del panell.

Aquesta imatge il·lustra el pas a Godot en què s'està configurant un recurs de conjunt de fitxes, anomenat "new_tile_set.tres": al panell FileSystem, l'usuari ha seleccionat el fitxer del conjunt de mosaics i la seva textura associada "tiles_packed.png"; una fletxa vermella apunta des del fitxer de textura a la secció "Fonts de rajoles" de l'editor TileSet, indicant que arrossegant el PNG a aquesta àrea l'importarà com a font de rajoles; una altra fletxa vermella apunta a la pestanya "TileSet" a la part inferior de l'editor, confirmant l'espai de treball actiu per a la configuració de les fitxes.

Godot detectarà que esteu important una textura i us preguntarà si voleu crear fitxes automàticament. Feu clic per confirmar. Això tallarà automàticament la imatge en rajoles en funció de la configuració predeterminada.

Després d'afegir una textura de rajoles al conjunt de rajoles, Godot mostra un diàleg titulat "Crear fitxes automàticament en regions de textura no transparent?" informant a l'usuari que "S'ha modificat la textura de l'atles" i preguntant-li si s'han de generar fitxes automàticament a partir de regions no transparents; el botó "Sí" es ressalta amb un quadre vermell, que indica l'acció recomanada per procedir amb l'enrajolament automàtic per crear un mapa eficient.

Alternativament, podeu crear un TileSet directament a l'Inspector seleccionant el node TileMapLayer, fent clic al menú desplegable al costat de Conjunt de rajoles propietat, seleccionant Nou TileSet, i després desar-lo. Tanmateix, crear-lo primer com a fitxer de recursos diferent sovint és més net per a l'organització del projecte.

Aquesta imatge mostra el tauler d'inspector de Godot per a un node TileMapLayer, destacant el menú desplegable de propietats Tile Set, al qual s'accedeix mitjançant el botó de fletxa petit a la seva dreta, que mostra opcions com "New TileSet", "Quick Load...", "Load...", "Edit", "Clear", "Make únic", "Make únic", "Make únic", "Make Asave", "Save", i "Save Asave". "Còpia". Dues fletxes vermelles apunten a aquest menú desplegable: una al botó de fletxa que l'obre i una altra específicament a l'opció "Desa com a...", que il·lustra com desar el recurs del conjunt de fitxes configurat al disc com a part de la configuració de la capa del mapa de fitxes. El camp Conjunt de rajoles està assignat actualment i altres propietats visibles inclouen Forma de rajoles (quadrat), Disseny de rajoles (apilats), Eix de desplaçament de rajoles (Desplaçament horitzontal) i Mida de rajoles (x 16 px, i 16 px).

Ajust de les dimensions dels tiles

Per defecte, Godot suposa que les fitxes són de 16 x 16 píxels. Tanmateix, els actius que estem utilitzant per a aquest projecte són lleugerament més grans (18 x 18 píxels) per tenir en compte l'embalatge o l'estil. Si no ho ajustem, les nostres rajoles es veuran tallades o desalineades.

En el TileSet panell (a la part inferior de la pantalla), localitzeu el Mida de la regió de textura establiment en el Configuració pestanya. Hem de canviar tant l'amplada com l'alçada de 16 a 18.

Aquesta imatge mostra la interfície de l'editor TileSet de Godot, concretament la pestanya "Configuració" on s'ajusten les dimensions de les rajoles: una fletxa vermella apunta als camps "Mida de la regió de textura", que s'estableixen en x = 18 px i y = 18 px, corregint la mida predeterminada de 16 x 16 píxels perquè coincideixi amb les dimensions reals de la textura tal com s'indica a la lliçó. El tauler "Fonts de rajoles" de l'esquerra mostra l'atles de rajoles importat ("tiles_packed.png"), confirmant que la textura està carregada i preparada per utilitzar-la. Aquest pas garanteix que les fitxes s'alineen correctament quan es pinten a TileMapLayer.

També hem de dir al mateix node TileMapLayer que utilitzi aquesta mida de quadrícula. Seleccioneu el TileMapLayer node al moll d'escena. En el Inspector, sota el Conjunt de rajoles propietats dels recursos, assegureu-vos que Mida de rajoles també s'estableix en 18 x 18 píxels.

Al panell Inspector de Godot, s'està configurant el recurs TileSet anomenat "new_tile_set.tres", amb una fletxa vermella que apunta a la propietat "Tile Size" a la secció TileSet; tant les dimensions x com y s'estableixen en 18 px, assegurant que les fitxes coincideixen amb la mida de textura corregida de 18 x 18 píxels tal com s'especifica a la lliçó.

Afegir propietats de col·lisio

Actualment, les nostres rajoles són només imatges visuals. Si col·loquéssim un jugador sobre ells, el jugador cauria directament. Hem d'afegir formes de col·lisió a les fitxes que haurien d'actuar com a sòl sòlid, de manera que el nostre jugador pugui estar a les plataformes i interactuar amb l'entorn.

  1. En el TileSet panell a la part inferior, canvieu a Pintar pestanya.
  2. Hem de seleccionar una propietat per pintar. Feu clic a Seleccioneu un editor de propietats desplegable.
  3. Amplia el Física agrupar i seleccionar Capa de Física 0.

Nota: Si no veieu "Capa de física 0", és possible que primer hàgiu d'afegir una capa de física al vostre recurs TileSet. Podeu fer-ho a l'Inspector seleccionant el recurs TileSet i afegint un element a la matriu "Capes de física".

A l'editor TileSet de Godot, la pestanya "Pintura" està seleccionada per assignar propietats de col·lisió a les fitxes; una fletxa vermella apunta des del botó "Pintar" al menú desplegable "Selecciona un editor de propietats", que s'amplia per mostrar opcions que inclouen "Física", i una altra fletxa destaca "Capa física 0" com a propietat escollida per pintar la col·lisió sobre rajoles, alineant-se amb el pas de la lliçó per afegir capes físiques per a la detecció de rajoles.

Amb la capa de física seleccionada, ara podeu pintar formes de col·lisió a les vostres fitxes:

  1. Premeu F (o seleccioneu l'eina rectangle) per pintar un quadre de col·lisió quadrat complet.
  2. Feu clic a les fitxes de la vista de l'atles (la quadrícula d'imatges) que representen un sòl sòlid (p. ex., herba, terra, pedra).
  3. Veureu una superposició ressaltada a les fitxes que tenen la col·lisió activada.

Si cometeu un error, podeu eliminar la col·lisió d'una fitxa. Feu clic al menú de tres punts de la barra d'eines de pintura, seleccioneu Clari, a continuació, feu clic a la fitxa que voleu arreglar. Per reprendre la pintura, utilitzeu Restableix la forma predeterminada de la rajola opció del mateix menú.

A l'editor TileSet de Godot, amb la pestanya "Pintura" activa, l'usuari està assignant propietats de col·lisió a les fitxes: la secció "Pintura" mostra "Capa física 0" seleccionada al menú desplegable de l'editor de propietats (indicat per la fletxa vermella 2), i actualment es selecciona una rajola de ratlles blaves per pintar (resaltada per la fletxa vermella 1); la font de mosaic "tiles_packed.png" és visible al tauler Fonts de mosaic de l'esquerra, mentre que el costat dret mostra la graella de l'atles de fitxes amb diversos actius del joc, com ara cors, claus i plataformes, preparats per a l'assignació de col·lisions.

Nota de Godot: capes de física i col·lisió

Godot utilitza un sistema de col·lisió basat en capes. Cada cos i àrea física poden pertànyer a una o més "capes" i poden escanejar una o més "màscares". Una col·lisió només es produeix quan la capa d'un objecte se solapa amb la màscara d'un altre objecte. Aquest sistema us permet crear regles complexes, com ara permetre que el jugador passi a través de monedes però xoqui amb les parets, sense escriure codi addicional.

La capa de física 0 que acabem de pintar a les nostres rajoles és la capa predeterminada. Més tard, quan afegim un jugador amb una CollisionShape2D, detectarà automàticament aquestes fitxes com a sòl sòlid.

Més informació: Introducció a la física (https://docs.godotengine.org/en/4.6/tutorials/physics/physics_introduction

.html)

Pintar tiles a l'escena

Amb el nostre TileSet configurat i les propietats de col·lisió al seu lloc, ara podem pintar la geometria del nivell real. Aquí és on el nivell comença a prendre forma visualment.

Seleccioneu el TileMapLayer node al moll d'escena.

Aquesta imatge mostra el panell Escena de Godot amb el node "Principal" ampliat, destacant el nou node "TileMapLayer" afegit, indicat amb un quadre vermell i una fletxa, que serveix com a contenidor per pintar el mapa de fitxes al nivell de joc; aquest node es va crear seguint les instruccions de la lliçó per evitar el node "TileMap" obsolet.

A l'Inspector, assegureu-vos que el vostre new_tile_set.tres estigui assignat a Conjunt de rajoles propietat. Si no és així, arrossegueu el fitxer des del sistema de fitxers a la ranura de propietat.

Al panell Inspector de Godot, el node TileMapLayer està seleccionat i s'està assignant la seva propietat "Tile Set": una fletxa vermella apunta al camp desplegable que mostra "new_tile_set.tres", que indica que aquest recurs TileSet desat s'ha enllaçat a la capa; la icona de la carpeta adjacent suggereix l'opció de navegar o gestionar el fitxer de conjunt de fitxes, mentre que el camí "res://Sprites/Tiles/new_tile_set.tres" confirma la seva ubicació al directori d'actius del projecte, completant la configuració necessària per començar a pintar fitxes al mapa.

Ara, mira el TileMap panell a la part inferior de l'editor. Aquesta és la vostra paleta per col·locar fitxes a l'escena.

Aquesta imatge mostra la interfície de l'editor TileMap de Godot, destacant la barra d'eines de pintura que s'utilitza per col·locar rajoles en una quadrícula: es mostren sis eines: Pintura de mosaic individual (icona de pinzell), línia de pintura (icona de línia), rectangle de pintura (icona rectangle), pinta tota l'àrea (icona d'omplir galleda), comptagotes (icona de comptagotes) i esborrar un mosaic amb la barra d'eines activa (icona de fletxa). quadrícula de tilemap on s'estan disposant rajoles com l'herba i la terra; la pestanya "TileMap" està seleccionada al panell inferior, indicant que l'usuari ara està pintant el disseny de nivell mitjançant el TileSet configurat anteriorment.

Corregir sprites borrosos

Mentre pinteu, és possible que noteu que el vostre pixel art sembla borrós o "taca". Això passa perquè Godot utilitza per defecte el filtratge de textures lineal, que és ideal per a textures 3D d'alta resolució, però dolent per a l'art de píxels nítids. Arreglem-ho perquè les nostres rajoles es mostrin amb vores afilades.

Aquesta imatge mostra la finestra de visualització de l'editor TileMap de Godot amb un zoom del 1586,0%, que mostra una capa de mapa de rajoles 2D parcialment pintada amb rajoles d'art de píxels disposades en bandes horitzontals: les vores de color verd fosc emmarquen una capa d'herba verda brillant per sobre d'una capa de brutícia marró amb taques grogues disperses i una altra secció verda a sota; la superposició de la quadrícula confirma l'alineació de les fitxes i la coordenada (1,1) és visible a la cantonada inferior esquerra, indicant la posició actual de la rajola dins del sistema de coordenades del mapa mentre l'usuari pinta el fons de nivell mitjançant el TileSet configurat.

Per solucionar-ho globalment per al nostre projecte:

  1. Vés a Projecte > Configuració del projecte a la barra de menú superior.

Aquesta imatge mostra la barra de menú superior de Godot amb el menú "Projecte" obert, destacant l'opció "Configuració del projecte...", indicada per un quadre vermell i una fletxa, que s'utilitza per configurar les propietats globals del projecte com ara la resolució de visualització, els mapes d'entrada o la configuració física; aquest pas pot ser rellevant per ajustar la representació del mapa de rajoles o el comportament de col·lisió en el context de la configuració d'un nivell de plataformes 2D.

  1. A la finestra de configuració, aneu a Renderització > Textures.
  2. Troba el Filtre de textura predeterminat configuració.
  3. Canvia-ho de Lineal a Més propera.

Això garanteix que totes les textures del joc es representin amb vores nítides i perfectes amb píxels.

Aquesta imatge mostra la finestra de configuració del projecte de Godot, concretament la secció "Renderització > Textures" a "Textures del llenç", on el "Filtre de textura predeterminat" està configurat a "Més proper", una configuració rellevant per als jocs d'art de píxels per evitar que la textura es difumi; una fletxa vermella destaca aquest menú desplegable i un altre quadre vermell emfatitza la subcategoria "Textures" dins de "Renderització", cosa que indica que aquest pas de configuració pot ser necessari per garantir que els mapes de rajoles es mostrin nítids tal com es pretén a la lliçó.

Dissenya el teu nivell

Ara que totes les eines estan al seu lloc, és hora de crear el vostre disseny de primer nivell. Utilitzeu les eines de pintura que hem configurat per crear plataformes, buits per saltar i parets. No hi ha cap manera correcta o incorrecta de fer-ho. Experimenta amb diferents dissenys i diverteix-te!

Per al nostre exemple, hem creat un terreny senzill amb diferents alçades i plataformes, com es mostra a continuació.

Aquesta imatge mostra un mapa de rajoles 2D a la finestra de visualització de l'editor de Godot, que mostra una disposició horitzontal de rajoles d'art de píxel pintades sobre un TileMapLayer: les rajoles consisteixen en blocs de terra marró amb taques grogues i cims d'herba verda, que varien en alçada per formar plataformes i característiques del terreny; Les línies de quadrícula visibles i els indicadors d'eix (X vermella, Y verda) confirmen que l'escena està en mode 2D, il·lustrant el resultat de la pintura de rajoles mitjançant el recurs TileSet configurat "new_tile_set.tres" amb dimensions de 18x18 píxels i propietats de col·lisió assignades mitjançant Physics Layer 0.

Configuració de fons

Per completar la configuració visual, afegim una imatge de fons perquè el nostre nivell no surti en un buit gris.

  1. En el Sistema de fitxers dock, navegueu a Sprites > Fons.
  2. Cerqueu el fitxer backgroundForest.png (o similar).
  3. Arrossegueu-lo i deixeu-lo anar directament a la vista d'escena.

Al panell del sistema de fitxers de Godot, l'usuari selecciona el fitxer d'imatge de fons "backgroundForest.png" situat a la carpeta "res://Sprites/Backgrounds", ressaltat amb un quadre vermell, per assignar-lo com a teló de fons del nivell; una fletxa vermella puntejada apunta des d'aquest fitxer cap a la finestra 2D de la dreta, indicant que aquest PNG s'utilitzarà com a fons visual per al nivell de joc que s'està construint, seguint l'enfocament de la lliçó en la configuració de mapes i fons de fitxes.

Això crearà un nou node Sprite2D. Al moll Scene, canvieu el nom d'aquest node a BackgroundSprite per mantenir les coses organitzades.

Hem d'assegurar-nos que el fons es col·loca correctament. És possible que hàgiu de moure'l a la jerarquia o ajustar el seu índex Z a l'Inspector si cobreix les vostres fitxes. En general, mantenir-lo com a primer fill de Main (a sobre de TileMapLayer a la llista) garanteix que es renderitza darrere de les fitxes.

Al tauler Escena de Godot, el node "Principal" s'amplia per revelar els seus nodes fills, amb el node "BackgroundSprite" ressaltat per un quadre vermell, que indica que s'ha afegit com a teló de fons visual per al nivell de joc, situat a sobre del node "TileMapLayer" a l'arbre de l'escena per garantir un ordre de representació adequat.

Corregir errors habituals del TileSet

Durant el desenvolupament, podeu trobar errors al depurador relacionats amb l'atles del conjunt de fitxes, específicament advertències sobre les fitxes que estan "fora de la textura". Aquesta secció mostra com resoldre'ls ràpidament.

Aquesta imatge mostra el tauler depurador de Godot centrat en la pestanya "Errors (120)", que mostra missatges d'error en temps d'execució repetits d'un TileSetAtlasSource relacionats amb errors de creació de fitxes a les coordenades (20, 0) i (21, 0); els errors indiquen "create_tile: No es pot crear mosaic. El mosaic està fora de la textura o les fitxes ja estan presents a l'espai que cobriria el mosaic" i "has_alternative_tile: L'atles TileSetAtlasSource no té mosaic a (20, 0)", indicant problemes amb la col·locació de les fitxes o la configuració de l'atles durant la configuració de l'escena, és probable que el quadre de referència es produeixi en el context de configuració de la capa.

Per corregir aquests errors, obriu el vostre recurs TileSet (feu doble clic al fitxer .tres o utilitzeu el tauler inferior). Busqueu qualsevol senyal d'advertència d'exclamació groc al Fonts de rajoles llista.

Aquesta imatge mostra la interfície de l'editor TileSet de Godot, concretament la pestanya "Fonts de rajoles", on es ressalta una icona d'advertència (un signe d'exclamació groc dins d'un cercle vermell) amb una fletxa vermella que apunta cap a ella, que indica un problema amb la configuració de l'atles de rajoles. El tauler de l'Atles mostra l'ID 0 sense cap nom assignat, i el seu camp Textura mostra una miniatura d'un full de sprites; Els marges s'estableixen en x: 0 px i y: 0 px. Aquesta advertència probablement es relaciona amb els errors d'execució mostrats anteriorment sobre les fitxes que es troben fora dels límits de la textura, cosa que suggereix que l'usuari ha d'ajustar l'atles o la col·locació de les fitxes per resoldre les coordenades de les fitxes no vàlides abans de continuar amb el moviment del jugador o el disseny de nivells.

Feu clic als tres punts al costat de l'avís i seleccioneu Traieu les rajoles fora de la textura. També es recomana seleccionar Elimina les rajoles a les regions de textura totalment transparents per netejar l'atles.

Aquesta imatge mostra un menú contextual a l'editor TileSet de Godot, que apareix després de fer clic a una icona d'advertència relacionada amb la configuració de l'atles de rajoles; el menú presenta tres opcions per resoldre problemes de col·locació de rajoles: "Crea rajoles en regions de textura no transparents", "Elimina rajoles en regions de textura totalment transparents" (ressaltat amb un quadre vermell) i "Elimina rajoles fora de la textura", que indica accions correctives per corregir errors on les fitxes es col·loquen fora dels límits de textura vàlids o en àrees transparents.

Felicitats! Has configurat el món amb èxit per al teu joc. Ara tenim un mapa de rajoles sòlid amb col·lisions i un fons escènic. En el següent capítol, donarem vida a aquest món creant el nostre personatge de jugador i implementant controls de moviment.

Creacio de l'escena del jugador

En aquest capítol, configurarem el personatge del jugador, el principal element interactiu del vostre joc. Al final, tindreu una escena del personatge del jugador que està preparada per moure's i saltar dins d'un entorn d'estil de plataformes, juntament amb les configuracions d'entrada necessàries per controlar-la.

Entendre l'escena del jugador

L'escena del jugador és un component crucial del vostre joc, ja que defineix l'objecte físic que controlarà el jugador. Aquesta escena inclourà diversos nodes que determinen l'aparença del jugador, la detecció de col·lisions i altres propietats.

Per començar, hem de determinar el node arrel del nostre reproductor. Per als jocs de plataformes (i els personatges en general), Godot proporciona un node especialitzat anomenat CharacterBody2D. Aquest node és molt útil perquè inclou funcions integrades com ara la detecció de col·lisions, la detecció de terra i la modificació de la velocitat.

Nota de Godot: CharacterBody2D

CharacterBody2D és un cos de física especialitzat dissenyat per a personatges que es mouen mitjançant script. A diferència del RigidBody2D, no reacciona a les forces físiques (com la gravetat) automàticament; cal programar-ne el moviment. Això us proporciona un control precís sobre el comportament del personatge, que és essencial per als jocs de plataformes.

Més informació: CharacterBody2D (https://docs.godotengine.org/en/4.6/classes/class_characterbody2d.html)

Creació del node Player

Ara fem el node arrel del nostre jugador. Al moll de l'escena, creeu un node nou, cerqueu CharacterBody2D i creeu-lo.

La imatge mostra el diàleg "Crea nou node" de Godot amb el terme de cerca "caràcter" introduït, destacant el node "CharacterBody2D" sota la jerarquia Node2D; una fletxa vermella apunta des d'aquesta selecció al botó "Crea" que hi ha a continuació, que indica el pas per crear una instancia d'aquest node de física 2D especialitzat per a personatges controlats per l'usuari. El tauler de descripció confirma que CharacterBody2D està dissenyat per al moviment amb guió i no respon a les forces físiques, sinó que afecta altres cossos, alineant-se amb l'objectiu de la lliçó de configurar un personatge de jugador controlable en un joc de plataformes.

Canvieu el nom del node a "Jugador".

Al panell de l'Escena de Godot, el node "Jugador" (anomenat amb un CharacterBody2D) es ressalta amb un quadre vermell i una fletxa, que indica la seva selecció com a arrel de l'escena del jugador; apareix sota la jerarquia de l'escena "Principal" al costat de "BackgroundSprite" i "TileMapLayer", i mostra una icona d'advertència que suggereix un possible problema de configuració que pot necessitar atenció durant la configuració.

És una bona pràctica desar el reproductor com a fitxer d'escena independent. Això us permet crear una instancia del jugador en diversos nivells sense recrear-lo.

Feu clic amb el botó dret al node i seleccioneu Desa la branca com a escena, o simplement arrossegueu el node a la vostra carpeta Escenes al moll FileSystem.

Aquesta imatge il·lustra com desar l'escena del reproductor a Godot: el node "Reproductor" (un CharacterBody2D) està seleccionat al tauler Escena sota la jerarquia "Principal", i una fletxa vermella puntejada apunta cap avall al tauler FileSystem on s'amplia la carpeta "Escenes"; dins d'ell, es destaca el fitxer "Player.tscn", que indica que el node Player s'ha desat com a fitxer d'escena reutilitzable per al seu ús posterior al joc.

Deseu el fitxer com a player.tscn dins de la vostra carpeta Scenes.

Aquesta imatge mostra el diàleg "Desa la nova escena com a..." de Godot, on l'usuari està desant un fitxer d'escena nou anomenat "player.tscn" al directori "res://Scenes" del projecte; el camp del nom del fitxer es ressalta amb un quadre vermell i una fletxa que apunta cap a ell, mentre que una altra fletxa vermella dirigeix ​​l'atenció des de la barra de ruta cap avall fins al botó "Desa", que també està enquadrat en vermell, indicant el pas final per confirmar el desat de l'escena del reproductor després de crear i configurar el seu node arrel.

Afegir elements visuals

Actualment, el nostre jugador és invisible. Hem d'afegir un sprite perquè el personatge tingui una representació visual al món del joc.

Obriu la vostra nova escena player.tscn (si encara no està oberta). A continuació, arrossegueu un sprite des de la vostra carpeta de sprites (p. ex., character_0000.png) al node Reproductor al moll de l'Escena, o directament a la finestra de visualització de l'editor mentre el node Reproductor està seleccionat.

A l'editor de Godot, el node "Jugador" (un CharacterBody2D) està seleccionat al panell Escena, ressaltat amb un quadre vermell i una fletxa; una fletxa vermella discontínua va des del fitxer "character_0000.png" al tauler FileSystem (situat a res://Sprites/Characters/) fins a la finestra 2D, on la mateixa imatge apareix com una petita icona de sprite etiquetada com "character_0000.png", que indica que l'usuari està arrossegant aquest actiu sprite com a representació visual del personatge a l'escena del reproductor.

Canvieu el nom del nou node de sprite a "Sprite" per a una referència fàcil als nostres scripts més endavant.

Al panell Escena de Godot, el node fill "Sprite" sota el node "Jugador" (un CharacterBody2D) es ressalta amb un quadre vermell i una fletxa, que indica que s'ha afegit per visualitzar el personatge; el nom del node "Sprite" és visible a l'editor, confirmant-ne el canvi de nom com a referència, tal com s'indica a la lliçó.

Hem d'assegurar-nos que el sprite es col·loca correctament en relació al node arrel. En el Inspector, estableix el Posició a (0, 0).

A més, sovint és útil alinear els peus del personatge amb l'origen del node arrel. Això fa que el posicionament del jugador a terra sigui molt més fàcil. A les propietats del sprite, trobeu el Desplaçament secció i establiu el Y valor a un nombre negatiu, com ara -12.

Al panell de l'inspector de Godot, les propietats del node Sprite2D s'estan configurant per alinear l'origen visual del personatge amb els seus peus per a una interacció física precisa: a la secció "Offset", el valor Y s'estableix en -12,0 px (ressaltat en vermell), mentre que l'opció "Centrat" ​​està activada; a més, es mostren els valors de Transformació > Posició (X: 0,0 px, Y: 0,0 px) (també ressaltats en vermell), confirmant que el sprite està centrat en relació al seu node principal CharacterBody2D tal com s'indica per al comportament adequat de col·lisió i moviment al joc de plataformes.

Definici de la fisica

Perquè el jugador xoqui amb plataformes i altres objectes del món, hem de definir la seva forma física. Feu clic amb el botó dret al node Reproductor, seleccioneu Afegeix un node filli trieu CollisionShape2D.

Aquesta imatge mostra el diàleg "Crea nou node" de Godot amb el terme de cerca "collis" introduït, destacant el node "CollisionShape2D" sota la jerarquia Node2D; una fletxa vermella apunta des d'aquesta selecció al botó "Crea" de sota, que indica el pas per afegir una forma de col·lisió 2D al node del reproductor. El tauler de descripció confirma que CollisionShape2D és un node que proporciona un Shape2D a un pare CollisionObject2D, essencial per definir els límits físics del jugador. Això segueix les instruccions del tutorial per fer clic amb el botó dret al node Reproductor i afegir un fill CollisionShape2D, que més tard es configurarà amb un CapsuleShape2D perquè coincideixi amb les dimensions del sprite i garanteixi un moviment suau.

A l'Inspector, localitzeu el Forma propietat. Feu clic al menú desplegable (que actualment diu <buit>) i seleccioneu Nova CapsuleShape2D. Una forma de càpsula és ideal per als personatges perquè la seva part inferior arrodonida permet un moviment suau sobre petits cops o buits al terra.

Al tauler Inspector de Godot, s'està configurant la propietat Shape d'un node CollisionShape2D: el menú desplegable, que actualment mostra "<buit>", s'amplia per mostrar les opcions de forma 2D disponibles, amb "New CapsuleShape2D" ressaltat i seleccionat mitjançant un quadre vermell i una fletxa, que indica el pas per assignar un moviment de col·lisió en forma de càpsula al jugador de col·lisió sense límits.

A la finestra gràfica, veureu la superposició de la forma de col·lisió. Utilitzem les nanses de mida per ajustar la forma de manera que s'ajusti a les dimensions del sprite. Volem que la part inferior de la càpsula toqui la base dels peus del personatge (el punt d'origen).

A la finestra de visualització de l'editor 2D de Godot, un sprite del personatge del jugador d'art de píxels es centra dins d'una forma de col·lisió CapsuleShape2D de color blau verdós, que s'ha afegit com a fill del node Player; el contorn de CollisionShape2D és visible i ajustat per tancar còmodament el cos del personatge mentre toca els seus peus, assegurant una interacció física precisa per a les plataformes; el punt de pivot de la forma es centra a (0,0) i el cursor del ratolí passa per sobre del sprite, indicant l'edició activa o la verificació de l'alineació.

Configuració de la camera

Si juguéssim ara, el jugador podria sortir de la pantalla i desaparèixer. Per mantenir la finestra centrada en el personatge, necessitem una càmera que segueixi el jugador.

Afegiu un node Camera2D com a fill del node Player. Com que és fill del jugador, es mourà automàticament sempre que el jugador es mogui.

Aquesta imatge mostra el diàleg "Crea nou node" de Godot amb el terme de cerca "càmera" introduït, destacant el node "Camera2D" sota la jerarquia Node2D; una fletxa vermella apunta des d'aquesta selecció al botó "Crea" de sota, que indica el pas per crear una instancia d'un node de càmera 2D per seguir el jugador a l'escena. El tauler de descripció confirma que és un "node de càmera per a escenes 2D" que obliga la pantalla a desplaçar-se seguint aquest node, facilitant la programació de les escenes desplaçables. Aquest pas segueix la configuració de l'escena del reproductor i precedeix la configuració de la càmera per seguir el personatge.

Tanmateix, com que el nostre pixel art és petit, la vista de la càmera predeterminada estarà massa lluny. Ajusteu el Zoom propietat a l'inspector a (3, 3). Això augmentarà la càmera un 300%, mantenint l'enfocament ajustat al personatge.

Al panell Inspector de Godot, la propietat Zoom del node Camera2D s'està configurant per seguir el personatge del jugador; tant els valors de zoom X com Y estan establerts a 3.0 (ressaltat amb un quadre vermell), cosa que indica que la càmera escalarà la vista tres vegades més gran que la predeterminada, mentre que les propietats "Ignora la rotació" i "Activada" romanen marcades per garantir un seguiment estable durant el joc.

També és possible que vulgueu col·locar la càmera lleugerament per sobre del reproductor (valor Y negatiu) perquè el jugador pugui veure més l'entorn que hi ha davant i per sobre.

A la finestra de visualització de l'editor 2D de Godot, un personatge de reproductor d'art de píxels (una figura verda amb un casc blanc) es troba centrat en una plataforma de terra amb una part superior d'herba, demostrant el resultat de la configuració de l'escena del jugador; el personatge es col·loca a sobre d'un CollisionShape2D configurat com a CapsuleShape2D que s'alinea amb els seus peus per a una interacció física precisa, i l'escena inclou plataformes addicionals al fons per simular un entorn de plataformes, confirmant que la configuració visual i de col·lisió del jugador s'ha completat abans de la integració de la càmera.

Nota de Godot: Camera2D i seguiment de la vista

Quan un node Camera2D és la càmera activa (la propietat Enabled està marcada), Godot ajusta automàticament la finestra gràfica perquè la posició de la càmera estigui al centre de la pantalla. En fer que la càmera sigui una filla del jugador, la seva posició s'actualitza automàticament cada fotograma sense cap script.

La propietat Zoom funciona com a multiplicador: un valor de (3, 3) significa que cada píxel del món del joc ocupa tres píxels de pantalla, la qual cosa és ideal per a petits sprites d'art de píxels que, d'altra manera, semblarien petits.

Més informació: Càmera 2D (https://docs.godotengine.org/en/4.6/classes/class_camera2d.html)

Afegir nodes d'utilitat

Per preparar futurs capítols on animarem i afegirem so al reproductor, ara afegirem dos nodes més a l'escena del reproductor.

Primer, afegiu un node AnimationPlayer. Això gestionarà les animacions de moviment del personatge (inactiu, córrer, saltar).

Aquesta imatge mostra el diàleg "Crea nou node" de Godot amb el terme de cerca "animació" introduït, destacant el node "AnimationPlayer" sota la jerarquia del node; una fletxa vermella apunta des d'aquesta selecció al botó "Crea" a continuació, que indica el pas per afegir un node AnimationPlayer per gestionar la reproducció d'animacions a l'escena del jugador, tal com es descriu a la progressió de la lliçó després de configurar la física i els elements visuals del personatge.

A continuació, afegiu un node AudioStreamPlayer. Això gestionarà els efectes de so del personatge, com ara saltar o recollir monedes.

Aquesta imatge mostra el diàleg "Crea nou node" de Godot on l'usuari ha escrit "audiostr" a la barra de cerca, destacant el node "AudioStreamPlayer" sota la jerarquia del node; una fletxa vermella apunta des d'aquesta selecció al botó "Crea" a continuació, que indica el pas per crear una instancia d'un node AudioStreamPlayer per a la reproducció d'àudio no posicional, com ara sons d'IU o música de fons, com a part de la configuració dels components auxiliars de l'escena del reproductor.

La vostra escena de jugador ara hauria de tenir cinc nodes secundaris en total, tal com es mostra a continuació.

Al tauler Escena de Godot, el node Player (un CharacterBody2D) s'amplia per mostrar els seus nodes fills: Sprite, CollisionShape2D, Camera2D, AnimationPlayer i AudioStreamPlayer, amb aquest últim destacat per indicar la seva recent incorporació com a component final en la configuració de l'escena del personatge del jugador per a un joc de plataformes, completant l'estructura necessària per a la representació de so, animació i reproducció de càmeres.

Configuració del mapa d'entrada

Abans de submergir-nos en el guió del moviment, els salts i la física del nostre jugador, hem d'establir les nostres entrades. Les entrades defineixen quins botons del vostre teclat, ratolí o controlador realitzen accions específiques al joc.

En lloc d'escoltar tecles específiques com la "fletxa esquerra" o la "barra espaiadora" directament al nostre codi, escoltarem accions abstractes com move_left o jump. Aquest enfocament fa que el nostre script sigui més flexible i més fàcil de gestionar.

Per que fer servir accions d'entrada?

L'ús del mapa d'entrada ofereix diversos avantatges:

Nota de Godot: el mapa d'entrada

El mapa d'entrada de Godot és un mapeig a nivell de projecte entre noms d'accions llegibles pels humans (com move_left) i entrades físiques (com la tecla de fletxa esquerra o

un llapis de joc). En els vostres scripts, només feu referència al nom de l'acció, mai a la clau en brut. Això vol dir que podeu reasignar els controls, afegir compatibilitat amb el gamepad o fins i tot admetre dispositius d'accessibilitat sense tocar ni una sola línia de codi de joc.

Més informació: Mapa d'entrada (https://docs.godotengine.org/en/4.6/classes/class_inputmap.html)

Configuració d'accions

Per accedir al mapa d'entrada, aneu a Projecte al menú superior i seleccioneu Configuració del projecte.

La imatge mostra la interfície del motor Godot amb el menú "Projecte" obert, destacant l'opció "Configuració del projecte...", el primer pas per configurar les accions d'entrada tal com es descriu a la lliçó. Aquesta selecció condueix a la pestanya Mapa d'entrada on es poden definir accions com 'move_left', 'move_right' i 'jump' i assignar-les a tecles com Fletxa esquerra, A, Fletxa dreta, D, Fletxa amunt, barra espaiadora i W, permetent un maneig d'entrada flexible basat en accions sense modificar la lògica de l'script.

A la finestra de configuració del projecte, feu clic a Mapa d'entrada pestanya.

Aquesta imatge mostra la finestra de configuració del projecte de Godot Engine, destacant específicament la pestanya "Mapa d'entrada", la interfície on es configuren accions d'entrada com "move_left", "move_right" i "jump". La pestanya es selecciona dins del tauler de configuració de "project.godot", indicant que l'usuari es troba a la ubicació correcta per definir i assignar entrades de teclat o controlador a accions amb nom, tal com es descriu a la lliçó per abstraure la lògica d'entrada dels scripts de joc.

Ara podem crear les nostres accions personalitzades. En el Afegeix una acció nova camp, escriviu un nom per a la vostra acció (p. ex., move_left) i premeu Intro (o feu clic a Afegeix).

Aquesta imatge mostra la finestra de configuració del projecte del motor Godot per a "project.godot", amb la pestanya "Mapa d'entrada" activa, destacant el botó "Afegeix una acció nova", un pas clau per definir accions d'entrada com "move_left" o "jump", tal com es descriu a la lliçó. El quadre vermell i la fletxa emfatitzen aquest botó, que els usuaris fan clic per començar a crear noves accions amb nom que abstreguin les entrades del teclat o del controlador de la lògica de l'script, permetent una configuració d'entrada flexible i mantenible.

Repetiu això per a les altres accions que necessitem. Creeu accions anomenades move_left, move_right i jump.

Aquesta imatge mostra la finestra de configuració del projecte del motor Godot per a "project.godot", amb la pestanya "Mapa d'entrada" activa, que mostra un camp de text on s'ha introduït el nom de l'acció d'entrada "move_left", que il·lustra el pas per definir una acció d'entrada amb nom abans d'assignar-hi tecles, com a part de la configuració de controls flexibles del jugador.

Assignacio de tecles

Ara hem d'assignar claus físiques a aquestes accions abstractes perquè el jugador les pugui utilitzar. A la fila de move_left, feu clic a + icona (més) al costat dret.

Aquesta imatge mostra la finestra de configuració del projecte del motor Godot per a "project.godot", amb la pestanya "Mapa d'entrada" activa, mostrant l'acció creada recentment "move_left" a la llista. Una fletxa i un quadre vermells destaquen el botó més (+) al costat dret de la fila "move_left"; aquest és el control utilitzat per assignar tecles d'entrada (com la fletxa esquerra o A) a l'acció, tal com es descriu a la lliçó per mapejar controls sense codificar tecles específiques en scripts. El valor de Deadzone de 0,2 també és visible al costat del nom de l'acció, que indica una configuració de sensibilitat configurable per a les entrades analògiques.

Això obre la finestra de configuració de l'esdeveniment. Podeu cercar una tecla manualment o simplement prémer la tecla del teclat mentre la finestra està oberta.

Aquesta imatge mostra el diàleg "Configuració d'esdeveniments per 'move_left'" del motor Godot, que apareix després de fer clic al botó més per assignar una entrada a l'acció "move_left". El diàleg mostra un camp "Escoltant l'entrada", que indica que el sistema està preparat per capturar una entrada de tecla o de controlador. A continuació, a "Entrades de filtre", les categories ampliables inclouen "Tecles del teclat", "Botons del ratolí", "Botons del Joypad" i "Eixos del Joypad", que permeten a l'usuari assignar l'acció a dispositius d'entrada específics, cosa que s'alinea amb l'èmfasi de la lliçó en l'abstracció dels mètodes d'entrada per a controls de jugador flexibles i que es puguin mantenir.

Premeu el botó Fletxa esquerra tecla i, a continuació, feu clic D'acord per confirmar l'encàrrec.

Aquesta imatge mostra el diàleg "Configuració d'esdeveniment per a 'move_left'" a Godot Engine, on l'usuari està assignant una clau física a l'acció d'entrada. El camp de cerca de la part superior mostra "Esquerra o Esquerra (física) o Esquerra (Unicode)", i la llista filtrada següent destaca l'entrada de la tecla "Esquerra", que indica la selecció de la tecla de fletxa esquerra. Un quadre vermell i una fletxa emfatitzen aquesta selecció, mentre que un altre quadre vermell destaca el botó "D'acord" a la part inferior, que confirma l'assignació. A sota de la llista de tecles, les "Opcions addicionals" mostren les caselles de verificació modificadores (Alt, Maj, Ctrl, etc.), cap seleccionada i una nota diu "Codi de tecles físic (posició al teclat QWERTY dels EUA)", que reforça que el mapatge es basa en la posició de la tecla física en lloc de la sortida del caràcter. Aquest pas finalitza l'enllaç de la tecla de fletxa esquerra amb l'acció "move_left" com a part de la configuració d'un maneig d'entrada flexible basat en accions.

Repetiu aquest procés per afegir claus alternatives (com ara WASD) i configurar les altres accions. Una configuració habitual per als jocs de plataformes és:

Aquesta imatge mostra la finestra de configuració del projecte del motor Godot per a "project.godot", concretament la pestanya Mapa d'entrada, que mostra tres accions d'entrada configurades: "move_left" assignat a les tecles de fletxa esquerra i A, "move_right" assignat a les tecles de fletxa dreta i D, i "saltar" assignat a fletxa amunt, barra espaiadora i tecla W, cada una de les tecles il·lustrades com a tecles d'entrada múltiples, cada una il·lustrada com a tecla d'entrada. mateixa acció abstracta per a un control flexible del jugador.

Amb la nostra escena de jugador construïda i el nostre mapa d'entrada configurat, hem establert les bases per a la interactivitat. En el següent capítol, crearem el guió del jugador i donarem vida al nostre personatge amb la lògica de moviment.

Implementació del moviment del jugador

En el capítol anterior, vam crear la nostra escena de jugador i vam configurar el mapa d'entrada. Tanmateix, el nostre personatge actualment és només una imatge estàtica amb forma de col·lisió; no pot moure's, saltar o interactuar amb el món.

En aquest capítol, donarem vida al nostre personatge escrivint el guió del jugador. Implementarem el moviment horitzontal, aplicarem la gravetat, afegirem mecàniques de salt i suavitzarem els controls per donar una sensació polida al joc. Finalment, ens assegurarem que el personatge s'enfronti visualment a la direcció del moviment.

Configuracio de l'script del jugador

Per començar, hem d'adjuntar un script al nostre node de reproductor. Aquest script contindrà tota la lògica per llegir les entrades i aplicar forces físiques.

Obriu la vostra escena player.tscn i seleccioneu el node arrel CharacterBody2D (anomenat Player).

La imatge mostra el tauler Godot Engine Scene amb el node "Player" (un CharacterBody2D) seleccionat, ressaltat per un quadre vermell i una fletxa, que indica que és l'objectiu per adjuntar l'script del reproductor tal com es descriu a la lliçó. L'arbre de nodes que hi ha a sota inclou els nodes Sprite, CollisionShape2D, Camera2D, AnimationPlayer i AudioStreamPlayer, tots fills de Player. Aquest pas de selecció precedeix la creació i l'adjunció de l'script player.gd per implementar la funcionalitat de moviment i salt mitjançant variables com move_speed, gravity i jump_force, i la funció _physics_process per a actualitzacions físiques coherents.

Amb el node seleccionat, feu clic a Nou guió icona a la part inferior de l'Inspector (el desplaçament amb un signe més verd). Alternativament, podeu fer clic amb el botó dret al node i seleccionar-lo Adjunta script.

La imatge mostra el tauler Godot Engine Inspector per a un node seleccionat, amb la propietat "Script" ressaltada, actualment configurada com a buida, i un quadre vermell que emfatitza el botó "Nou Script..." que es fa clic amb el cursor del ratolí, indicant el pas per crear un nou script per al node Player tal com s'indica a la lliçó. Aquesta acció inicia el procés d'adjuntar un script anomenat player.gd al node CharacterBody2D, que més tard contindrà variables com move_speed, acceleration, gravity, jump_force i move_input, juntament amb la funció _physics_process per gestionar el moviment i la física.

Al diàleg de creació de l'script, assegureu-vos que l'idioma està configurat en GDScript i que l'script hereta de CharacterBody2D. Establiu el camí a res://Scripts/player.gd per mantenir el nostre projecte organitzat.

Aquesta imatge mostra el diàleg "Adjuntar script del node" a Godot Engine, on s'està configurant un script nou per al node del reproductor; l'idioma està configurat com a GDScript, hereta de CharacterBody2D i el camp Path mostra "res://Scripts/player.gd", indicant que l'script es desarà com a player.gd a la carpeta Scripts, confirmat pels missatges de validació verd "El nom del camí de l'script és vàlid". i "Crearà un fitxer d'script nou". Una fletxa vermella assenyala el botó "Crea" ressaltat, que finalitza la creació de l'script tal com s'indica a la lliçó.

Feu clic Crear per generar el fitxer i obrir l'editor d'scripts.

Definici de variables de moviment

El nostre guió de jugador necessita diverses variables per controlar com es mou el personatge. En definir-los a la part superior del nostre guió, podem modificar fàcilment la "sensació" del joc més tard sense reescriure la lògica.

Utilitzarem la paraula clau @export per a aquestes variables. Això els exposa a l'Inspector, cosa que ens permet ajustar valors com la velocitat i l'alçada de salt directament a l'editor mentre el joc s'executa.

Substituïm el contingut de l'script predeterminat per la configuració següent:

extends 
CharacterBody2D
@export 
var 
move_speed : float = 100 @export 
var 
acceleration : float = 50 @export 
var 
braking : float = 20 @export 
var 
gravity : float = 500 @export 
var 
jump_force : float = 200
var 
move_input : float

Això és el que controla cada variable:

Implementació bàsica del moviment

Godot proporciona una funció integrada anomenada _physics_process per gestionar càlculs físics. A diferència de _process, que executa cada fotograma (temps variable), _physics_process s'executa a una velocitat fixa (per defecte 60 vegades per segon).

Això garanteix que el moviment i les col·lisions siguin constants independentment de la velocitat de fotogrames de l'ordinador.

Nota de Godot: _procés_físic vs _procés

Godot ofereix dues devolucions de trucada per fotograma. _process(delta) s'executa una vegada per fotograma representat, de manera que la seva velocitat varia amb el rendiment de l'ordinador.

_physics_process(delta) runs at a fixed interval (60 times per second by default), making it ideal for movement, collision detection, and anything that relies on consistent timing.

Com a regla general, poseu la lògica relacionada amb la física (velocitat, forces, difusió de raigs)

_processa_física i posa una lògica només visual (animacions, actualitzacions d'interfície d'usuari, efectes de càmera) al _procés.

Més informació: processament inactiu i físic (https://docs.godotengine.org/en/4.6/tutorials/scripting/idle_and_physics_ processing.html)

Començarem implementant el moviment bàsic esquerra i dreta amb el codi següent:

func 
_physics_process(delta):

move_input = Input.get_axis("move_left", "move_right") velocity.x = move_input * move_speed

move_and_slide()

Anem a trencar aquesta lògica:

  1. Tractament d'entrada: Input.get_axis("move_left", "move_right") comprova les dues accions que hem definit al mapa d'entrada. Retorna -1 si es prem "move_left", 1 si es prem "move_right" i 0 si no es prem cap (o tots dos).
  2. Assignació de velocitat: establim la velocitat horitzontal (velocity.x) multiplicant la direcció d'entrada pel nostre move_speed.
  3. Aplicació del moviment: move_and_slide() és una funció especial per a CharacterBody2D. Mou el cos en funció de la seva propietat de velocitat actual i gestiona automàticament les col·lisions amb parets i sòls.

Aplicacio de la gravetat

Si executeu el joc ara, notareu un problema: el personatge pot moure's cap a l'esquerra i la dreta, però suren a l'aire si surt d'una plataforma.

Aquesta imatge mostra la vista del joc Godot Engine 2D durant la depuració, que mostra un personatge verd d'un jugador amb pixel-art a l'aire entre dues plataformes de terra sobre un fons nevat amb arbres estilitzats; l'escena confirma visualment la capacitat del jugador per moure's i saltar tal com s'implementa a l'script player.gd, que defineix variables com move_speed, gravity i jump_force, i utilitza _physics_process amb Input.get_axis per gestionar el moviment horitzontal i move_and_slide per al moviment basat en la física.

Per solucionar-ho, hem d'aplicar la gravetat a la velocitat vertical (velocity.y) sempre que el jugador no estigui a terra.

Actualitzeu la vostra funció _physics_process per incloure la gravetat:

func 
_physics_process(delta):
# Apply gravity only when airborne
if not 
is_on_floor():

velocity.y += gravity * delta

move_input = Input.get_axis("move_left", "move_right") velocity.x = move_input * move_speed

move_and_slide()

La funció is_on_floor() és un mètode integrat que retorna true si el caràcter es troba en un objecte de col·lisió. Si torna fals, afegim el nostre valor de gravetat (multiplicat per delta per a la consistència del temps) a la velocitat vertical, fent que el jugador s'acceleri cap avall.

Ara, si proveu el joc, el vostre personatge hauria de caure si no es troba en una de les fitxes del sòl.

Aquesta imatge mostra la vista del joc Godot Engine 2D durant la depuració, que mostra un personatge verd d'art de píxels a l'aire entre dues plataformes horitzontals de terra amb cims d'herba, sobre un fons nevat amb arbres blaus estilitzats; l'escena confirma visualment la implementació reeixida de la mecànica de moviment i salt a partir de l'script player.gd, tal com es descriu a la lliçó, amb el jugador posicionat entre plataformes per demostrar la gravetat i la física dels salts.

Implementació del salt

Un joc de plataformes no està complet sense la capacitat de saltar. Hem de comprovar l'entrada de salt i assegurar-nos que el jugador pot saltar (és a dir, que està a terra).

Afegirem aquesta lògica a la nostra funció _physics_process.

  1. Comproveu l'entrada i l'estat: Utilitzem Input.is_action_pressed("saltar") per veure si el botó està premut i is_on_floor() per assegurar-nos que el jugador no estigui ja a l'aire.
  2. Aplicar força: En el sistema de coordenades 2D de Godot, "amunt" és la direcció Y negativa. Per saltar, posem la velocitat.y en un valor negatiu

(-força_salt).

Aquí teniu el codi actualitzat:

func 
_physics_process(delta):
# Apply gravity only when airborne
if not 
is_on_floor():

velocity.y += gravity * delta

move_input = Input.get_axis("move_left", "move_right") velocity.x = move_input * move_speed

# Only allow jumping while grounded
if 
Input.is_action_pressed("jump") 
and 
is_on_floor(): velocity.y = -jump_force

move_and_slide()

El teu personatge ara pot saltar per sobre de buits i obstacles.

Aquesta imatge mostra el joc de plataformes Godot 2D en mode de depuració, mostrant un petit personatge verd pixelat a l'aire sobre diverses plataformes terrestres, il·lustrant la funcionalitat de salt que s'ensenya a la lliçó; l'escena inclou arbres blaus estilitzats al fons i la barra d'eines superior de l'editor amb indicadors de mode "Entrada", "2D" i "3D" visibles, confirmant el context d'implementació de la mecànica de salt mitjançant _physics_process on velocity.y s'estableix en un valor negatiu quan Input.is_action_pressed("jump") i is_on_floor() són true.

Suavitzar el moviment

Actualment, el nostre moviment és molt rígid. El personatge arriba a tota velocitat a l'instant quan es prem una tecla i s'atura a l'instant quan es deixa anar. Per fer que el moviment se senti més natural i pesat, podem utilitzar Interpolació lineal (sovint anomenat lerp).

Lerp ens permet fer una transició suau d'un valor d'un punt inicial a un punt final al llarg del temps. L'utilitzarem per augmentar gradualment la velocitat (acceleració) i disminuir-la (frenada/fricció).

Substituïu l'assignació de velocitat directa.x per la lògica següent:

# Smoothly accelerate toward target speed, or brake to a stop
if 
move_input != 0:

velocity.x = lerp(velocity.x, move_input * move_speed, acceleration * delta)

else:

velocity.x = lerp(velocity.x, 0.0, braking * delta)

Si el jugador està prement una tecla (move_input != 0), lerpem la velocitat actual cap a la velocitat objectiu utilitzant el valor d'acceleració. Si no es prem cap tecla, anem la velocitat cap a 0,0 utilitzant el valor de frenada.

Aquí teniu la funció completa _physics_process amb suavització aplicada:

func 
_physics_process(delta):
# Apply gravity only when airborne
if not 
is_on_floor():

velocity.y += gravity * delta

move_input = Input.get_axis("move_left", "move_right")

# Smoothly accelerate toward target speed, or brake to a stop
if 
move_input != 0:

velocity.x = lerp(velocity.x, move_input * move_speed, acceleration * delta)

else:

velocity.x = lerp(velocity.x, 0.0, braking * delta)

# Only allow jumping while grounded
if 
Input.is_action_pressed("jump") 
and 
is_on_floor(): velocity.y = -jump_force

move_and_slide()

Nota de Godot: interpolació lineal (lerp)

lerp significa "interpolació lineal". Donat un valor inicial, un valor final i un pes entre 0 i 1, retorna un punt proporcionalment entre ells.

Quan es diu cada fotograma amb delta com a part del pes, el resultat es mou ràpidament al principi i s'alenteix a mesura que s'acosta a l'objectiu, produint l'efecte d'acceleració i frenada suau que acabem d'implementar.

Godot proporciona lerp per a valors generals, lerpf per a flotadors específicament i

Vector2.lerp / Vector3.lerp per a vectors.

Més informació: Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. (https://docs.godotengine.org/en/4.6/classes/class_@globalscope.html#class

-globalscope-method-lerp)

Visuals: inverteix el sprite

Tenim moviment funcional, però visualment, el personatge sempre mira a la mateixa direcció (normalment a la dreta). Quan es mou a l'esquerra, el personatge sembla que està caminant per la lluna. Hem de capgirar el sprite horitzontalment en funció de la direcció del moviment.

Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know.

La imatge mostra el tauler de propietats del node Sprite2D del motor Godot, destacant la casella de selecció "Flip H" a la secció Offset, que controla la inversió horitzontal del sprite. Aquesta configuració és directament rellevant per a l'objectiu de la lliçó de capgirar dinàmicament el sprite del jugador en funció de la direcció del moviment; el fragment de codi proporcionat a la lliçó (sprite.flip_h = velocity.x > 0) canvia programadament aquesta propietat a cada fotograma per assegurar-se que l'sprite s'enfronta a la direcció del moviment. Actualment, la casella de selecció no està marcada ("On" no està seleccionada), cosa que indica que l'esprit no està capgirat horitzontalment per defecte en aquesta vista.

Primer, necessitem una referència al node Sprite al nostre script. Let’s add the following line at the top of our script, just below extends CharacterBody2D:

@onready 
var 
sprite : Sprite2D = $Sprite

La paraula clau @onready assegura que Godot espera fins que el node estigui completament carregat abans d'assignar-lo a la variable.

A continuació, gestionarem les actualitzacions visuals. Mentre que els càlculs físics pertanyen

_procés_físic, sovint es gestionen actualitzacions visuals, com ara el gir de sprites

_procés, que executa cada fotograma.

Ara afegim una funció _process al nostre script:

func 
_process(delta):
# Flip the sprite to face the direction of movement
if 
velocity.x != 0:

sprite.flip_h = velocity.x > 0

Aquest codi verifica si el jugador es mou (velocity.x != 0). Si ho són, es posa

flip_h en funció de la direcció:

Nota: Depenent de la direcció original del vostre sprite, potser haureu d'invertir aquesta lògica (p. ex., velocity.x < 0). Si el vostre sprite mira cap a la dreta de manera predeterminada, flip_h hauria de ser false quan es mou a la dreta i true quan es mou a l'esquerra.

Torna a provar el joc. El vostre personatge hauria d'enfrontar-se ara a la direcció en què va.

Aquesta imatge mostra l'editor de Godot Engine executant una escena de plataformes en 2D en mode de depuració, titulada "Godot2DPlatformerCourse (DEBUG)", amb el personatge del jugador (un petit sprite verd amb un casc blanc) flotant a l'aire sobre plataformes terrestres amb pixel-art sobre un fons de bosc blau clar; l'escena mostra visualment el resultat d'implementar la lògica de capgirament de sprite basada en la velocitat, tal com es descriu a la lliçó, on l'orientació de l'esprit s'ha d'ajustar dinàmicament per fer front a la direcció del moviment, encara que no hi ha cap codi o script visible en aquesta vista.

En aquest capítol, hem creat amb èxit la mecànica de moviment bàsica per al nostre joc de plataformes. El nostre jugador pot córrer, saltar i interactuar amb la gravetat, i els controls són suaus i sensibles. In the next chapter, we will enhance the visuals further by setting up the AnimationPlayer to switch between idle, running, and jumping animations.

Sistema d'animaci del jugador

En aquest capítol, configurarem animacions per al nostre personatge jugador. Les animacions són les que donen vida a un personatge del joc: donen al jugador comentaris visuals per a accions com córrer, quedar-se quiet i saltar. Ens centrarem a crear tres animacions essencials (inactiu, moure i saltar) i després escriure la lògica del guió per canviar entre elles en funció del que està fent el jugador.

Entendre les animacions a Godot

A Godot, una animació és essencialment una línia de temps que comença des de 0 segons i acaba amb una durada especificada. Al llarg d'aquesta línia de temps, podeu afegir fotogrames clau que canvien les propietats del vostre sprite o qualsevol altre node. Per al nostre jugador, animarem la propietat de textura del node Sprite2D per alternar entre diferents imatges de sprite al llarg del temps.

Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know.

AnimationPlayer is one of Godot’s most versatile nodes. Pot animar pràcticament qualsevol propietat de qualsevol node de l'arbre de l'escena, no només textures. Podríeu animar la posició d'un node per crear escenes de tall, el seu color modular per fer una cosa intermitent, o fins i tot un paràmetre d'ombra per als efectes visuals. Cada propietat que animeu té la seva pròpia "pista" a la línia de temps i es poden executar diverses pistes simultàniament dins d'una sola animació.

La pista RESET que habilitem més endavant és una pràctica recomanada: emmagatzema el valor predeterminat de cada propietat animada perquè Godot pugui restaurar els nodes al seu estat original quan s'atura l'animació.

Més informació: Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. (https://docs.godotengine.org/en/4.6/classes/class_animationplayer.html)

Configuracio de l'AnimationPlayer

Abans de poder crear animacions, necessitem un node per gestionar-les. El node AnimationPlayer s'encarrega d'emmagatzemar i reproduir totes les animacions d'una escena, així que assegurem-nos que el jugador en tingui un.

Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. node com a fill de l'arrel del reproductor. Si ho heu afegit al capítol anterior, simplement seleccioneu-lo. Si no, afegiu-ne un ara.

La imatge mostra l'arbre d'escenes de l'editor Godot amb el node "Jugador" ampliat, destacant el node "AnimationPlayer" seleccionat i delineat en vermell, amb una fletxa vermella apuntant-hi, indicant la seva importància a l'hora de configurar animacions de personatges tal com es descriu a la lliçó. Aquest node és essencial per crear i gestionar animacions com ara inactiu, moure's i saltar afegint fotogrames clau a propietats com ara la textura de Sprite al llarg del temps. Els nodes que l'envolten (Sprite, CollisionShape2D, Camera2D) proporcionen context per a l'estructura del reproductor, però l'objectiu és seleccionar l'AnimationPlayer per accedir a la línia de temps de l'animació i començar a configurar pistes i fotogrames clau.

Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. Animació apareixerà a la part inferior de l'editor. Aquí és on construirem les nostres línies de temps.

Aquesta imatge mostra la interfície de l'editor d'animació de Godot a la part inferior de l'editor, amb la pestanya "Animació" activa i seleccionada, que indica que l'usuari està configurant animacions per a un personatge. La línia de temps és visible però buida, amb l'hora actual establerta en 0,0 segons i el camp de durada també mostra 0,0, cosa que suggereix que encara no s'ha creat ni configurat cap animació. Els elements clau de la interfície d'usuari rellevants per a la lliçó inclouen la pestanya "Animació" (resaltada), la visualització de l'hora, el menú desplegable "Segons" i el control lliscant de zoom (icona de lupa) que s'utilitza per ajustar la precisió de la línia de temps. L'indicador de versió "4.4.beta2" apareix a la cantonada inferior dreta, confirmant la versió Godot que s'està utilitzant. Aquesta vista correspon al pas en què l'usuari està a punt de crear la primera animació ("inactiva") fent clic a "Animació > Nou", tal com es descriu a la lliçó.

Creació d'animació inactiva

L'animació inactiva es reprodueix quan el jugador està parat. És l'estat visual predeterminat que fonamenta el vostre personatge al món, així que primer creem-lo.

A la finestra d'animació, feu clic a Animació botó i seleccioneu Nou.

Aquesta imatge mostra la finestra d'animació de l'editor Godot amb un menú contextual obert sota el menú desplegable "Animació", destacant l'opció "Nou...", que s'utilitza per crear un nou clip d'animació tal com s'indica a la lliçó. Una fletxa vermella assenyala aquest menú, emfatitzant l'acció d'iniciar una animació nova (p. ex., "inactiva") per al personatge del jugador. La línia de temps mostra 0,0 segons, que indica el punt de partida per a la creació de fotogrames clau, i les pestanyes inferiors confirmen que la pestanya "Animació" està activa, alineant-se amb l'enfocament del tutorial a configurar animacions mitjançant el node AnimationPlayer.

Anomena l'animació inactiva i fes clic a D'acord.

Aquesta imatge mostra el diàleg "Crea una animació nova" a Godot, on l'usuari anomena un nou clip d'animació; el camp de text conté el nom "idle", que coincideix amb les instruccions de la lliçó per crear una animació inactiva per al personatge del jugador. A sota del camp d'entrada hi ha els botons "D'acord" i "Cancel·la", utilitzats per confirmar o descartar la creació de l'animació. Aquest pas segueix seleccionant "Animació > Nou" al menú, tal com es mostra a la imatge anterior, i precedeix la configuració de la durada de l'animació i l'addició de pistes de textura tal com es descriu al tutorial.

De manera predeterminada, les animacions estan configurades per durar un segon. Per a una postura inactiva senzilla, volem que sigui més curta. Feu clic al camp de durada a prop de la part superior dreta de la línia de temps (que actualment diu 1,0) i canvieu el valor a 0,5.

També podeu ampliar la línia de temps utilitzant el control lliscant de la part inferior dreta per treballar en increments més petits.

Aquesta imatge mostra l'editor d'animació de Godot amb l'animació "inactiva" seleccionada, mostrant una línia de temps de 0,0 a 1,0 segons; una fletxa vermella assenyala el camp de durada a la part superior dreta, que actualment diu "1,0", que indica la durada de l'animació predeterminada que s'ha de canviar a 0,5 segons tal com s'indica a la lliçó. A la part inferior dreta, el control lliscant del zoom està ressaltat amb un quadre vermell i el cursor passant per sobre, il·lustrant com ajustar la vista de la línia de temps per a un control més fi quan s'afegeixen fotogrames clau, un pas necessari abans d'animar la propietat de textura de Sprite per a l'estat inactiu.

Amb la durada establerta, verifiqueu que la línia de temps reflecteixi la nova durada.

Aquesta imatge mostra l'editor d'animació de Godot amb l'animació "inactiva" seleccionada, ressaltant el camp de durada a la part superior dreta de la línia de temps, que s'ha canviat del valor predeterminat d'1,0 a 0,5 segons, tal com s'indica a la lliçó per escurçar la durada de l'animació inactiva. Una fletxa vermella apunta directament a aquest valor actualitzat, posant èmfasi en l'ajust necessari per a la configuració d'animació del personatge del jugador. La línia de temps següent abasta de 0,0 a 2,2 segons i l'indicador de temps actual es troba a 0,0, a punt per a la col·locació de fotogrames clau. El tauler inferior confirma que la pestanya "Animació" està activa i la sortida mostra les pestanyes "Depurador (1)" i "Àudio" al costat, indicant el context de l'edició de l'animació a l'editor Godot.

Afegir la pista de textura

Per animar una propietat, hem de crear-hi una "pista". Una pista indica a AnimationPlayer quina propietat ha de canviar i quins valors ha d'utilitzar en cada punt de la línia de temps.

Mantingueu oberta la finestra d'animació i seleccioneu el vostre Sprite node al moll d'escena. En el Inspector, localitza el Textura propietat. Veureu una petita icona de clau al costat. Feu clic a aquesta icona de clau per crear la pista.

Al tauler Godot Inspector, la propietat Textura del node Sprite2D està seleccionada, amb una fletxa vermella que apunta al botó del fotograma clau (una petita icona de diamant) al costat, que indica el pas per crear una pista d'animació per a la propietat de textura com a part de la configuració de l'animació inactiva; la secció Offset a continuació mostra X establert a 0,0 px i Y configurat a 12,0 px, amb Centrat activat, que són paràmetres de posicionament de sprites no relacionats amb la configuració de l'animació actual però visibles en context.

Apareixerà un diàleg de confirmació. Assegureu-vos Crea pistes de RESTABLECIMENT està habilitat i feu clic Crear.

Aquesta imatge mostra el diàleg "Confirmeu..." de Godot que apareix després de fer clic al botó de fotograma clau de la propietat Texture de Sprite2D, demanant a l'usuari que creï una pista nova per animar la propietat "textura"; inclou una casella de selecció amb l'etiqueta "Crea pista(s) de RESTABILITZACIÓ" (que està marcada) i dos botons: "Crea" (ressaltat amb un quadre vermell i una fletxa) i "Cancel·la", amb el text d'instrucció a sobre que indica "Mantén premuda la tecla Maj en fer clic a la icona de la tecla per saltar aquest diàleg".

Ara hauríeu de veure una pista nova per a la propietat de textura de Sprite a la línia de temps d'animació.

Aquesta imatge mostra l'editor d'animació de Godot amb l'animació "inactiva" activa, mostrant una línia de temps de 0,0 a 2,2 segons; destacada en un quadre vermell hi ha la pista d'animació creada recentment per a la propietat "textura" del node Sprite, que indica que la textura s'animarà amb el temps. Aquesta pista s'ha afegit fent clic al botó de fotograma clau que hi ha al costat de la propietat Texture a l'Inspector i confirmant la creació de la pista amb RESET activat, tal com s'indica a la lliçó per començar a animar fotogrames de sprite per a l'estat inactiu.

Configuració de fotogrames clau

Quan vam crear la pista, Godot va afegir automàticament un fotograma clau a la posició actual del temps (0,0 segons) utilitzant la textura de sprite actual.

Aquesta imatge mostra el tauler d'inspector de Godot centrat en una entrada d'AnimationTrackKeyEdit per a l'animació "inactiva", mostrant un fotograma clau a Time 0.0 amb el valor configurat en una icona de sprite d'art de píxel (probablement el fotograma inactiu) i Easing configurat a 1.00, indicant que s'ha afegit el primer fotograma clau per animar la propietat de la textura a l'inici de l'inactivitat, com a part de l'inici de la textura. animació.

Per a una animació estàtica inactiva (on el personatge només es queda quiet), aquest fotograma clau únic és realment tot el que necessitem. L'animació simplement mantindrà aquesta textura durant tot el temps. Podeu provar-ho mitjançant els controls de reproducció de la finestra d'animació.

Aquesta imatge mostra l'editor d'animació de Godot amb l'animació "inactiva" seleccionada, destacant la barra de control de reproducció a la part superior de la línia de temps, amb botons per a rebobinar, reproduir, pausa, avançar ràpid i aturar, utilitzats per previsualitzar les animacions; a continuació, la pista de "textura" del node Sprite és visible a la línia de temps, cosa que indica que la propietat de textura ara està animada i preparada per a la col·locació de fotogrames clau per definir l'estat inactiu.

Escolteu les pistes de RESET

Quan vam crear la nostra primera pista, vam habilitar el Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. opció de pista. Aquesta és una animació especial que Godot crea automàticament per ajudar a gestionar les vostres propietats animades.

Aquesta imatge destaca el botó "RESET" a l'editor d'animació de Godot, situat dins dels controls de pista per a la propietat de textura del node Sprite sota l'animació "inactiva"; el botó presenta una icona de fletxa circular i s'etiqueta "RESET", que indica la seva funció per restablir o esborrar els valors dels fotogrames clau per a aquesta pista, una característica activada en crear la pista mitjançant la casella de selecció "Crea RESTABILITZAR pistes" tal com s'ha indicat anteriorment.

Creació d'animació en moviment

Amb l'animació inactiva al seu lloc, creem l'animació per quan el personatge estigui en execució. Aquesta animació passarà a través de dos fotogrames alterns per donar l'aparença de moviment.

Feu clic a Animació > Nou de nou.

Aquesta imatge mostra la interfície de l'editor d'animació de Godot, destacant el menú desplegable "Animació" (delineat en vermell) i una fletxa vermella que apunta al camp de durada a la part superior de la línia de temps, que actualment mostra "0.0", que indica l'inici de la línia de temps d'animació on s'afegiran fotogrames clau per a la propietat de textura del node Sprite, com a part de la configuració de les animacions del personatge del jugador.

Anomena aquest moviment d'animació.

Aquesta imatge mostra el diàleg "Crea una animació nova" de Godot, on l'usuari anomena un nou clip d'animació; el camp de text conté el nom "mou", que indica la creació de la segona animació (després de "inactiva") com a part de la configuració de les animacions dels personatges del jugador. A sota del camp d'entrada hi ha els botons "D'acord" i "Cancel·la" per confirmar o descartar l'acció, alineant-se amb les instruccions de la lliçó per crear tres animacions essencials: inactiu, en moviment i en salt.

Igual que abans, afegiu una pista per al Textura propietat fent clic a la icona de clau a l'Inspector mentre el node Sprite està seleccionat.

Al tauler Godot Inspector, es mostra la propietat Texture del node Sprite2D amb la seva icona de sprite assignada actualment; una fletxa vermella assenyala el botó de fotograma clau (icona en forma de diamant) al costat del camp Textura, que indica el pas per afegir un fotograma clau per animar aquesta propietat com a part de la configuració de l'animació de moviment. A continuació, la secció Desplaçament mostra els valors centrat a Activat i Desplaçament a x: 0,0 px, y: 12,0 px, que no estan directament implicats en l'animació de textura, però proporcionen context per al posicionament de l'esprit. Aquesta acció crea una pista d'animació que permet canviar entre els sprites al llarg del temps, essencial per definir animacions basades en fotogrames com ara inactiu, en moviment o en salt.

Afegir fotogrames de moviment

Per a l'animació de moviment, volem que el personatge alterni entre els sprites "cames amunt" i "cames avall" per simular la carrera. Configurarem dos fotogrames clau, cadascun amb un marc de sprite diferent.

  1. Primer fotograma clau: seleccioneu el fotograma clau a 0,0 segons. A l'Inspector (a les propietats del fotograma clau), arrossegueu l'esprit on les cames del personatge estiguin cap amunt (p. ex., character_0001.png) al Valor ranura.

Aquesta imatge il·lustra el procés d'assignació d'un fotograma de sprite específic a un fotograma clau d'animació a Godot: a l'esquerra, el panell FileSystem mostra el fitxer "character_0001.png" seleccionat a "res://Sprites/Characters/", mentre que l'editor d'animació mostra la pista de textura del node Sprite amb un fotograma clau a 0,0 segons; una fletxa vermella apunta des del fitxer seleccionat al camp de valor del fotograma clau a l'Inspector, que mostra una previsualització de l'esprit de caràcters de pixel-art verd, que indica que aquest fotograma s'està configurant com a primer fotograma clau per a l'animació.

  1. Segon fotograma clau: moveu el cursor de la línia de temps aproximadament a la meitat de l'animació. Feu clic amb el botó dret a la pista i seleccioneu Insereix la clau.

A l'editor d'animació de Godot, amb l'animació "mou" seleccionada i la línia de temps mostrant un temps actual de 0,4 segons (ressaltat per un quadre vermell), l'usuari ha fet clic amb el botó dret a la pista de textura del node Sprite per obrir un menú contextual; l'opció "Insereix clau..." es ressalta amb un cursor, indicant que el següent pas és afegir un fotograma clau en aquest punt de la línia de temps per animar la textura del sprite per a l'estat en moviment.

  1. Assigna texturaError 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. Valor propietat a l'inspector.

Aquesta imatge mostra el tauler de l'inspector de Godot centrat en una entrada d'AnimationTrackKeyEdit per a l'animació "moure", amb el camp Temps establert a 0,4333 segons; ressaltat en un quadre vermell hi ha el camp Valor, que mostra una icona de sprite d'art de píxels (probablement representa un fotograma específic de l'animació), que indica la textura assignada a aquest fotograma clau en aquest moment. Això segueix les instruccions de la lliçó per afegir i configurar fotogrames clau al llarg de la línia de temps de l'animació per controlar els canvis de sprite.

Bucle i temporitzacio

Una animació en execució s'ha de repetir contínuament mentre el jugador es mou, de manera que hem d'habilitar el bucle i augmentar el temps.

Activeu el bucle fent clic a Bucle icona (fletxes que formen un cercle) al final dels controls de la línia de temps.

A l'editor d'animació de Godot, amb l'animació "mou" activa i la línia de temps mostrant una durada d'1,0 segons (ressaltat per una fletxa vermella), l'usuari està a punt d'ajustar la durada de l'animació; la icona d'actualització circular a l'extrem superior dret de la línia de temps (tancada en un quadre vermell) s'utilitza per alternar el bucle per a l'animació, alineant-se amb l'enfocament de la lliçó a configurar les propietats de l'animació, com ara la durada i els fotogrames clau per a la textura del sprite del personatge del jugador.

La durada predeterminada d'1 segon és massa lenta per a un cicle d'execució. Canvieu la durada de l'animació a 0,25 segons per obtenir una sensació més ràpida.

A l'editor d'animació de Godot, l'animació "mou" està activa, amb la seva durada de la línia de temps establerta en 0,25 segons com es mostra al camp de durada ressaltat a la part superior dreta de la línia de temps, un valor ajustat des del valor predeterminat per escurçar la durada de l'animació; una fletxa vermella apunta directament a aquest camp per emfatitzar el canvi, mentre que la pista de "textura" del node Sprite és visible a continuació, indicant que els fotogrames clau de la propietat de la textura s'animaran durant aquesta durada reduïda per crear l'animació de moviment per al personatge del jugador.

Quan reduïu la durada, el vostre segon fotograma clau pot acabar fora de la línia de temps visible. Amplieu i arrossegueu el segon fotograma clau perquè quedi aproximadament al mig de la nova durada (al voltant de 0,1 o 0,12 segons).

A l'editor d'animació de Godot, l'animació "mou" està activa amb una durada de 0,25 segons que es mostra al camp superior dret; la línia de temps abasta de 0,0 a 0,25, mostrant un únic fotograma clau a 0,1 segons a la pista de "textura" del node Sprite, que indica que s'ha establert el primer fotograma de l'animació en moviment. Això segueix les instruccions de la lliçó per crear i configurar l'animació de moviment ajustant la durada i afegint fotogrames clau de textura.

Reprodueix l'animació per assegurar-te que les cames del personatge s'alternen ràpidament.

Creació de l'animació de salt

Finalment, creem l'animació de salt. A diferència de l'animació de moviment, aquesta serà una posició estàtica única que es mostra mentre el personatge està a l'aire, de manera que només necessita un fotograma clau.

  1. Feu clic Animació > Nou i anomena-li salt.

La imatge mostra el menú contextual del node AnimationPlayer de l'editor de Godot, amb el menú desplegable "Animació" ressaltat i una fletxa vermella apuntant a l'opció "Nou...", que indica el pas per crear una animació nova com a part de la configuració de l'animació de salt del jugador; això s'alinea amb la instrucció de la lliçó per fer clic a "Animació > Nou" per començar a crear la pista d'animació de "salt".

La imatge mostra el diàleg "Crea una animació nova" a Godot, on l'usuari ha escrit "saltar" al camp "Nom de l'animació nova" per anomenar la nova animació tal com s'indica a la lliçó; aquest pas segueix la selecció de "Nou..." al menú contextual de l'AnimationPlayer i precedeix l'addició de fotogrames clau per a l'animació de salt.

  1. Afegiu la pista de textura fent clic a la icona de la clau a la propietat Texture de Sprite.

Aquesta imatge mostra el panell Inspector de l'editor Godot per a un node Sprite2D, on l'usuari està afegint un fotograma clau per animar la propietat Texture. Si feu clic a la icona de la clau al costat del camp Textura, s'activa un diàleg "Confirmeu..." que demana "Crear una pista nova per a la propietat "textura" i inserir la clau?", amb el botó "Crea" ressaltat amb una fletxa vermella, que indica el pas per establir una pista d'animació per canviar la textura de l'esprit durant l'animació de salt tal com es descriu a la lliçó.

  1. Seleccioneu el fotograma clau a 0,0 segons. A l'Inspector, assigneu el sprite amb les cames completament esteses o a l'aire (p. ex., character_0001.png o un marc de salt dedicat si en teniu un).

Aquesta imatge mostra el tauler d'inspector de l'editor Godot centrat en un AnimationTrackKeyEdit, on el camp "Time" s'estableix a 0,0 per al primer fotograma clau de l'animació de salt; A continuació es destaquen els controls de valors que inclouen una icona de vista prèvia de sprite (que mostra un caràcter verd amb les cames a l'aire) i un botó de fitxer/carpeta, utilitzat per assignar la textura de fotograma correcta per a l'animació de salt com a part de la configuració dels estats d'animació del jugador.

Ara hauríeu de tenir tres animacions diferents a la vostra llista: inactiu, moure i

saltar.

La imatge mostra la interfície del node AnimationPlayer de l'editor Godot, on el menú desplegable "Animació" està obert i mostra una llista d'animacions: "RESET", "inactiu", "salta" i "mou". L'animació de "salt" està seleccionada actualment, indicada per un ressaltat blau i un cercle ple al costat, mentre el cursor del ratolí passa per sobre de l'animació de "mou". Això reflecteix el pas de la lliçó de verificar que les tres animacions necessàries (inactiu, salt i moviment) estan creades correctament i estan disponibles per utilitzar-les en la lògica d'animació basada en l'estat del personatge del jugador.

Programació lògica d'animació

Ja tenim les nostres animacions preparades, però el joc no sap quan jugar a cadascuna. En aquesta secció, actualitzarem el nostre script player.gd perquè l'animació correcta es reprodueixi automàticament en funció del que faci el jugador: dempeus, córrer o saltar.

Obriu l'script player.gd. Primer, necessitem una referència al node AnimationPlayer perquè el nostre codi pugui dir-li quina animació reproduir. Afegiu aquesta variable a la part superior del vostre script, juntament amb les vostres altres variables:

@onready 
var 
anim : AnimationPlayer = $AnimationPlayer

A continuació, creem una funció dedicada per gestionar la selecció d'animacions. Mantenir aquesta lògica en la seva pròpia funció fa que el codi sigui més fàcil de llegir i mantenir. Afegiu la funció següent al vostre script:

# Select the correct animation based on the player's current state
func 
_manage_animation(): 
if not 
is_on_floor(): anim.play("jump") 
elif 
move_input != 0: anim.play("move")

else:

anim.play("idle")

Aquesta lògica verifica l'estat del jugador en un ordre específic de prioritat:

  1. Aerotransportat: Si el jugador no està a terra (no is_on_floor()), està saltant o caient. Juguem l'animació del "salt".
  2. En moviment: Si el jugador està al terra i proporciona entrada (move_input

!= 0), reproduïm l'animació "moveu".

  1. Inactiu: Si cap de les coses anteriors és certa (el jugador està a terra i no es mou), reproduïm l'animació "inactiva".

Finalment, hem d'anomenar aquesta funció cada fotograma perquè l'animació es mantingui sincronitzada amb les accions del jugador. Actualitzeu la vostra funció _process per incloure la lògica d'inversions de sprite i la crida a _manage_animation():

func 
_process(delta):
# Flip the sprite to face the direction of movement
if 
velocity.x != 0:

sprite.flip_h = velocity.x > 0

_manage_animation()

Provar el joc

Ara és el moment de veure la nostra feina en acció. Torneu a l'escena del vostre nivell i premeu el botó Jugar botó. Amb les tres animacions connectades, el personatge hauria de respondre visualment a cada canvi d'estat.

Quan el jugador està parat, s'ha de reproduir l'animació inactiva.

Aquesta imatge mostra un personatge d'un jugador d'art de píxels (una figura verda amb un casc blanc) inactiu sobre un bloc de terra marró amb una part superior d'herba, sobre un fons de cel blau clar; representa visualment l'estat d'animació "inactiu" descrit a la lliçó, que es reprodueix quan el jugador està al terra i no es mou, tal com determina la funció _manage_animation a player.gd que verifica is_on_floor() i move_input per activar animacions "idle", "move" o "jump" mitjançant el node AnimationPlayer referenciat com a $AnimationPlayer.

Quan camines a l'esquerra o a la dreta, el personatge hauria de canviar a l'animació en curs.

Aquesta imatge mostra el personatge del jugador d'art de píxels (una figura verda amb un casc blanc) inactiu sobre un bloc de terra marró amb una part superior d'herba, sobre un fons de cel blau clar, que representa visualment l'estat d'animació "inactiu" tal com es descriu a la lliçó; aquesta és l'animació predeterminada que es reprodueix quan el jugador està a terra i no es mou, segons el govern de la funció _manage_animation que comprova si is_on_floor() i move_input == 0 abans de jugar "inactiu".

Quan saltes, el personatge hauria de canviar a la postura del salt mentre estàs a l'aire.

Aquesta imatge mostra el personatge del jugador d'art de píxels (una figura verda amb un casc blanc) flotant a l'aire sobre un bloc de terra marró amb herba, sobre un fons de cel blau clar, demostrant visualment l'estat d'animació de "salt" tal com es descriu a la lliçó; això correspon a la lògica del codi on anim.play("jump") s'activa quan no is_on_floor(), confirmant que l'animació es reprodueix correctament durant les fases de salt o caiguda.

Si tot funciona correctament, el vostre personatge de jugador hauria de fer una transició perfecta entre els estats, afegint una capa important de poliment al vostre joc.

En el següent capítol, passarem del personatge del jugador i començarem a implementar la IA enemiga per afegir desafiaments al nostre nivell.

Creacio d'enemics

En un joc de plataformes, els nivells estàtics només poden oferir tants reptes. Perquè el joc sigui més atractiu i dinàmic, hem d'introduir amenaces actives que obliguin el jugador a mantenir-se alerta. En aquest capítol, crearem el nostre primer personatge enemic: un ratpenat que patrulla una zona concreta.

Implementarem un patró de moviment d'anada i tornada i establirem un sistema de detecció perquè l'enemic sàpiga quan ha colpejat el jugador. Tot i que encara no implementarem la lògica de danys completa, establirem les bases essencials detectant col·lisions i identificant el jugador mitjançant el sistema de grups de Godot.

Configuracio de l'escena de l'enemic

Començarem per construir l'escena enemiga. A diferència del Player, que utilitza un CharacterBody2D per al moviment basat en la física (manejar la gravetat i les col·lisions), el nostre enemic utilitzarà un Area2D com a node arrel.

Un Area2D és perfecte per a aquest propòsit perquè detecta solapaments sense bloquejar físicament el moviment. Això permet que el jugador passi "a través" de l'enemic (fer danys en el procés) en lloc de colpejar una paret invisible a l'aire.

Nota de Godot: Area2D vs cossos físics

Godot ofereix tres tipus principals de nodes físics per a 2D, cadascun adequat per a un paper diferent:

CharacterBody2D es mou completament pel vostre codi. És l'opció preferida per als personatges dels jugadors i els NPC on necessiteu un control total sobre el moviment.

RigidBody2D està impulsat pel motor físic. Utilitzeu-lo per a objectes que haurien de respondre automàticament a la gravetat, les col·lisions i les forces (com ara caixes o boles que reboten).

Àrea 2D no participa en absolut de la física. Només detecta solapaments amb altres objectes. Això el fa ideal per a activadors, col·leccionables i enemics que haurien de detectar el jugador sense bloquejar el moviment.

Més informació: Àrea 2D (https://docs.godotengine.org/en/4.6/classes/class_area2d.html)

Creacio dels nodes

Amb el tipus d'escena decidit, anem a construir l'arbre de nodes que constituirà l'enemic. Necessitem un sprite per a la visualització, una forma de col·lisió per a la detecció de superposició i un reproductor d'animació per a l'efecte de bateig.

Primer creem una nova escena i seleccionem Àrea 2D com a node arrel.

La imatge mostra el diàleg "Crea un nou node" a Godot Engine, on l'usuari ha escrit "area2d" a la barra de cerca; el node "Area2D" està ressaltat a Coincidències, amb una fletxa vermella que apunta al botó "Crea" de sota, indicant que el següent pas és crear una instancia d'aquest node. El tauler de descripció confirma que Area2D és una regió de l'espai 2D que detecta altres CollisionObject2D que entren o surten, cosa que s'alinea amb l'objectiu de la lliçó de crear un enemic que detecti les col·lisions dels jugadors sense bloqueig físic. Aquest pas visual correspon a la creació del node arrel de l'enemic tal com es descriu al tutorial.

Canvieu el nom d'aquest node a Enemy.

A l'arbre de l'escena del Motor Godot, el node "Enemic", ressaltat amb un quadre vermell i assenyalat per una fletxa vermella, està seleccionat sota l'escena "Principal"; és un node Area2D (indicat per la seva icona) i mostra un triangle d'advertència groc, que suggereix un problema d'script o de configuració. Aquest node es va crear com a arrel per al personatge enemic, tal com es descriu a la lliçó, i s'escripturarà per moure's d'anada i tornada mentre es detecten col·lisions amb el jugador sense bloquejar-los físicament. Els nodes circumdants ("BackgroundSprite", "TileMapLayer", "Player") proporcionen context per a la jerarquia de l'escena.

A continuació, necessitem una representació visual del nostre enemic. En el Sistema de fitxers dock, navegueu a Sprites > Personatges i trobeu l'esprit ratpenat (p. ex., character_0024.png).

Al moll del sistema de fitxers del motor Godot, l'usuari està navegant per la carpeta "res://Sprites/Characters" per seleccionar un sprite per al personatge enemic; el fitxer "character_0024.png" està ressaltat amb un quadre vermell i assenyalat per una fletxa vermella, que indica que és l'esprit de ratpenat que s'ha d'arrossegar al node enemic tal com es descriu a la lliçó.

Arrossegueu el ratpenat sprite al node Enemy al moll de l'escena i, a continuació, canvieu el nom del nou node fill a Sprite.

A l'editor de Godot Engine, el moll de l'Escena mostra el node "Enemic" (un Area2D) seleccionat a l'escena "Principal", amb el seu node "Sprite" fill ressaltat en un quadre vermell i assenyalat per una fletxa vermella; el node Sprite mostra un caràcter de ratpenat pixelat a la finestra 2D, que indica que s'ha arrossegat correctament des de la carpeta "res://Sprites/Characters" del sistema de fitxers i s'ha situat a (0, 0), tal com s'indica a la lliçó per a l'alineació correcta.

Per assegurar-vos que el sprite estigui alineat correctament amb el node arrel, configureu-lo Posició a (0, 0) a l'Inspector.

Al tauler Godot Engine Inspector, es mostren les propietats de transformació del node Sprite2D amb la seva Posició establerta a (0,0 px, 0,0 px), ressaltada amb un quadre vermell i una fletxa per emfatitzar el restabliment de la posició del sprite a l'origen per a una alineació adequada dins del node Enemic; aquest pas segueix l'addició de l'esprit ratpenat com a fill del node Area2D i precedeix la configuració de components de col·lisió i animació per al moviment enemic.

Ara hem de definir l'àrea on l'enemic pot detectar el jugador. Per fer-ho, feu clic amb el botó dret al node Enemic i afegiu un node fill del tipus CollisionShape2D.

Al diàleg "Crea nou node" del motor Godot, l'usuari ha escrit "collis" a la barra de cerca i el node "CollisionShape2D" es ressalta a Coincidències amb un quadre vermell i una fletxa que l'apunten; a continuació, la seva descripció diu "Un node que proporciona un Shape2D a un pare CollisionObject2D" i una fletxa vermella dirigeix ​​l'atenció al botó "Crea", que indica que el següent pas és afegir aquest node com a fill al node Enemic per definir el seu límit de col·lisió.

Aquesta forma determina la regió que desencadena els esdeveniments de superposició. A l'Inspector, configureu el Forma propietat a Nova CircleShape2D.

Al panell Godot Engine Inspector, s'està configurant la propietat Shape d'un node CollisionShape2D; el menú desplegable, ressaltat amb un quadre vermell i una fletxa, mostra "<buida>" com a selecció actual, i l'usuari l'ha ampliat per revelar les opcions de forma 2D disponibles, amb "New CircleShape2D" seleccionat i emfatitzat per un quadre vermell i una fletxa. Aquest pas estableix la forma de col·lisió del col·lisionador del node enemic en un cercle, tal com es requereix per detectar col·lisions de jugadors mentre permeten el pas.

A la finestra gràfica, ajusteu la mida del cercle perquè s'adapti a l'esprit ratpenat. Sovint és un bon disseny del joc per fer que el hitbox sigui lleugerament més petit que el sprite visual; això dóna al jugador una mica de marge a l'hora d'esquivar i fa que el joc se senti més just.

Aquesta imatge mostra l'esprit del personatge enemic completat (un ratpenat pixelat amb una forma de col·lisió circular verde verda superposada) situat dins de la finestra 2D del motor Godot, confirmant la configuració correcta del node enemic com a Area2D amb un fill Sprite i una CollisionShape2D configurada com a cercle; aquesta imatge representa la culminació d'afegir l'esprit ratpenat (character_0024.png), centrar-lo a (0,0) i assignar el col·lisionador circular per permetre la detecció de col·lisions sense bloqueig físic, tal com es descriu a la lliçó per crear un enemic que es mou d'anada i tornada i danya el jugador en contacte.

Finalment, afegiu un Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. node com a fill del node Enemic. Ho farem servir més endavant per animar les ales del ratpenat.

Al diàleg "Crea nou node" del motor Godot, l'usuari ha escrit "animació" a la barra de cerca i el node "AnimationPlayer" està ressaltat a Coincidències amb un quadre vermell i una fletxa que hi apunta; a continuació, la seva descripció diu "Un node que s'utilitza per a la reproducció d'animacions. S'utilitza un reproductor d'animacions per a la reproducció d'animacions de propòsit general. Conté un diccionari de recursos d'AnimationLibrary i temps de combinació personalitzats entre les transicions d'animació", i una fletxa vermella dirigeix ​​l'atenció al botó "Crea", que indica que el següent pas és afegir aquest node com a nen al node d'animació enemic per activar la funció.

Ara el vostre arbre d'escenes hauria de semblar a la imatge següent, amb el node arrel Enemy que conté Sprite, CollisionShape2D i AnimationPlayer.

Aquesta imatge mostra el moll de l'escena del motor Godot, que mostra la jerarquia de nodes completada per al personatge enemic a l'escena principal: el node arrel de l'enemic (un Area2D) conté tres nodes secundaris: Sprite (per a la visualització del ratpenat), CollisionShape2D (configurat com a cercle per a la detecció de col·lisions) i AnimationPlayer (per activar animacions). El node Enemic es ressalta amb un quadre vermell, emfatitzant la seva estructura com a base per al moviment enemic i la lògica de col·lisió, tal com es descriu a la lliçó.

Programacio del moviment de l'enemic

Amb l'escena muntada, ara podem donar vida al ratpenat amb un guió. L'objectiu és fer que l'enemic es mogui d'anada i tornada entre una posició inicial i una posició objectiu, creant un bucle de patrulla senzill que el jugador haurà d'esquivar.

Adjuntem un script nou al node Enemic. Anomeneu-lo enemy.gd i deseu-lo a la vostra carpeta Scripts.

Aquesta imatge mostra el diàleg "Adjuntar script de node" a Godot Engine, on s'està configurant un nou script per a un node Area2D: el camp "Hereta" s'estableix a "Area2D", el camp "Camí" mostra "res://Scripts/enemy.gd" i el botó "Crea" està ressaltat, indicant que l'usuari està a punt de generar l'script que es descriu a la lliçó.

Necessitem unes quantes variables per controlar el moviment. En exportar move_direction, podem establir la ruta de patrulla directament a l'editor per a cada instància enemiga individual, de manera que és fàcil reutilitzar la mateixa escena amb diferents rutes de patrulla.

També necessitem variables per emmagatzemar la velocitat de l'enemic, així com els dos punts de patrulla que farem servir.

Afegiu les variables següents al vostre script:

extends 
Area2D
@export 
var 
move_direction : Vector2 @export 
var 
move_speed : float = 20
@onready 
var 
start_pos : Vector2 = global_position
@onready 
var 
target_pos : Vector2 = global_position + move_direction

Ara implementem la lògica del moviment en _physics_process. Utilitzarem el mètode move_toward, que mou sense problemes un valor (la nostra posició) cap a un objectiu en una quantitat específica (la nostra velocitat).

Afegiu el codi següent:

func 
_physics_process(delta):
# Move steadily toward the current target position

global_position = global_position.move_toward(target_pos, move_speed

* delta)

# When the enemy arrives, swap the target to create a patrol loop
if 
global_position == target_pos:
if 
target_pos == start_pos:

target_pos = start_pos + move_direction else:

target_pos = start_pos

Així és com funciona aquesta lògica:

  1. Mou-te: a cada fotograma, la posició_global de l'enemic es mou

target_pos a la velocitat de moviment definida.

  1. Comproveu l'arribada: Comprovem si l'enemic ha arribat a l'objectiu (posició_global == target_pos).
  2. Canvia d'objectiu: Si l'enemic és a l'objectiu, comprovem si aquest objectiu era l'inici o el final del camí, després l'intercanviem al punt oposat, creant un bucle continu.

Provar el moviment

Vegem-ho en acció. Col·loca una instància de la teva escena de l'enemic a l'escena del nivell principal i situa l'enemic on vulguis que comenci.

En una escena de joc en 2D d'art de píxels, un personatge d'astronauta verd es troba sobre una plataforma de terra amb herba a la part superior, mentre un petit sprite enemic de ratpenat flota a l'aire entre dues plataformes, indicant el seu camí de patrulla d'anada i tornada; la fletxa del cursor apunta cap al ratpenat, cosa que suggereix la interacció del jugador o la configuració del moviment de l'enemic tal com es descriu a la lliçó per crear un enemic basat en Area2D que detecti col·lisions sense bloqueig físic, utilitzant una CollisionShape2D circular i un AnimationPlayer per al moviment.

A l'Inspector, establiu move_direction a (0, -50). Això diu a l'enemic que es mogui 50 píxels cap amunt des de la seva posició inicial i després cap avall.

Al panell Godot Engine Inspector, es mostren les propietats de l'script del node "Enemic", destacant la variable exportada `move_direction` del fitxer de script `enemy.gd`, que s'estableix en un Vector2 amb x = 0,0 i y = -50,0, que indica un moviment cap avall; a sota, la propietat "move_speed" s'estableix en 20.0, que defineix la rapidesa amb què es mou l'enemic, mentre que les propietats Monitoring i Monitorable del node Area2D estan habilitades (On), garantint la detecció de col·lisions per al càlcul de danys quan el jugador interactua amb l'enemic.

Premeu Reproduir. Hauríeu de veure el ratpenat volant amunt i avall en bucle.

En una escena de joc en 2D d'art de píxels, un personatge d'astronauta verd es troba a la plataforma de terra esquerra mentre un petit sprite enemic de ratpenat flota a l'aire entre dues plataformes, il·lustrant el seu camí de patrulla d'anada i tornada; la fletxa del cursor apunta cap al ratpenat, indicant la interacció del jugador o el comportament del moviment de l'enemic tal com es defineix a l'script enemy.gd amb variables exportades com move_direction i move_speed per al moviment controlat.

Detectar el jugador

Ara que l'enemic es mou, ha de ser perillós. Volem detectar quan el jugador toca l'enemic per tal que finalment puguem fer mal. Com que el nostre node arrel és un Area2D, podem utilitzar els senyals integrats de Godot per escoltar les superposicions.

Per configurar-ho, seleccioneu el node Enemic i aneu a Node moll (al costat de l'Inspector). Trobeu el senyal body_entered. Aquest senyal es dispara cada cop que un cos físic (com el nostre Player's CharacterBody2D) entra a la zona.

La imatge mostra el tauler Node de Godot amb la pestanya "Señals" seleccionada per a un node Area2D, destacant el senyal body_entered (body: Node2D), que s'activa quan un cos físic entra a l'àrea, com a objectiu per a la connexió a la configuració de detecció de col·lisions enemigas. El context de la lliçó explica que aquest senyal es connectarà a un mètode d'script _on_body_entered(body) que comprova si el cos que entra pertany al grup "Jugador" abans de fer dany. La interfície d'usuari mostra altres senyals relacionats com area_entered i body_shape_entered, però el focus se centra en body_entered com a esdeveniment clau per detectar col·lisions de jugadors.

Feu doble clic a body_entered per obrir el diàleg de connexió i, a continuació, connecteu-lo al vostre script enemy.gd.

Aquesta imatge mostra el diàleg "Connecta un senyal a un mètode" de Godot, on el senyal body_entered(body: Node2D) del node Enemy (un Area2D) s'està connectant al seu propi script; el camp Mètode del receptor mostra _on_body_entered i es ressalta el botó Connectar, que indica el pas final per establir la connexió del senyal per a la detecció de col·lisions, alineant-se amb l'objectiu de la lliçó de provocar danys quan el jugador entra al col·lisionador de l'enemic.

Això crea una funció anomenada _on_body_entered al vostre script. Hem d'assegurar-nos que el cos que va entrar a la zona és realment el jugador i no una paret o un altre objecte.

Actualitzeu la funció amb el codi següent:

func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return

print("Deal damage to player")

Us dels grups

El codi anterior comprova si el cos està en un grup anomenat "Jugador". Tanmateix, encara no hem assignat el nostre jugador a aquest grup. Els grups són la manera de Godot d'etiquetar els nodes perquè pugueu identificar-los en codi sense dependre de noms o camins de nodes específics.

Arreglem això. Obriu la vostra escena player.tscn i seleccioneu l'arrel Jugador node. En el Node moll, canvia a Grups pestanya i, a continuació, feu clic a + icona per crear un grup nou. Anomeneu-lo "Reproductor" i feu clic D'acord.

Aquesta imatge mostra el panell Node de Godot amb la pestanya "Grups" seleccionada, destacant la interfície per assignar un node a un grup, concretament el botó més (+) utilitzat per crear un nou grup, que és essencial per etiquetar el node del jugador perquè l'script de col·lisió de l'enemic pugui identificar-lo mitjançant body.is_in_group("Player"); el tauler també mostra les seccions "Grups d'escenes" i "Grups globals" sota la pestanya Grups activa, indicant on apareixeran els grups assignats.Aquesta imatge mostra el diàleg "Crea un grup nou" de Godot, on l'usuari està assignant el node Jugador a un grup anomenat "Jugador"; el camp Nom conté "Jugador", un missatge de validació verd confirma que "El nom del grup és vàlid.", i el botó D'acord es ressalta amb un cursor, que indica el pas final per confirmar l'addició del jugador a aquest grup perquè l'script _on_body_entered de l'enemic pugui identificar-lo mitjançant body.is_in_group ("Jugador").

Ara, sempre que el jugador xoqui amb l'enemic, el guió reconeixerà el grup "Jugador" i executarà el codi.

Nota de Godot: grups per a la identificació de nodes

Els grups a Godot funcionen com etiquetes. Qualsevol node pot pertànyer a diversos grups, i podeu comprovar la pertinença amb is_in_group ("nom") o recuperar tots els nodes d'un grup amb get_tree().get_nodes_in_group ("nom"). Els grups són una manera lleugera d'identificar nodes sense tipus de ruta o tipus de codificació, la qual cosa manté el vostre codi flexible i reutilitzable.

Més informació: Grups (https://docs.godotengine.org/en/4.6/tutorials/scripting/groups.html)

Provar la col·lisio

Amb el senyal connectat i el grup assignat, comprovem que tot funciona. Torna a executar el joc i mou el teu jugador al camí de l'enemic. Quan xoquen, comproveu Sortida panell a la part inferior de l'editor. Hauríeu de veure el missatge "Fes dany al jugador".

La imatge mostra la consola de sortida de Godot Engine mostrant dues línies de text: "infligir danys al jugador" repetida dues vegades, confirmant que el senyal _on_body_entered de l'enemic ha detectat correctament el jugador i ha executat la lògica de dany del marcador de posició. La capçalera de la consola indica la versió del motor (Godot Engine v4.4.beta2.official) i el backend de renderització (Vulkan 1.3.280 - Forward+). A la vista del joc, una escena d'art de píxels inclou un bloc de terra amb herba a la part superior i siluetes d'arbres blaus febles al fons; una petita icona a l'extrem superior dret sembla que representa el jugador o el node enemic, d'acord amb la prova de detecció de col·lisions tal com es descriu a la lliçó.

Animar l'enemic

El moviment de patrulla funciona, igual que la nostra detecció de col·lisions, però el ratpenat encara sembla estàtic mentre llisca pel seu camí. Per donar-li vida, afegim una animació de bateig perquè les seves ales batguin mentre vola.

Primer, seleccioneu el Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know. node a l'escena de l'enemic.

Al tauler Node de Godot, els components secundaris del node enemic es mostren en un arbre jeràrquic: Sprite, CollisionShape2D i AnimationPlayer, amb el node AnimationPlayer ressaltat per un quadre vermell i assenyalat per una fletxa vermella, que indica la seva selecció o rellevància en el context de la lliçó actual, que se centra a configurar el senyal de col·lisió i el grup de jugadors de detecció.

En el Animació panell a la part inferior, feu clic Animació > Nou.

Aquesta imatge mostra el tauler inferior de Godot amb la pestanya "Animació" seleccionada i un menú contextual obert des del node AnimationPlayer (anteriorment destacat a la imatge 6), on s'està seleccionant l'opció "Nou...", que indica que l'usuari està a punt de crear un nou actiu d'animació per al node enemic, que pot visualitzar el dany o el comportament de detecció provocat pel senyal body_entered; la fletxa vermella emfatitza aquesta acció com a part de la configuració de la retroalimentació visual per al sistema de detecció de col·lisions descrit a la lliçó.

Anomena la mosca d'animació.

Aquesta imatge mostra el diàleg "Crea una animació nova" de Godot, on l'usuari anomena un nou actiu d'animació; el camp de text conté "volar", que indica el nom previst per a l'animació de vol de l'enemic, que probablement s'utilitzarà per representar visualment el comportament de l'enemic quan detecti o reaccioni al jugador, alineant-se amb l'enfocament de la lliçó a implementar la detecció de col·lisions i la retroalimentació visual associada.

Animarem la textura de l'Sprite per canviar entre dos fotogrames, creant un efecte de solapa d'ala. Tal com vam fer al capítol anterior amb el reproductor, seleccioneu el Sprite node, troba el Textura propietat a l'Inspector i feu clic a clau icona per inserir un fotograma clau.

Aquesta imatge mostra el tauler d'inspector de Godot per a un node Sprite2D, amb la propietat "Textura" ampliada i el seu valor es mostra com una petita miniatura de vista prèvia d'un sprite de caràcter; una fletxa vermella apunta al botó "Edita" (una icona de clau anglesa) al costat del camp de textura, que indica que l'usuari està a punt de modificar o configurar l'actiu de textura del sprite, probablement en preparació per animar el comportament visual de l'enemic després de la detecció de col·lisions, com a part de la lliçó en curs sobre la implementació de la interacció jugador-enemic.

Confirmeu que voleu crear una pista nova (i assegureu-vos Crea pistes de RESTABLECIMENT està comprovat).

Aquesta imatge mostra el diàleg "Confirmeu..." de Godot que apareix quan es crea una nova pista d'animació per a la propietat "textura", preguntant-se si cal crear una o més pistes de RESTABLECIMENT al costat del fotograma clau; la casella de selecció per a "Crear pistes de restabliment" està marcada i el botó "Crea" està ressaltat, indicant que l'usuari està confirmant la creació d'una pista d'animació per controlar la textura de l'esprit, probablement com a part de l'animació de l'estat visual de l'enemic durant la detecció de col·lisions.

En aquest cas, establiu la durada de l'animació en 0,3 segons.

Aquesta imatge mostra l'editor de línia de temps d'AnimationPlayer de Godot, on s'està configurant un fotograma clau a la marca de 0,3 segons de la pista d'animació, indicat pel quadre vermell al voltant del valor de temps "0,3" i una fletxa vermella que hi apunta, probablement per a l'animació de "volar" de l'enemic creada al pas anterior, per definir quan s'hauria de produir un canvi de propietat específic (com ara la textura o la posició de reproducció).

Necessitem dos fotogrames per al moviment de bateig:

  1. Fotograma 1 (0,0 s): El sprite predeterminat (ales cap amunt). Això ja està establert pel primer fotograma clau.
  2. Fotograma 2 (~0,15 s): Les ales cap avall sprite.

Mou la línia de temps a uns 0,1 o 0,2 segons. Feu clic amb el botó dret a la pista i seleccioneu Insereix la clau.

La imatge mostra un primer pla de l'editor de la línia de temps d'AnimationPlayer de Godot, on el cursor del ratolí passa per sobre del botó "Insereix clau..." situat a la marca de 0,3 segons d'una pista d'animació, indicant que l'usuari està a punt d'inserir un fotograma clau per a l'animació "volar" de l'enemic, que s'anomenava anteriorment i s'està configurant per definir el comportament visual del punt de temps específic en l'animació.

Amb aquest nou fotograma clau seleccionat, arrossegueu el sprite amb les ales cap avall (p. ex.,

character_0025.png) al Valor ranura a l'inspector.

Aquesta imatge mostra el tauler AnimationTrackKeyEdit de Godot, on s'està editant un valor de fotograma clau per a una pista d'animació, específicament el camp "Valor" mostra una petita miniatura de sprite (probablement representa l'estat visual de l'enemic) al costat d'un valor numèric "1.00" i un gràfic de corba suavitzant a sota, que indica aquesta propietat o escala d'intensitat possiblement amb un control d'intensitat total. interpolació lineal; aquest pas segueix la configuració de l'animació de "volar" de l'enemic i la inserció d'un fotograma clau a 0,3 segons per definir el seu comportament durant la detecció de col·lisions.

Repetiu aquest procés si voleu més fotogrames, o simplement alterna entre els dos.

Aquesta imatge mostra el tauler d'inspector de Godot centrat en la interfície AnimationTrackKeyEdit, on les propietats d'un fotograma clau s'estan editant per a una pista d'animació, concretament el camp "Temps" s'estableix en 0,2 segons, i el camp "Valor" mostra una miniatura de sprite (que representa l'estat visual animat) al costat d'un valor numèric i un gràfic que indica a sota. comportament d'interpolació per a aquest fotograma clau a la seqüència d'animació de l'enemic.

Un cop hàgiu acabat l'animació, activeu-la Bucle de manera que el ratpenat bateja contínuament.

Aquesta imatge mostra l'editor de la línia de temps d'AnimationPlayer de Godot, destacant el botó de commutació de bucle (una icona de fletxa circular tancada en un quadre vermell i assenyalada per una fletxa vermella) que s'utilitza per permetre el bucle continu de la pista d'animació a la marca de 0,3 segons, probablement per a l'animació "vola" de l'enemic configurada per respondre visualment quan es detecta el jugador.

No dubteu a modificar el temps. En el nostre exemple següent, hem ajustat la durada a 0,4 segons per fer que el bateig sigui una mica més lent i per fer més espai per a un fotograma clau addicional.

Aquesta imatge mostra l'editor de la línia de temps d'AnimationPlayer de Godot, on el botó de commutació de bucle (una icona de fletxa circular tancada en un quadre vermell i assenyalada per una fletxa vermella) es destaca a la marca de 0,4 segons a la pista d'animació per a l'animació "volar"; la pista s'etiqueta "textura" sota el node "Sprite", cosa que indica que s'està inserint un fotograma clau per animar la textura de l'esprit en aquest moment, continuant la configuració del comportament visual de l'enemic com a part de la lliçó de detecció de col·lisions.

Reprodueix l'animació

L'últim pas és dir que l'animació es reprodueixi automàticament quan es carregui l'escena. Afegiu la funció _ready al vostre script enemy.gd:

func 
_ready():

$AnimationPlayer.play("fly")

Si executes el joc ara, l'enemic patrullarà el seu camí mentre bat les ales.

Aquesta imatge il·lustra el resultat del joc de la configuració de detecció de col·lisions enemigues: un personatge d'art de píxels (verd amb un casc blanc) es mostra a l'aire a prop d'un enemic (taronja amb ales), col·locat per sobre de dues plataformes de terra sobre un fons blau clar amb arbres estilitzats, confirmant visualment que el col·lisionador Area2D de l'enemic ha detectat el senyal del col·lisionador Area2D i ha activat el col·lisionador. marcador de posició "Fes dany al jugador" lògica tal com es descriu a la lliçó.

Ara tenim un enemic funcional que patrulla una zona i detecta el jugador. En el següent capítol, implementarem el sistema de salut perquè aquestes col·lisions facin mal al jugador.

Principals mecàniques: Salut i puntuació

En els capítols anteriors, vam implementar el moviment del jugador i vam crear un enemic que patrullava el nivell. Tanmateix, el nostre joc actualment no té conseqüències i recompenses. El jugador pot caminar a través dels enemics sense patir danys i no hi ha objectius per completar.

En aquest capítol, convertirem el nostre projecte en un joc adequat introduint la mecànica de joc bàsica. Implementarem un sistema de salut on el jugador rep danys en xocar amb els enemics, restablint el nivell si la salut arriba a zero. També crearem monedes col·leccionables i un sistema de puntuació que fa un seguiment del progrés del jugador en els restabliments de nivell mitjançant un script de càrrega automàtica persistent.

El sistema de dany

El nostre primer objectiu és permetre que el jugador rebi danys. Definirem una variable de salut, crearem una funció per gestionar la lògica del dany i restablirem l'escena quan el jugador sigui derrotat.

Configuració de la salut del jugador

Hem de fer un seguiment de quants cops pot rebre el jugador abans que el joc es reiniciï. Obrim l'script player.gd i afegim una variable de salut a la part superior del fitxer (on hi ha les altres variables exportades).

@export 
var 
health : int = 3

Iniciem aquesta variable a 3, és a dir, el jugador té tres "cors" o punts de vida.

Creacio de la funcio de rebre dany

A continuació, necessitem una manera de reduir aquesta salut. Crearem una funció anomenada take_damage que accepta una quantitat de dany per aplicar. Aquesta funció restarà el dany de la salut actual i comprovarà si el jugador ha estat derrotat.

Afegiu la funció següent a player.gd:

func 
take_damage(amount : int): health -= amount
if 
health <= 0: game_over()

Aquí teniu la lògica:

  1. La variable de salut es redueix en la quantitat.
  2. Comprovem si la salut ha baixat a zero (o per sota).
  3. Si és així, anomenem una funció game_over.

Implementació del Game Over

La funció game_over gestiona el que passa quan el jugador perd. De moment, simplement tornarem a carregar el nivell actual per reiniciar el joc.

Afegiu aquesta funció al vostre script:

func 
game_over(): get_tree().change_scene_to_file("res://Scenes/level_1.tscn")

Aquesta línia accedeix a l'arbre d'escenes i li indica que torni a carregar el level_1.tscn

fitxer, restablint efectivament l'estat del joc.

Actualitzacio de l'script de l'enemic

Ara que el jugador pot rebre danys, necessitem que l'enemic l'infligui realment. Com a tal, obriu l'script enemy.gd a continuació.

En el capítol anterior, vam configurar la funció _on_body_entered per imprimir un missatge quan es detectés el reproductor. Ara modificarem aquesta funció per trucar a take_damage al reproductor.

Podem actualitzar la funció de la següent manera:

func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return

body.take_damage(1)

Quan el jugador entra a l'àrea de col·lisió de l'enemic, el guió confirma que el cos pertany al grup "Jugador" i després crida a take_damage(1), causant un punt de dany.

Gestioneu les devolucions de trucades de la física

Si proveu el joc ara i deixeu que el jugador rebi tres danys, el joc intentarà reiniciar-se. Tanmateix, és possible que us trobeu amb un error a la consola del depurador i el joc pot fallar o comportar-se de manera inesperada.

La imatge mostra la consola del depurador de Godot que mostra quatre missatges d'error de player.gd a les 0:00:57, tots indicant: "Eliminar un node CollisionObject durant una devolució de trucada física no està permès i provocarà un comportament no desitjat. Elimina amb call_deferred()". Aquests errors es produeixen durant la funció game_over(), que intenta eliminar nodes mentre la física està activa, una violació de les regles de Godot. El missatge superior també assenyala un paràmetre "delta" no utilitzat a _process(), cosa que suggereix que hauria d'anar prefixat amb un guió baix si és intencionat. Aquesta sortida es relaciona directament amb la implementació de la lliçó de game_over(), on la recàrrega de l'escena pot desencadenar inadvertidament l'eliminació de nodes durant les devolucions de trucada de la física, requerint una correcció mitjançant call_deferred().

Aquest error es produeix perquè _on_body_entered es produeix durant un pas de física. Godot bloqueja el motor físic durant aquest pas per garantir l'estabilitat. No es permet intentar canviar l'escena (que elimina nodes) mentre el motor està processant col·lisions.

Per solucionar-ho, hem d'utilitzar call_deferred. Això diu a Godot que espere fins que s'acabi el fotograma actual abans d'executar la funció.

Actualitzeu la funció take_damage a player.gd per utilitzar l'execució diferida:

func 
take_damage(amount : int): health -= amount
# Defer game_over to avoid freeing nodes mid-physics step
if 
health <= 0: call_deferred("game_over")

Ara, quan la salut arribi a zero, Godot acabarà els seus càlculs físics per al marc i aleshores truca a game_over, evitant l'error.

Nota de Godot: call_deferred i seguretat física

Godot processa la física en passos discrets. Durant una devolució de trucada de física (com

_on_body_entered), el motor bloqueja l'arbre de l'escena per evitar modificacions

que podria corrompre la simulació. La crida a queue_free(), el canvi d'escenes o l'eliminació de nodes directament dins d'aquestes devolucions de trucada provocarà un error.

call_deferred("function_name") indica a Godot que esperi fins que el pas de física del fotograma actual s'hagi completat abans d'executar la funció. És un patró habitual en projectes Godot quan cal modificar l'escena en resposta a esdeveniments de física.

Més informació: Object.call_diferred (https://docs.godotengine.org/en/4.6/classes/class_object.html#class-object-mètode-trucada-diferit)

Provar i desar

Tornem a provar el joc. Xoc amb l'enemic tres vegades. En el tercer cop, l'escena hauria de tornar a carregar sense problemes.

Quan estigueu satisfet amb el comportament de l'enemic, hauríem de desar-lo com a escena reutilitzable perquè puguem col·locar diversos enemics al nivell.

  1. Arrossegueu el node Enemy des del moll d'Escenes a la vostra carpeta Escenes al FileSystem.
  2. Deseu-lo com a enemy.tscn.

Aquesta imatge mostra el diàleg "Desa la nova escena com a..." de Godot, on l'usuari està desant un fitxer d'escena nou anomenat "enemy.tscn" al directori "res://Scenes" del projecte; Els fitxers existents visibles d'aquesta carpeta inclouen "level_1.tscn" i "player.tscn", que s'alinea amb el context de la lliçó de configuració del dany del jugador i la funcionalitat de restabliment de l'escena mitjançant la funció game_over() que torna a carregar "res://Scenes/level_1.tscn".

Ara pots duplicar l'enemic al teu nivell (Ctrl+D) per afegir més reptes. No dubteu a ajustar les propietats de direcció de moviment i velocitat de moviment per a cada instància per crear patrons de patrulla variats.

Aquesta imatge mostra l'editor d'escenes en 2D de Godot amb l'escena "level_1.tscn" oberta, que mostra un personatge del jugador (un sprite en forma de cor) situat entre diverses plataformes de terra rectangulars amb cims d'herba; el jugador està seleccionat i ressaltat amb un quadre delimitador verd i un aparell de transformació, que indica que s'està editant o provant en el context de la implementació de mecàniques de salut i danys. Concretament, això es prepara per provar els danys provocats per col·lisions dels enemics que eventualment cridaran player.take_damage(1) i restabliran l'escena mitjançant game_over() quan la salut arribi a zero.

Aquesta imatge mostra el tauler d'inspector de Godot per a un node "Enemy3", ressaltant les propietats de l'script exportat des de enemy.gd: "Move Direction" s'estableix en x=0,0 i y=-80,0, i "Move Speed" s'estableix en 30,0. Aquests valors controlen el vector de moviment i la velocitat de l'enemic, que són rellevants a mesura que avança la lliçó per modificar la funció _on_body_entered de l'enemic per trucar a player.take_damage(1) en cas de col·lisió, implementant així mecàniques de dany que desencadenen game_over() quan la salut arriba a zero.

Creacio de col·leccionables

Ara que tenim riscos, afegim recompenses. Crearem un objecte moneda que el jugador podrà recollir per augmentar la seva puntuació. Començarem configurant l'escena visual i després animant-la.

Configuració de l'escena de la moneda

Per començar, crea una escena nova amb un Àrea 2D com a node arrel. Anomena-ho Coin. Com l'enemic, utilitzem Area2D perquè pot detectar cossos superposats sense bloquejar-los físicament, que és exactament el que volem per a un objecte col·leccionable.

La imatge mostra el diàleg "Crea un nou node" a Godot Engine, on l'usuari està buscant i seleccionant el node "Area2D" per crear un objecte moneda per a un joc en 2D; el camp de cerca conté "àrea2" i "Area2D" es destaca a Coincidències amb la seva descripció que indica que és una regió de l'espai 2D que detecta altres CollisionObject2D que entren o surten, rellevant per configurar la detecció de col·lisions de la moneda tal com es descriu a la lliçó. Una fletxa vermella apunta des de l'"Area2D" seleccionat al botó "Crea", que indica el següent pas per crear una instancia del node. El tauler Recent també mostra "Area2D", confirmant el seu ús recent. Això s'alinea amb les instruccions del tutorial per començar creant un node Area2D anomenat "Coin" com a arrel de l'escena de la moneda.

Aquesta imatge mostra el tauler Escena del motor Godot amb el node "Moneda" seleccionat, ressaltat per una fletxa vermella i una icona d'advertència que indica un problema potencial; el node Coin és un fill d'Area2D a Main, juntament amb altres nodes com Player i Enemy, i la seva selecció correspon al pas de la lliçó de configurar l'escena de la moneda abans de programar el seu comportament d'animació i col·lisió.

A continuació, afegiu a Sprite2D node (anomenat Sprite) com a fill i assigneu la textura de la moneda dels vostres actius (p. ex., tile_0151.png o similar). Assegureu-vos que la seva posició estigui configurada en (0, 0).

Aquesta imatge il·lustra l'editor Godot Engine durant la fase de configuració de monedes d'un tutorial de jocs en 2D, mostrant el tauler Escena amb el node Area2D "Coin" seleccionat i el seu node "Sprite" subratllat en vermell; una fletxa vermella apunta des del node Sprite fins a la seva representació visual al llenç (un sprite de moneda d'art de píxels amb un anell exterior marró i un centre groc), confirmant el pas d'assignació de textura. El tauler FileSystem mostra el camí de l'actiu "res://Sprites/Objects/tile_0" per a la textura de la moneda i la posició del node Sprite s'estableix a (0, 0) tal com s'indica. No hi ha cap missatge de codi ni d'error visible en aquest marc, però la selecció i els comentaris visuals confirmen que la jerarquia de nodes i la configuració de l'esprit han estat correcta abans d'escripturar animacions.

Aquesta imatge mostra el tauler Godot Engine Inspector centrat en un node Sprite2D dins de l'escena Coin, destacant la secció Transform on la propietat Posició s'estableix a (x: 0,0 px, y: 0,0 px), tal com s'indica a la lliçó per centrar l'esprit de la moneda; una fletxa i un quadre vermells emfatitzen aquesta configuració, confirmant l'alineació amb el pas del tutorial per col·locar el node Sprite a l'origen abans d'afegir animacions o formes de col·lisió.

Així podem detectar el reproductor, afegiu a CollisionShape2D node fill.

Aquesta imatge mostra el diàleg "Crea nou node" del motor Godot, on l'usuari ha escrit "col" al camp de cerca i seleccionat "CollisionShape2D" de la llista de coincidències, un pas necessari per afegir la detecció de col·lisions al node Coin tal com es descriu a la lliçó; El tauler Descripció següent explica que CollisionShape2D proporciona un Shape2D a un pare CollisionObject2D, que permet la interacció amb els nodes Area2D o PhysicsBody2D, i una fletxa vermella apunta des del node seleccionat al botó "Crea" ressaltat, que indica la següent acció per instància del node.

Assigna a CircleShape2D a la forma de col·lisió i canvieu-ne la mida perquè coincideixi amb el gràfic de la moneda.

Aquesta imatge mostra el tauler Godot Engine Inspector per a un node CollisionShape2D dins de l'escena Coin, destacant la propietat Shape establerta en CircleShape2D, indicant que s'ha assignat un límit de col·lisió circular a la moneda; una fletxa vermella apunta des d'aquesta configuració cap a la finestra 2D, on el sprite de la moneda es superposa visualment amb una forma de col·lisió circular verde verda que coincideix amb la seva mida, confirmant que la geometria de la col·lisió s'ajusta correctament als límits visuals de la moneda tal com s'indica a la lliçó.

Programació d'animació de monedes

Perquè la moneda sembli atractiva, escriurem una animació senzilla que la faci moure cap amunt, cap avall i girar. Si bé podríem utilitzar un

AnimationPlayer, fer-ho mitjançant codi ens proporciona una bona suavitat matemàtica i demostra com manipular transformacions directament.

Per començar, adjunteu un script nou anomenat coin.gd al node Coin.

Aquesta imatge mostra el diàleg "Adjunta l'script del node" a Godot Engine, on s'està creant un nou GDScript per al node Coin; el camp Ruta mostra "res://Scripts/coin.gd", indicant que l'script es desarà a la carpeta Scripts amb aquest nom de fitxer, i dos missatges d'estat verd confirmen que la ruta és vàlida i es crearà un fitxer nou; una fletxa vermella apunta des del camp Camí fins al botó "Crea" ressaltat, indicant el següent pas per generar el fitxer de script com a part de la configuració de la lògica d'animació de la moneda.

A continuació, afegiu el codi següent per definir les nostres variables d'animació i lògica:

extends 
Area2D
var 
rotate_speed : float = 3.0 
var 
bob_height : float = 5.0 
var 
bob_speed : float = 5.0
@onready 
var 
start_pos : Vector2 = global_position @onready 
var 
sprite : Sprite2D = $Sprite
func 
_physics_process(delta):
var 
time = Time.get_unix_time_from_system()
# rotate

sprite.scale.x = sin(time * rotate_speed)

# bob up and down
var 
y_pos = ((1 + sin(time * bob_speed)) / 2) * bob_height global_position.y = start_pos.y - y_pos

Desglossem aquest efecte:

Sobre les ones sinusoïdals

La funció sin() que hem utilitzat crea el que es coneix com a ona sinusoïdal. Una ona sinusoïdal és una corba suau i semblant a una ona que es repeteix amunt i avall en un patró regular.

S'utilitza habitualment als jocs per crear moviments naturals en bucle, com ara flotar, balancejar-se o agitar. Quan utilitzeu sin() al vostre codi, obtindreu un valor que varia sense problemes de -1 a 1 amb el temps.

A l'exemple del moviment de balanceig, notareu que el valor "pecat" s'ajusta afegint primer un i després dividint per dos. Això transforma el seu rang natural en un nou rang entre zero i un. Aquest canvi és útil perquè assegura que el moviment es mantingui sempre positiu, ideal per als casos en què voleu que la posició vertical de la moneda es mantingui per sobre d'un punt determinat.

Si col·loqueu la moneda al nivell i executeu el joc, la veureu girant i flotant.

En aquesta escena de joc d'art de píxels, un personatge d'astronauta verd es troba sobre una plataforma de terra amb la part superior d'herba, mentre una petita moneda groga flota a prop a la dreta, demostrant visualment l'objecte col·leccionable animat creat a la lliçó; el moviment de balanceig i rotació de la moneda (tal com s'indica a coin.gd) està implicat per la seva posició i orientació a l'aire, i un enemic volador amb ales apareix més a la dreta, contextualitzant la moneda dins del joc on es pot recollir per augmentar la puntuació.

Recollir monedes

Ara que tenim una moneda a l'escena, hem de connectar la lògica perquè el jugador pugui recollir-la. Això implica afegir una funció de puntuació al jugador i connectar el senyal de col·lisió de la moneda.

Actualitzacio de l'script del jugador

En primer lloc, necessitem una funció al jugador que gestioni els augments de puntuació. Obert

player.gd i afegiu una funció de marcador de posició:

func 
increase_score(amount: int): print("increase score")

Implementarem la lògica de puntuació real a la secció següent. De moment, aquesta declaració d'impressió ens ajudarà a comprovar que el mecànic de recollida funciona.

Gestionar la col·lisio

Amb el jugador preparat per rebre actualitzacions de puntuació, podem connectar el senyal de col·lisió de la moneda. Primer, seleccioneu el node Coin a la vostra escena. En el Node dock, connecteu el senyal body_entered a l'script coin.gd.

La imatge mostra el tauler d'inspector del motor Godot amb la pestanya "Node" seleccionada, ressaltant la secció "Señals" per a un node Area2D. Una fletxa vermella apunta al senyal "body_entered(body: Node2D)", que està emfatitzat amb un quadre vermell. Aquest és el senyal utilitzat a la lliçó per detectar quan un cos físic (com el jugador) entra a l'àrea de col·lisió de la moneda. La lliçó explica la connexió d'aquest senyal per activar la lògica de recollida de la moneda, inclosa la crida a la funció augmente_score del jugador i l'eliminació de la moneda mitjançant queue_free(). La llista de senyals visibles inclou altres senyals relacionats com area_entered, area_exited i body_exited, però el focus se centra en body_entered com a controlador d'esdeveniments clau per a la col·lisió entre el jugador i la moneda.

Aquesta imatge mostra el diàleg "Connecta un senyal a un mètode" de Godot, on el senyal body_entered(body: Node2D) del node Coin s'està connectant al seu propi mètode _on_body_entered; el node Coin està seleccionat a "Connecta a l'script" i el botó "Connecta" es ressalta amb un quadre vermell i una fletxa, que indica el pas final per establir la connexió del senyal com a part de la configuració de la gestió de col·lisions de monedes.

A la funció _on_body_entered generada, afegiu la lògica següent:

func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return 
body.increase_score(1) queue_free()

Aquest codi comprova si el cos que xoca és el jugador. Si és així, activa la funció augmente_score al reproductor i després crida a queue_free() a si mateix. queue_free() és la forma estàndard d'eliminar un node de l'escena a Godot, "recollint" efectivament la moneda.

Provar i desar

Executar el joc i entrar en una moneda. Hauria de desaparèixer i hauríeu de veure "augmenta la puntuació" imprès al tauler de sortida.

La imatge mostra una escena de joc Godot Engine amb un personatge d'un jugador d'art de píxels dret sobre una plataforma de terra i una moneda flotant a prop; a sota de l'escena, la consola de sortida Godot mostra el text "augmenta la puntuació" ressaltat en un quadre vermell, confirmant que la funció augmenta_puntuació del jugador s'ha cridat correctament durant les proves de col·lisió tal com es descriu a la lliçó. Aquesta sortida verifica la implementació bàsica abans d'afegir la lògica de puntuació completa.

Un cop verificada, deseu la moneda com a escena (coin.tscn) a la carpeta Escenes perquè pugueu col·locar diverses monedes al llarg del nivell.

Aquesta imatge mostra el tauler d'escena del motor Godot amb el node "Moneda" seleccionat a l'arbre de l'escena, ressaltat per un quadre vermell, que indica que és el focus actual per al comportament de col·lisió d'scripts; una fletxa vermella puntejada apunta cap avall al tauler FileSystem, on el fitxer d'escena "00_Coin.tscn" es destaca a la carpeta "Escenes", confirmant que el recurs d'escena de la moneda s'està referenciant o editant com a part de la configuració de la seva resposta de col·lisió per activar la funció d'augment_score del jugador.

Aquesta imatge mostra el diàleg "Desa la nova escena com a..." de Godot, on l'usuari està desant un fitxer d'escena nou anomenat "coin.tscn" al directori res://Scenes; Els fitxers d'escena existents visibles inclouen enemy.tscn, level_1.tscn i player.tscn. L'opció "Restableix la posició" està marcada, mentre que "Restableix la rotació" i "Restableix l'escala" no estan marcades. Aquest pas segueix la configuració del comportament de col·lisió de la moneda i precedeix la prova de la implementació, tal com es descriu a la lliçó en què el node de la moneda activa la funció d'augment_score del jugador en la col·lisió i després s'elimina mitjançant queue_free().

Aquesta imatge mostra l'editor d'escenes en 2D del Godot Engine que mostra level_1.tscn, on un personatge d'un jugador d'art de píxels es troba en una plataforma de terra al costat de múltiples nodes de monedes i pastilles de cor, disposats en plataformes flotants sobre un fons blau clar amb siluetes d'arbres estilitzades; l'escena s'amplia al 345,2% i el node del jugador es selecciona al tauler Escena (indicat per la seva icona i nom), mentre que les monedes es col·loquen com a objectes de col·lecció per activar-se mitjançant la detecció de col·lisions body_entered, d'acord amb l'objectiu de la lliçó de configurar la funcionalitat d'augment de la puntuació en la col·lisió del jugador-moneda, encara que aquí no hi ha cap codi o sortida de consola visible.

Puntuacio persistent

Tenim un problema: sempre que el jugador mor, tornem a carregar l'escena amb change_scene_to_file. Això restableix tot a l'escena, inclòs el guió del jugador i qualsevol variable que hi hagi dins. Si emmagatzemem la puntuació a player.gd, la puntuació es tornarà a zero cada vegada que el jugador mor.

Per mantenir la puntuació entre els restabliments de nivell, necessitem una variable que existeixi fora l'escena. A Godot, fem servir un Carrega automàtica (o Singleton) per a això.

Creació d'un script de càrrega automàtica

Una càrrega automàtica és un script que Godot carrega una vegada a l'inici i es manté viu durant tota la sessió del joc. Com que no forma part de cap escena en particular, sobreviu als canvis d'escenari. Per configurar-ho, aneu a Projecte > Configuració del projecte.

La imatge mostra la interfície del motor Godot amb el menú "Projecte" obert, destacant l'opció "Configuració del projecte...", que s'està seleccionant per configurar els paràmetres de tot el projecte, específicament per configurar un script de càrrega automàtica (singleton) anomenat PlayerStats per al seguiment de la puntuació persistent a través de les escenes, tal com es descriu a la lliçó. El títol de la finestra indica que el fitxer d'escena actual és "level_1.tscn" dins d'un projecte "Godot2DPlatformerCourse". No hi ha cap codi ni sortida de consola visible; el focus és navegar per la interfície d'usuari per accedir a la configuració del projecte, un pas necessari abans d'afegir l'script de càrrega automàtica a la pestanya Globals.

Canvia a la Globals pestanya. Aquí és on definim scripts que es carreguen automàticament quan s'inicia el joc i romanen a la memòria fins que el joc es tanca.

  1. En el Nom del node camp, escriviu PlayerStats.
  2. Feu clic a la icona de la carpeta al costat del camp Camí per crear un script nou. Deseu-lo com a player_stats.gd a la vostra carpeta Scripts.
  3. Feu clic Afegeix.

Aquesta imatge mostra la finestra de configuració del projecte del motor Godot, concretament la pestanya Globals, on s'està configurant un script de càrrega automàtica per a dades de joc persistents. El camp Nom del node conté "PlayerStats", que s'utilitzarà per accedir a l'script singleton a través de les escenes. Una fletxa vermella apunta des de la pestanya Globals a l'entrada del nom del node i després al botó "+ Afegeix", que indica els passos per registrar l'script com a càrrega automàtica. Aquesta configuració permet que l'script PlayerStats.gd mantingui una variable de puntuació global que persisteix en les transicions de nivell, tal com es descriu a la lliçó.

Aquesta imatge mostra el diàleg "Crea un script" del motor Godot, on s'està creant un fitxer GDScript nou per a dades de joc persistents. El camp Ruta mostra "res://Scripts/player_stats.gd", indicant que l'script es desarà a la carpeta Scripts amb aquest nom de fitxer. A continuació, dos missatges de validació verd confirmen que el camí és vàlid i es crearà un nou fitxer d'script. Una fletxa vermella apunta des del camp Camí fins al botó "Crea" ressaltat, posant èmfasi en el pas final per generar el fitxer de script com a part de la configuració del singleton de PlayerStats per a la persistència de la puntuació entre escenes.

Ara hauríeu de veure PlayerStats a la llista de càrrega automàtica.

Aquesta imatge mostra la finestra de configuració del projecte del motor Godot a la pestanya Globals, que mostra l'script de càrrega automàtica afegit amb èxit anomenat "PlayerStats", que està configurat per carregar el fitxer de seqüència de comandaments a la ruta "res://Scripts/player_stats.gd" i està habilitat per utilitzar-lo a totes les escenes. Aquesta configuració singleton permet un seguiment de la puntuació persistent tal com es descriu a la lliçó, amb controls visibles per activar/desactivar o gestionar l'entrada de càrrega automàtica.

Nota de Godot: Carrega automàtica de singletons

Una càrrega automàtica és un script (o escena) que Godot carrega automàticament quan comença el joc i es manté a la memòria durant tota la sessió. Com que viu fora de qualsevol escena en particular, les seves dades persisteixen durant els canvis d'escena. Podeu accedir-hi des de qualsevol script mitjançant el nom de node que heu assignat a la configuració del projecte (en el nostre cas, PlayerStats).

Les càrregues automàtiques són ideals per a l'estat global, com ara puntuacions, configuració o desar dades. Tanmateix, eviteu posar-hi massa lògica. Si un sistema només ha d'existir dins d'una única escena, un node normal és una millor opció.

Més informació: Singletons (càrrega automàtica) (https://docs.godotengine.org/en/4.6/tutorials/scripting/singletons_autoload

.html)

Implementació de la puntuació global

Obriu l'script player_stats.gd acabat de crear. Només necessitem una única variable per mantenir la puntuació:

extends 
Node
var 
score : int = 0

Com que aquest script és una càrrega automàtica, podem accedir-hi des de qualsevol lloc del nostre joc utilitzant el nom PlayerStats.

Actualitzacio de l'script del jugador

Ara, torna a player.gd. Modificarem la funció augmente_score per actualitzar la variable global en lloc d'imprimir només un missatge.

func 
increase_score(amount : int): PlayerStats.score += amount print(PlayerStats.score)

Provar la persistència

Executar el joc i recollir unes quantes monedes. Hauríeu de veure el recompte de la puntuació a la sortida (1, 2, 3...).

Error 500 (Server Error)!!1500.That’s an error.There was an error. Please try again later.That’s all we know.

Ara, intenta deixar que el jugador mori intencionadament per activar un restabliment de l'escena. Quan es torni a carregar el nivell, recull una altra moneda. La puntuació hauria de continuar augmentant des d'on ho vau deixar (p. ex., 4, 5...), demostrant que les dades han persistit durant el canvi d'escena.

Aquesta imatge mostra la sortida de la consola Godot Engine que confirma que el joc s'està executant amb Vulkan 1.3, seguit d'una seqüència de números (1, 2, 3, 4), impresos en línies separades, que demostra que el sistema de puntuació persistent (implementat mitjançant l'script de càrrega automàtica de PlayerStats) augmenta correctament i conserva el seu valor durant els reinicis de l'escena, com s'esperava quan es recullen monedes d'esdeveniments del joc.

Mitjançant l'ús d'una càrrega automàtica, hem separat amb èxit les dades del joc de la lògica de l'escena, garantint-nos que el progrés es desa fins i tot quan el nivell es restableixi.

Al capítol següent, ampliarem el nostre disseny de nivell creant "Finals de finalització" que permeten al jugador completar un nivell i viatjar al següent.

Logica de finalitzacio del nivell

En aquest capítol, implementarem la condició guanyadora del nostre joc. Cada nivell de plataformes necessita un objectiu clar perquè el jugador assoleixi, i el nostre serà una "bandera final". Quan el jugador toca aquesta bandera, el joc detecta la col·lisió i passa al següent nivell.

Per aconseguir-ho, primer organitzarem la nostra jerarquia d'escenes per mantenir-la manejable. Aleshores, construirem l'objecte de bandera final utilitzant un node Area2D i escriurem un script breu per gestionar la lògica de transició d'escena.

Organitzacio de la jerarquia de l'escena

A mesura que el nostre nivell creix, el moll d'escena es pot desordenar ràpidament. Ara mateix, l'escena conté diversos nodes individuals d'enemics i monedes barrejats, cosa que dificulta trobar res d'un cop d'ull. Abans d'afegir més objectes, agrupem nodes similars sota els nodes del contenidor perquè l'arbre es mantingui ordenat.

La imatge mostra el tauler Escena del motor Godot, que mostra una estructura de nodes jeràrquica sota el node arrel "Principal", que inclou BackgroundSprite, TileMapLayer, Player i diversos nodes Enemy i Coin (Enemy2–3, Coin2–7), il·lustrant l'estat no organitzat actual dels objectes del joc abans d'agrupar-los com es descriu a les lliçons de gestió.

Feu clic amb el botó dret a Principal node i seleccioneu Afegeix un node fill. Cerca un genèric Node (sovint anomenat "Node buit" perquè no té propietats de transformació ni visuals) i afegiu-lo a l'escena.

Aquesta imatge mostra el diàleg "Crea un nou node" de Godot, on l'usuari ha escrit "node" a la barra de cerca i seleccionat la classe genèrica "Node" de la llista de coincidències; una fletxa vermella destaca aquesta selecció apuntant cap avall al botó "Crea", indicant el pas per crear una instancia d'un nou node buit, rellevant per organitzar la jerarquia de l'escena mitjançant la creació de contenidors principals com "Monedes" i "Enemics", tal com es descriu a la lliçó.

Canvieu el nom d'aquest nou node a Monedes. A continuació, seleccioneu tots els vostres nodes de monedes existents al moll d'escena i arrossegueu-los al node Monedes per crear-los.

Aquesta imatge mostra el tauler Escena de Godot després d'organitzar la jerarquia: s'ha creat un nou node principal anomenat "Monedes" i ara conté set nodes secundaris etiquetats Coin a Coin7, demostrant visualment l'agrupació d'objectes monedes sota un únic contenidor per millorar la gestió de l'escena tal com es descriu a la lliçó.

Repetiu aquest procés per als enemics:

  1. Creeu un altre genèric Node i canviar-li el nom a Enemics.
  2. Seleccioneu tots els nodes enemics i arrossegueu-los al node Enemics.

Aquesta imatge mostra el tauler Escena de Godot després d'organitzar els nodes enemics: s'ha creat un nou node pare anomenat "Enemics" i ara conté tres nodes secundaris etiquetats "Enemic", "Enemic2" i "Enemic3", que demostra visualment l'agrupació d'objectes enemics sota un únic contenidor per millorar la gestió de l'escena, tal com es descriu a la jerarquia.

La teva jerarquia d'escenes hauria de semblar molt més neta, amb seccions plegables per als objectes del joc.

Aquesta imatge mostra el tauler de l'Escena de Godot després d'organitzar la jerarquia del joc: sota el node arrel "Principal" hi ha BackgroundSprite, TileMapLayer, Player i dos nodes contenidors recentment creats ("Coins" i "Enemies"), cadascun col·lapsat amb un triangle de divulgació, que indica que ara agrupen els seus respectius nodes secundaris (com es mostrava anteriorment a la configuració de la bandera de final de les escenes de la línia anterior).

Creació definitiva de la bandera

Ara que la nostra jerarquia està organitzada, podem construir l'objecte objectiu. La bandera final funciona de manera similar a les nostres monedes i enemics: necessita un sprite visual i una àrea de col·lisió per detectar el jugador. Quan el jugador hi entri, el joc sabrà que el nivell s'ha completat.

Primer, neteja un espai al teu nivell per a l'objectiu. Suprimeix qualsevol node de moneda situat on voleu col·locar la bandera.

A continuació, creeu un nou Àrea 2D node i canviar-lo per EndFlag.

Aquesta imatge mostra el diàleg "Crea un nou node" de Godot on l'usuari ha escrit "area2d" a la barra de cerca, destacant la classe "Area2D" a la llista de coincidències; una fletxa vermella apunta des del node Area2D seleccionat fins al botó "Crea", indicant el pas per crear una instancia d'aquest node com a part de la configuració de la bandera final. El tauler de descripció següent confirma que Area2D és una regió de l'espai 2D que detecta altres CollisionObject2Ds que hi entren o surten, i assenyala que s'ha de definir per un o més nodes fills CollisionShape2D o CollisionPolygon2D, alineant-se amb els passos següents de la lliçó per afegir un sprite i una forma de col·lisió a l'Aread2D de nou nom creat.

Aquesta imatge mostra el tauler Escena de Godot amb el node "EndFlag" recentment creat ressaltat en vermell, situat sota el node arrel "Principal" al costat de BackgroundSprite, TileMapLayer, Player, Coins i Enemies; el node EndFlag està seleccionat i mostra una icona d'advertència, que indica que pot requerir una configuració addicional, com ara adjuntar un script o afegir nodes secundaris com un Sprite i CollisionShape2D, tal com es descriu a la lliçó per configurar l'activador de finalització de nivell.

A continuació, hem d'afegir el component visual. En el Sistema de fitxers atraca, navega fins a Sprites > Objectes i cerqueu la imatge de la bandera (p. ex., tile_0112.png). Arrossegueu aquesta imatge a l'escena per crear un sprite.

A l'editor de Godot Engine, el node "EndFlag" està seleccionat al panell Escena, amb el seu fill "Tile0112" ressaltat; el Dock FileSystem mostra el fitxer "tile_0112.png" a res://Sprites/Objects/, que s'ha arrossegat a l'escena per servir com a sprite visual de la bandera; una fletxa vermella apunta des del fitxer al sprite col·locat a la finestra 2D, on apareix per sobre del sòl al costat d'una forma de col·lisió circular, i una vista ampliada a l'extrem superior dret mostra la textura de la bandera d'art de píxels (pancarta taronja al pal gris) que es col·loca per a l'alineació.

Canvieu el nom del nou node de sprite a Sprite i assegureu-vos que sigui un fill del

Node EndFlag.

Al tauler Escena de Godot, el node "EndFlag" s'amplia per revelar el seu node "Sprite" fill, tots dos destacats dins d'un rectangle vermell; el node EndFlag mostra una icona d'advertència que indica que pot requerir més configuració, mentre que el node Sprite es col·loca com a fill directe a EndFlag, reflectint la configuració de l'objecte de la bandera final amb el seu component visual tal com es descriu a la lliçó.

Igual que amb els nostres altres objectes, configureu el Posició del node Sprite a (0, 0), de manera que s'alinea perfectament amb l'origen del node pare.

Al panell Inspector de Godot, el node Sprite seleccionat sota l'EndFlag es mostra amb les seves propietats de transformació expandides; els camps de posició es ressalten en un quadre vermell, mostrant x: 0,0 px i y: 0,0 px, confirmant que l'origen del sprite està centrat a (0,0) en relació al seu node EndFlag pare, tal com s'indica per a l'alineació adequada del component visual de la bandera final.

Finalment, hem de definir l'àrea de detecció perquè el joc sàpiga quan ha arribat el jugador. Afegeix a CollisionShape2D node com a fill d'EndFlag.

Al diàleg "Crea nou node" de Godot, l'usuari ha escrit "col" a la barra de cerca i el node "CollisionShape2D" està seleccionat a la categoria Node2D; una fletxa vermella apunta des d'aquesta selecció fins al botó "Crea", que indica el pas per crear una instancia de CollisionShape2D com a fill del node EndFlag per definir el seu límit de col·lisió. El tauler de descripció següent confirma que és un node que proporciona un Shape2D a un pare CollisionObject2D, que permet la detecció del comportament d'Area2D o de la física sòlida.

A l'Inspector, configureu el Forma propietat a a CircleShape2D. Canvieu la mida del cercle a la finestra gràfica perquè cobreixi l'esprit de la bandera. Aquesta àrea representa la zona a la qual ha d'entrar el jugador per acabar el nivell.

Al tauler d'inspector de Godot Engine, el node CollisionShape2D seleccionat sota l'EndFlag es mostra amb la seva propietat Shape establerta en CircleShape2D, ressaltat en un quadre vermell; una fletxa vermella apunta des d'aquest paràmetre a la vista de l'escena 2D on la forma de col·lisió circular està visiblement superposada al sprite de la bandera, confirmant que la forma s'ha aplicat i redimensionat per adaptar-se als límits visuals de la bandera com a part de la configuració de l'àrea de detecció física de la bandera final.

La vostra estructura d'escena EndFlag ara està completa i preparada per a la lògica.

Aquesta imatge mostra el tauler Escena de Godot amb el node "EndFlag" seleccionat i ampliat, revelant els seus dos nodes fills: "Sprite" i "CollisionShape2D", tots dos destacats dins d'un rectangle vermell per emfatitzar la seva relació jeràrquica sota EndFlag; el cursor es troba sobre el node EndFlag, indicant que és la selecció activa com a part de la configuració de l'objecte de bandera final per a la lògica de transició d'escena.

Programaci de la bandera final

Amb l'estructura del node al seu lloc, necessitem un script per gestionar el que passa quan el jugador arriba a la bandera. Seleccioneu el node EndFlag i adjunteu un script nou anomenat end_flag.gd.

Aquesta imatge mostra el diàleg "Adjunta l'script del node" de Godot, on s'està creant un nou GDScript per al node EndFlag; l'Idioma està configurat en GDScript, Hereta és Area2D i el camp Path mostra "res://Scripts/end_flag.gd", indicant la ubicació del fitxer d'script; dos missatges de validació confirmen que el camí és vàlid i que es crearà un nou fitxer d'script; una fletxa vermella apunta des del camp Camí fins al botó "Crea" ressaltat, que indica el següent pas per generar el fitxer de guió per gestionar les transicions d'escena quan el jugador arriba a la bandera final.

Connexió del senyal

Per detectar quan el jugador entra a l'àrea de la bandera, utilitzarem el senyal body_entered, tal com vam fer amb les monedes i els enemics. Com a recordatori, aquest senyal es dispara sempre que un cos físic se superposa a l'Area2D.

  1. Seleccioneu el node EndFlag.
  2. Aneu a la Node pestanya (al costat de l'Inspector).
  3. Feu doble clic al senyal body_entered.

Al tauler Inspector de Godot, a la pestanya "Señals" del node Area2D, el senyal "body_entered(body: Node2D)" es ressalta amb un quadre vermell i s'assenyala amb una fletxa vermella, que indica que és el senyal seleccionat per connectar-se per detectar quan un cos físic entra a l'àrea. Això s'utilitzarà a l'script end_flag.gd per activar transicions d'escena quan el jugador arribi a la bandera.

Al diàleg de connexió, connecteu el senyal al mateix node EndFlag. Això generarà la funció _on_body_entered al vostre script.

Aquesta imatge mostra el diàleg "Connexió d'un senyal a un mètode" de Godot, on el senyal "body_entered(body: Node2D)" del node Area2D s'està connectant a un mètode receptor. El node "EndFlag (Connexió des de)" està seleccionat sota el contenidor "Enemics" de l'arbre de l'escena, i el camp "Mètode del receptor" mostra "_on_body_entered", que indica el mètode que s'anomenarà quan un cos entri a l'àrea. Una fletxa vermella apunta des del node EndFlag seleccionat fins al botó "Connecta" ressaltat a la part inferior del diàleg, indicant el pas final per establir la connexió per activar les transicions d'escena quan el jugador xoca amb la bandera final.

Implementació de la transició d'escena

Ara podem obrir l'script i implementar la lògica per carregar el següent nivell. Utilitzarem una variable exportada per definir quina escena carregar, fent que aquest script sigui reutilitzable per a qualsevol nivell.

Afegiu el codi següent a end_flag.gd:

extends 
Area2D
@export 
var 
scene_to_load : PackedScene
func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return
get_tree().change_scene_to_packed(scene_to_load)

Així és com funciona cada peça:

Nota de Godot: càrrega d'escena i escena empaquetada

Un PackedScene és un recurs que conté una escena en un format compacte i carregable. Quan arrossegueu un fitxer .tscn a una variable @export a l'Inspector, Godot emmagatzema una referència a aquesta escena empaquetada. En temps d'execució, cridar a change_scene_to_packed() el desempaqueta i s'intercanvia al nou arbre d'escenes.

L'ús de PackedScene en lloc d'una cadena de ruta de fitxer (com change_scene_to_file()) té dos avantatges: Godot valida la referència en el moment de l'edició (de manera que no podeu escriure accidentalment un camí incorrecte) i precarrega el recurs per a transicions més ràpides.

Més informació: Escena empaquetada (https://docs.godotengine.org/en/4.6/classes/class_packedscene.html)

Provar la bandera final

Amb l'script al seu lloc, comprovem que tot funciona. Seleccioneu el node EndFlag al moll de l'escena. A l'Inspector, veureu Escena per carregar propietat, on hem d'assignar l'escena a la qual ha de passar el joc.

Com que encara no tenim un "Nivell 2", podem assignar temporalment una escena diferent (com l'escena del reproductor) només per verificar que la transició funciona.

Al panell Inspector de Godot, el node "EndFlag" seleccionat mostra el seu script adjunt "end_flag.gd" sota la propietat "Escena per carregar", que es ressalta amb un rectangle vermell; aquest camp permet especificar la següent escena a la qual passarà quan el jugador arriba a la bandera, i inclou icones per editar el guió, visualitzar-ne la documentació i seleccionar un fitxer d'escena mitjançant la icona de carpeta, que indica la fase de configuració per gestionar la lògica de finalització del nivell.

Nota: Godot impedeix que carregueu exactament el mateix fitxer d'escena que està actiu actualment per evitar bucles de recursivitat infinits. Per provar, assegureu-vos que trieu un fitxer d'escena diferent del que esteu reproduint actualment.

Executeu el joc i moveu el vostre jugador a la bandera. Si tot està configurat correctament, el joc hauria de canviar immediatament a l'escena que heu assignat.

A la finestra de visualització de l'editor 2D de Godot Engine durant una sessió de depuració titulada "Godot2DPlatformerCourse (DEBUG)", un petit personatge alienígena verd d'art de píxels amb un casc blanc es centra en un fons gris fosc, que representa l'esprit del jugador; a sobre d'ell, una lleugera forma de col·lisió circular és visible, que indica la zona activa de l'Area2D per al node EndFlag. Això confirma la ubicació de la bandera i la configuració de col·lisió tal com es descriu a la lliçó, on el jugador ha d'entrar a aquesta àrea per activar la lògica de transició de l'escena mitjançant el senyal body_entered connectat.

Felicitats! Heu implementat amb èxit el bucle bàsic del vostre joc: comença un nivell, supera els reptes i assoleix l'objectiu. En el següent capítol, polirem l'experiència afegint elements d'IU per mostrar la salut i la puntuació del jugador.

Construccio de la interfície d'usuari

En aquest capítol, crearem la interfície d'usuari (UI) per al nostre joc. Una bona interfície d'usuari proporciona comentaris essencials al jugador, com ara el seu estat de salut actual i el seu progrés a través del nivell.

Dissenyarem un Heads-Up Display (HUD) format per dos elements principals: una fila de cors que representen la salut i una etiqueta de text que mostra la puntuació actual. A continuació, connectarem aquests elements visuals a la nostra lògica de joc mitjançant senyals, assegurant-nos que s'actualitzen a l'instant sempre que el jugador tingui danys o reculli una moneda.

Configuració del CanvasLayer

Per garantir que la nostra interfície d'usuari es mantingui visible a la pantalla independentment d'on es mogui el jugador al món del joc, necessitem un node especial que es mostri independentment de la càmera del joc. A Godot, aquest node s'anomena CanvasLayer.

Treballarem dins del Jugador escena per a aquesta configuració. Comencem per crear un nou node CanvasLayer com a fill del node del reproductor arrel.

La imatge mostra el diàleg "Crea un nou node" en un editor de motors de jocs, on l'usuari ha escrit "llenç" a la barra de cerca i seleccionat "CanvasLayer" de la llista de coincidències; una fletxa vermella apunta des del CanvasLayer seleccionat al botó "Crea" de sota, indicant que el següent pas és crear una instancia d'aquest node. El tauler de descripció confirma que CanvasLayer és un node que s'utilitza per a la representació independent d'objectes d'escena 2D, assenyalant que els fills derivats de CanvasItem es representaran dins d'ell mitjançant un índex de capa numèrica (0 per defecte). Això s'alinea amb l'objectiu de la lliçó de configurar una interfície d'usuari mitjançant la creació d'un CanvasLayer per mantenir els elements de salut i puntuació que romanen fixats a la pantalla independentment del moviment de la càmera de joc.

El CanvasLayer actua com un full transparent enganxat al monitor. Qualsevol node col·locat dins d'ell es mantindrà fix en relació a la pantalla, el que el converteix en el contenidor perfecte per a barres de salut, puntuacions i menús.

Nota de Godot: CanvasLayer per a la interfície d'usuari de l'espai de pantalla

De manera predeterminada, tots els nodes d'una escena comparteixen el mateix llenç i es veuen afectats pel Camera2D actiu. Un CanvasLayer crea una capa de dibuix independent amb la seva pròpia transformació, el que significa que els seus fills ignoren completament la càmera. És per això que les barres de salut i les etiquetes de puntuació es mantenen fixades a les cantonades de la pantalla fins i tot mentre el jugador passa pel nivell.

Podeu apilar diversos CanvasLayers amb diferents valors de capes per controlar l'ordre de dibuix. Un número de capa més alt es renderitza a la part superior.

Més informació: CanvasLayer (https://docs.godotengine.org/en/4.6/classes/class_canvaslayer.html)

Creacio de l'indicador de salut

La nostra pantalla de salut constarà de diverses icones de cor disposades en fila. En lloc de posicionar cada cor manualment, utilitzarem un node contenidor per gestionar el disseny automàticament. Aquest enfocament manté la interfície d'usuari flexible si decidim afegir més cors més tard.

Afegir la textura del cor

Primer, creem un únic cor que serveixi de plantilla. Crea una nova

El node TextureRect com a fill del CanvasLayer.

Al diàleg "Crea un nou node" d'un editor de motor de joc, l'usuari ha escrit "textura" a la barra de cerca i seleccionat "TextureRect" de les coincidències a la categoria Control; una fletxa vermella apunta des del TextureRect ressaltat fins al botó "Crea" a continuació, indicant que el següent pas és crear una instancia d'aquest node com a part de la creació de la pantalla de salut de la interfície d'usuari, que després passarà a anomenar-se "Cor" i se li assignarà una textura de cor des de la carpeta Sprites/Objectes.

Canvieu el nom d'aquest node a Cor.

La imatge mostra el tauler d'arbre d'escenes d'un motor de joc, destacant el nou node CanvasLayer creat amb el seu node fill anomenat "Cor", que és un TextureRect utilitzat per representar la salut a la interfície d'usuari; aquesta estructura reflecteix la instrucció de la lliçó per niar el node Heart a CanvasLayer perquè es mostri correctament a la pantalla, amb el quadre vermell emfatitzant aquests dos nodes com el focus actual de la configuració.

Ara hem d'assignar una imatge a aquest node. En el Sistema de fitxers dock, navegueu a la carpeta Sprites > Objectes i localitzeu la textura del cor (p. ex., tile_0044.png).

La imatge mostra el tauler FileSystem d'un editor de motors de jocs, destacant el fitxer "tile_0044.png" situat a la ruta res://Sprites/Objects/, que s'identifica com la textura del cor utilitzada per a la visualització de la salut de la IU; una fletxa vermella apunta a aquest fitxer, que indica que s'ha de seleccionar i arrossegar al node Heart TextureRect tal com s'indica a la lliçó per assignar l'actiu visual correcte per a l'indicador de salut del jugador.

Arrossegueu la textura del cor cap a Textura propietat del node Heart a l'Inspector.

Al panell Inspector d'un editor de motors de jocs, se selecciona el node TextureRect anomenat "Cor", amb la seva propietat Texture ressaltada, mostrant una icona vermella d'art de píxel assignada com a textura, arrossegada des de la carpeta Sprites/Objectes segons les instruccions; per sota d'això, el mode Expandir està configurat a "Mantenir la mida", el mode estirament és "Escala" i tant Flip H com Flip V estan desactivats, reflectint la configuració inicial abans d'ajustar la configuració del disseny per corregir l'estirament.

Per defecte, la textura pot semblar estirada o comprimida a la vista de l'editor perquè TextureRect no canvia automàticament la mida per coincidir amb la relació d'aspecte de la imatge en totes les configuracions.

A la finestra 2D de l'editor del motor del joc, es mostra una textura de cor amb art de píxels dins d'un node TextureRect seleccionat anomenat "Cor", que està imbricat sota un CanvasLayer per a la representació d'IU; el cor apareix de mida correcta a 80 x 80 píxels tal com s'ha configurat a la secció Disseny de l'inspector > Transformació, i el seu quadre delimitador amb nanses de canvi de mida confirma que està activament seleccionat per editar-lo; a sobre del cor, hi ha una petita icona de node verd (probablement el CanvasLayer o el contenidor principal), que indica l'estructura jeràrquica, mentre que les línies de quadrícula tènues i les guies d'alineació suggereixen que l'escena s'està preparant per a la disposició de la interfície d'usuari, d'acord amb l'objectiu de la lliçó de configurar una pantalla de salut mitjançant TextureRects gestionat per un HBoxContainer.

Per solucionar-ho, hem de definir la mida explícitament. A l'Inspector, amplieu el Disseny pestanya i després la Transformar secció. Estableix el Mida fins a 80 x 80.

Al tauler d'inspector d'un editor de motors de joc, es mostra el node TextureRect seleccionat anomenat "Cor" amb la seva secció Layout expandida; una fletxa vermella apunta des de la capçalera "Disposició" fins a la subsecció Transformació, on la propietat Mida s'estableix en x: 80,0 px i y: 80,0 px, assegurant que la textura del cor es mostri com un quadrat perfecte tal com s'indica a la lliçó per a l'escalat adequat de la interfície d'usuari.

Això garanteix que el nostre cor es mostri com un quadrat perfecte.

A la finestra 2D del motor del joc, un node TextureRect seleccionat anomenat "Cor" mostra una textura de cor amb art de píxels, de mida adequada a 80 x 80 píxels tal com es configura a la secció Disseny de l'inspector > Transformació; el node està imbricat sota un CanvasLayer per a la representació de la interfície d'usuari i el seu quadre delimitador amb nanses de canvi de mida és visible, cosa que indica que està seleccionat actualment per editar-lo o col·locar-lo dins del disseny de la interfície d'usuari.

Us de contenidors per al disseny

Per gestionar de manera eficient diversos cors, utilitzarem un HBoxContainer (Horizontal Box Container). Aquest node disposa automàticament els seus fills en una fila horitzontal, la qual cosa ens estalvia d'haver de posicionar cada cor a mà.

Creeu un nou node HBoxContainer com a fill de CanvasLayer.

Al diàleg "Crea un nou node" d'un editor de motor de joc, l'usuari ha escrit "hbox" a la barra de cerca i seleccionat "HBoxContainer" de les coincidències a la categoria Control; una fletxa vermella apunta des de l'HBoxContainer ressaltat fins al botó "Crea" a continuació, que indica que el següent pas és crear una instancia d'aquest node contenidor per organitzar automàticament els elements de la interfície d'usuari secundaris horitzontalment, específicament per gestionar diverses icones de cor a la pantalla de salut tal com es descriu a la lliçó.

Canvieu el nom d'aquest node a HealthContainer.

La imatge mostra el tauler de l'arbre d'escenes d'un editor de motors de jocs, destacant el node HBoxContainer acabat de crear anomenat "HealthContainer", que és un fill de CanvasLayer i situat a sota de tres nodes TextureRect existents etiquetats "Heart", "Heart2" i "Heart3". Una fletxa vermella assenyala el node HealthContainer, emfatitzant la seva selecció com el següent pas per organitzar els elements de la interfície d'usuari de salut. Això reflecteix la instrucció de la lliçó per crear i canviar el nom de l'HBoxContainer a CanvasLayer per alinear automàticament les icones del cor horitzontalment, amb els passos posteriors que inclouen arrossegar-hi els nodes del cor i ajustar-ne el mode d'expansió per a un disseny adequat.

Hem d'assegurar-nos que el contenidor és prou alt com per contenir els nostres cors. A l'Inspector, sota Disseny > Transformar, estableix el Talla Y a 80.

Al tauler Inspector d'un editor de motors de jocs, es mostra el node seleccionat "HealthContainer" (un HBoxContainer) amb la seva secció Layout expandida; una fletxa vermella apunta des de la capçalera "Disposició" fins a la subsecció Transformació, on el valor Y de la propietat Mida s'estableix explícitament en 80,0 px, que coincideix amb l'alçada de les textures del cor que contindrà, mentre que el valor X es manté en 40,0 px; aquesta configuració garanteix l'alineació vertical amb els cors tal com s'indica a la lliçó per crear la interfície d'usuari de salut.

Ara, arrossegueu el vostre node Heart existent al HealthContainer per convertir-lo en fill.

La imatge mostra el tauler d'arbre d'escenes d'un motor de joc, destacant l'estructura jeràrquica on un node anomenat "HealthContainer" (un HBoxContainer) està imbricat a "CanvasLayer" i conté un node secundari anomenat "Heart" (un TextureRect), que il·lustra el pas de la lliçó per organitzar els elements de salut de la IU dins d'un contenidor per a l'alineació horitzontal automàtica.

Amb el cor dins del contenidor, hem d'ajustar com s'escala. Seleccioneu el node Cor i canvieu-lo Mode d'expansió propietat a Amplada d'ajust. Això indica que la textura s'escala horitzontalment per adaptar-se a les regles de disseny del contenidor mantenint la seva relació d'aspecte.

Al tauler Inspector d'un editor de motors de jocs, el node TextureRect seleccionat anomenat "Cor" es mostra amb la seva propietat "Mode d'expansió" ressaltada i s'estableix en "Amplada d'ajust", indicada per un quadre vermell i una fletxa; aquesta configuració garanteix que la textura del cor s'escala horitzontalment per adaptar-se al seu HBoxContainer principal, alhora que conserva la seva relació d'aspecte, com a part de la configuració de la pantalla de salut de la IU per alinear automàticament diversos cors.

Finalment, duplica el node Cor (Ctrl+D) dues vegades per crear un total de tres cors.

La imatge mostra el tauler d'arbre d'escenes d'un motor de joc, destacant l'estructura jeràrquica on el node "HealthContainer" (un HBoxContainer) està imbricat a "CanvasLayer" i conté tres nodes secundaris: "Heart", "Heart2" i "Heart3", tots ells nodes de TextureRect que representen cors de salut individuals a la IU; això reflecteix el pas de la lliçó de duplicar el node Heart per crear diversos cors gestionats automàticament per HBoxContainer per a l'alineació horitzontal.

L'HBoxContainer els organitzarà automàticament un al costat de l'altre.

A la finestra 2D del motor del joc, es mostren tres icones de cor amb art de píxels una al costat de l'altra sota un CanvasLayer, cadascuna representada mitjançant un node TextureRect anomenat "Heart", "Heart2" i "Heart3", tots relacionats amb un HBoxContainer anomenat "HealthContainer"; el cor més a la dreta està seleccionat, indicat per un quadre delimitador taronja i mànecs de canvi de mida, mostrant que està preparat per a la duplicació o l'ajust com a part de la configuració de la interfície d'usuari de salut, amb HealthContainer assegurant l'alineació horitzontal i la mida coherent (80x80 píxels) tal com s'ha configurat als passos anteriors.

Creació del text de la partitura

A continuació, afegirem una etiqueta de text per mostrar la puntuació del jugador. Això dóna als jugadors una clara sensació de progressió a mesura que recullen monedes al llarg del nivell. Per fer-ho, creeu un nou node Label com a fill de CanvasLayer.

Al diàleg "Crea un nou node" d'un editor de motor de joc, l'usuari ha escrit "la" a la barra de cerca i seleccionat el node "Etiqueta" de les coincidències a la categoria Control; una fletxa vermella apunta des de l'etiqueta ressaltada fins al botó "Crea" a continuació, indicant que el següent pas és crear una instancia d'aquest node per mostrar text sense format a la interfície d'usuari, tal com es descriu al pla de la lliçó per afegir una visualització de puntuació sota els cors de salut. El tauler de descripció confirma que Label és un control per mostrar text sense format amb opcions d'alineació i embolcall, però no admet el format de text enriquit com la negreta o la cursiva.

Canvieu el nom d'aquest node a ScoreText.

La imatge mostra el tauler de l'arbre d'escenes d'un motor de joc, destacant el node "ScoreText" (un node Label) imbricat sota el "CanvasLayer" i situat a sota del node "HealthContainer"; això reflecteix la instrucció de la lliçó per crear una visualització de text per a la puntuació del jugador com a part de la IU, sent "ScoreText" el nom designat per al node Label que mostrarà el valor de la puntuació.

A continuació, a l'Inspector, configureu el Text propietat per puntuar: 500. Això serveix com a marcador de posició perquè puguem veure com es veu a l'editor.

Al tauler Inspector d'un editor de motors de jocs, el node d'etiqueta seleccionat anomenat "ScoreText" es mostra amb la seva propietat Text ressaltada i s'estableix en "Puntuació: 500", que indica el valor de visualització de la puntuació actual per a la IU; això segueix les instruccions de la lliçó per crear un element de text sota CanvasLayer per mostrar la puntuació del jugador, situat a sota del HealthContainer.

Com veureu, la mida de lletra predeterminada és bastant petita.

A la finestra 2D del motor del joc, es mostren tres icones de cor amb art de píxels horitzontalment a la part superior de la pantalla sota un CanvasLayer, cadascuna representada mitjançant un node TextureRect anomenat "Heart", "Heart2" i "Heart3", tots relacionats amb un HBoxContainer anomenat "HealthContainer" per a l'alineació horitzontal automàtica; a sota d'ells, un node d'etiqueta anomenat "ScoreText" mostra el text "Puntuació: 500" dins d'un quadre delimitador rectangular amb nanses de canvi de mida visibles, indicant que està seleccionat i situat com a part de la IU per mostrar la puntuació actual del jugador.

Per estilitzar el text, localitzeu el Configuració de l'etiqueta propietat a l'inspector. Feu clic al menú desplegable (actualment <buit>) i seleccioneu Nova configuració de l'etiqueta.

Al tauler d'inspector d'un editor de motors de joc, es mostra el node d'etiqueta seleccionat anomenat "ScoreText" amb la seva propietat Text establerta a "Puntuació: 500"; una fletxa vermella apunta des de la secció "Configuració de l'etiqueta" fins al botó "Configuració de l'etiqueta nova", que indica que el següent pas és crear o assignar un recurs LabelSettings nou per personalitzar l'aparença del text per a la visualització de la puntuació de la IU.

A continuació, feu clic al nou recurs per ampliar-ne les propietats. Sota Font, posem el Mida fins a 38 píxels.

Al tauler d'inspector d'un editor de motors de joc, es mostra el node d'etiqueta seleccionat anomenat "ScoreText" amb la seva propietat Text establerta a "Puntuació: 500"; a la secció "Configuració de l'etiqueta" ampliada, un quadre vermell i una fletxa ressalten la subsecció "Tipus de lletra", que assenyala específicament el camp "Mida" que està establert en "38 px", que indica la configuració actual de la mida del tipus de lletra per a l'element d'IU de visualització de la puntuació.

Per fer que el text aparegui contra el fons, afegim una ombra. Amplia el Ombra secció, augmentar la Mida a 6 i ajusteu el Color alfa (transparència) per fer-lo visible (el valor exacte depèn de tu i de la teva estètica).

Al tauler d'inspector d'un editor de motors de joc, es mostra el node d'etiqueta seleccionat anomenat "ScoreText" amb la seva propietat Text establerta a "Puntuació: 500"; a la secció "Configuració de l'etiqueta" ampliada, una fletxa vermella apunta des de la subsecció "Tipus de lletra" fins a la subsecció "Ombra", que es ressalta amb un quadre vermell, que mostra la mida de l'ombra establerta a "6 px" i el color configurat a transparent (indicat per un patró de tauler d'escacs), amb valors de compensació de x: 1,0 px i y: il·lustració de l'efecte visual de la lliçó 1.0 per a la configuració de la lliçó. visualització de la puntuació.

Col·loqueu HealthContainer i ScoreText a la cantonada superior esquerra de la pantalla. Si executeu el joc ara, hauríeu de veure la vostra interfície d'usuari superposada al joc.

Aquesta imatge mostra la vista dins del joc d'un joc de plataformes en 2D durant la depuració, mostrant els elements de la interfície d'usuari completats de la lliçó: tres icones de cor de pixel-art disposades horitzontalment a la cantonada superior esquerra, que representen la salut del jugador, i a sota, el text "Puntuació: 500" representat mitjançant un node d'etiqueta, tots dos situats en un CanvasLayer sense importar el moviment de la càmera a la pantalla. El món del joc visible a sota inclou un personatge de pell verda a l'aire, plataformes flotants amb tapes d'herba, monedes col·leccionables i enemics semblants a ratpenats contra un cel blau clar amb pins estilitzats, cosa que il·lustra que la interfície d'usuari superposa amb èxit el joc sense veure's afectada pel posicionament espacial de l'escena.

Connectar la logica amb senyals

La nostra interfície d'usuari sembla bé, però ara mateix és completament estàtica. Perquè sigui funcional, hem d'actualitzar la pantalla sempre que canviï la salut o la puntuació del jugador. Farem servir signals for this purpose. Signals let the player script broadcast when something happens, and the UI script can listen and react, keeping both scripts cleanly separated.

Actualitzacio de l'script del jugador

Per començar, obriu l'script player.gd. Hem de definir dos senyals personalitzats a la part superior del fitxer. La paraula clau del senyal declara un esdeveniment amb nom al qual es poden subscriure altres nodes:

signal 
OnUpdateHealth (health : int)
signal 
OnUpdateScore (score : int)

Nota de Godot: senyals personalitzats

Els senyals a Godot implementen el patró d'observador. Qualsevol node pot definir un senyal amb el senyal SignalName(args) i emetre-lo amb SignalName.emit(values). Altres nodes es subscriuen mitjançant source.SignalName.connect(callback). Això permet que els sistemes es comuniquin sense referències directes entre ells, mantenint el vostre codi modular.

Els nodes integrats inclouen molts senyals predefinits (com body_entered a Area2D). Els senyals personalitzats amplien aquest sistema per a la vostra pròpia lògica de joc.

Més informació: Senyals (https://docs.godotengine.org/en/4.6/tutorials/scripting/gdscript/gdscript_b asics.html#signals)

A continuació, hem d'emetre aquests senyals quan canvien els valors rellevants. Actualitzem primer la funció take_damage per emetre OnUpdateHealth:

func 
take_damage (amount : int): health -= amount OnUpdateHealth.emit(health)
if 
health <= 0: call_deferred("game_over")

A continuació, actualitzarem la funció augmente_score per emetre OnUpdateScore:

func 
increase_score (amount : int): PlayerStats.score += amount OnUpdateScore.emit(PlayerStats.score)

Ara, sempre que el jugador fa malbé o recull una moneda, aquests senyals transmetran els nous valors.

Creació de l'script d'interfície

Per al següent pas, necessitem un script per gestionar els elements de la IU. Seleccioneu el

CanvasLayer i adjunteu un script nou anomenat player_ui.gd.

Aquesta imatge mostra el diàleg "Adjunta l'script del node" en un editor de motor de joc, on l'usuari està configurant un nou GDScript per a un node. L'script està configurat per heretar de "CanvasLayer", tal com es destaca en un quadre vermell, assegurant que funciona dins de la capa d'IU. El camí del fitxer de l'script s'especifica com a "res://Scripts/player_ui.gd", també inclòs en un quadre vermell, que indica on es desarà l'script. A continuació, dos missatges d'estat verd confirmen que la ruta de l'script és vàlida i que es crearà un fitxer de script nou. Una gran fletxa vermella apunta cap avall al botó "Crea", que es mostra de manera semblant en vermell, indicant el pas final per generar el fitxer d'script. Aquesta configuració s'alinea amb l'objectiu de la lliçó de crear un sistema d'IU connectant la lògica al node CanvasLayer.

En aquest script, necessitem referències als nostres nodes d'IU i al reproductor. També crearem una matriu per contenir les nostres icones del cor perquè puguem mostrar-les o amagar-les en funció de la salut actual del jugador.

Recordeu que el nostre CanvasLayer és un fill del nostre node Player, així que podem utilitzar

get_parent() per obtenir la referència al jugador. Afegiu les variables següents a player_ui.gd:

extends 
CanvasLayer
@onready 
var 
health_container = $HealthContainer 
var 
hearts : Array = []
@onready 
var 
score_text : Label = $ScoreText @onready 
var 
player = get_parent()

Implementació de funcions d'actualització

Ara crearem dues funcions per gestionar les actualitzacions visuals.

La funció _update_hearts fa un bucle a través de la matriu d'icones del cor i compara cada índex amb el valor de salut actual. Si l'índex és inferior a la salut, aquest cor es manté visible; en cas contrari queda amagat.

# Show or hide each heart icon based on current health
func 
_update_hearts(health : int):
for 
i 
in 
range(len(hearts)): hearts[i].visible = i < health

La funció _update_score simplement actualitza el text de l'etiqueta.

func 
_update_score(score : int): score_text.text = "Score: " + str(score)

Connectar-ho tot a _ready

Finalment, hem de connectar-ho tot quan comenci el joc. En el

funció _ready, farem:

  1. Ompliu la matriu de cors amb els fills de HealthContainer.
  2. Connecteu els senyals del reproductor a les nostres funcions d'actualització.
  3. Truqueu immediatament a les funcions d'actualització una vegada per assegurar-vos que la interfície d'usuari mostra els valors inicials correctes.
func 
_ready():

hearts = health_container.get_children()

# Subscribe to the player's health and score signals 
player.OnUpdateHealth.connect(
_update_hearts
) player.OnUpdateScore.connect(
_update_score
)
# Show the correct starting values on the first frame

_update_hearts(player.health)

_update_score(PlayerStats.score)

Provar la interfície

Executeu el joc i proveu la vostra nova interfície d'usuari. Els cors i l'etiqueta de la puntuació haurien d'aparèixer a l'extrem superior esquerre de la pantalla, superposant el joc.

Quan reps dany d'un enemic, els cors haurien de desaparèixer un a un.

La imatge mostra un joc de plataformes en 2D de Godot en mode de depuració, que mostra els elements de la interfície d'usuari del jugador tractats a la lliçó: dues icones de cor vermell que representen la salut i una etiqueta "Puntuació: 500" a la cantonada superior esquerra, totes dues representades a la pantalla com a part de la interfície d'usuari de CanvasLayer. L'escena inclou un personatge verd pixelat a peu sobre una plataforma de terra, amb plataformes addicionals, monedes de col·lecció i sprites enemics visibles al nivell. Aquest visual confirma l'èxit d'implementació del sistema de visualització de la salut i la puntuació que s'està ensenyant, concretament el HealthContainer amb icones de cor i l'etiqueta ScoreText, a les quals es fa referència al codi d'script que es mostra a la lliçó (per exemple, @onready var health_container = $HealthContainer, @onready var score_text : Label = $ScoreText). No hi ha missatges d'error ni de sortida de la consola visibles; el focus se centra en els comentaris de la interfície d'usuari en directe vinculats a l'estat del jugador.

Quan recolliu monedes, l'etiqueta de puntuació s'hauria d'actualitzar a l'instant.

Aquesta imatge mostra el joc de plataformes Godot 2D en mode de depuració, mostrant els elements de la interfície d'usuari del jugador que s'estan implementant a la lliçó: tres icones de cor vermells pixelats que representen la salut total i una etiqueta "Puntuació: 5" a la cantonada superior esquerra, totes dues representades a la pantalla com a part de la interfície d'usuari de CanvasLayer; l'escena inclou un personatge verd pixelat en una plataforma de terra amb una altra plataforma i una moneda a la dreta, sobre un fons blau clar amb arbres estilitzats, que confirma visualment que els components de la interfície d'usuari (health_container, matriu de cors, score_text) a què es fa referència a la configuració de l'script estan correctament posicionats i actualitzats dinàmicament.

Ara teniu una interfície d'usuari totalment funcional que respon als esdeveniments de joc en temps real. En el següent capítol, ens centrarem a polir la sensació del joc afegint comentaris visuals i efectes de so.

Efectes visuals i àudio

En aquest capítol, ens centrarem en la "sensació de joc", la retroalimentació tàctil i visual que fa que un joc sigui satisfactori per jugar. Actualment, el nostre joc funciona correctament: el jugador pot moure's, recollir monedes i fer mal. Tanmateix, el feedback és mínim. Quan el jugador rep un cop, l'única indicació és un número que canvia a la interfície d'usuari.

Millorarem aquesta experiència mitjançant la implementació d'efectes visuals com un flaix danyat i un moviment de pantalla per donar pes als impactes. També millorarem l'entorn afegint un fons de paral·laxi que crea una sensació de profunditat. Finalment, integrarem l'àudio per proporcionar comentaris auditius per als esdeveniments clau del joc.

Visuals de dany

La nostra primera tasca és millorar el feedback quan el jugador rep danys. Un bon feedback visual ajuda el jugador a entendre què està passant a l'instant, sense haver de mirar una barra de salut. Perquè aquests moments tinguin impacte, implementarem dos efectes: un flaix visual on el personatge es torna vermell i un sacsejada de la pantalla que sacseja la càmera.

Implementacio del flaix de dany

El flash de danys és un clàssic de videojocs que comunica clarament la lesió. Això ho aconseguirem manipulant la propietat de modular de l'esprit del jugador.

Obriu l'script player.gd. Crearem una nova funció anomenada

_damage_flash que canvia el color del sprite a vermell i després el torna a blanc al cap d'una fracció de segon.

Afegiu la funció següent a la part inferior del vostre script:

# Briefly tint the sprite red to signal damage
func 
_damage_flash(): sprite.modulate = Color.RED

await get_tree().create_timer(0.05).timeout sprite.modulate = Color.WHITE

En aquesta funció:

Nota de Godot: la propietat modular

Cada node CanvasItem (que inclou tots els nodes 2D com Sprite2D i Control) té una propietat de modulació. Aquest és un valor de Color que es multiplica amb els colors originals del node en temps de renderització. Configurant-lo a Color.RED tenyeix el sprite de vermell; establir-lo a Color (1, 1, 1, 0,5) el fa semitransparent.

Color.WHITE (per defecte) deixa els colors originals sense canvis.

Com que modulate s'hereta, establir-lo en un node pare també matisa tots els seus fills. Això fa que sigui fàcil de flashejar un caràcter sencer (sprite, partícules i tot) en una única línia de codi.

Més informació: CanvasItem.modulate (https://docs.godotengine.org/en/4.6/classes/class_canvasitem.html#class-ca nvasitem-property-modulate)

Per activar aquest efecte, hem de cridar la funció sempre que el jugador rep danys. Localitzeu la funció take_damage al vostre script i afegiu la trucada a

_damage_flash():

_damage_flash()

Ara, quan el jugador xoca amb un enemic, el sprite parpellejarà breument en vermell, proporcionant una confirmació visual immediata de l'impacte.

La imatge mostra un joc de plataformes en 2D Godot en mode de depuració, que il·lustra l'efecte de flaix de danys que es parla a la lliçó: el personatge del jugador (un quadrat vermell) parpelleja visiblement en vermell després de patir danys, mentre que dues icones de cor i "Puntuació: 1" apareixen a la cantonada superior esquerra. L'escena inclou plataformes flotants, enemics amb ales i arbres de fons, però el focus visual clau és l'esprit del jugador tenyit de vermell, que demostra l'efecte de la funció _damage_flash tal com es descriu al tutorial, on sprite.modulate s'estableix temporalment en Color.RED i després torna a Color.WHITE després d'un retard de 0,05 segons. No hi ha cap codi ni sortida de consola visible; la imatge serveix com a resultat visual de la implementació del sistema de retroalimentació de danys.

Implementació del tremolor de camera

A continuació, afegirem un efecte de sacsejada de pantalla. Això afegeix una sensació d'impacte visceral al dany, reforçant que alguna cosa important acaba de passar. Implementarem això adjuntant un script a la nostra càmera que compensa ràpidament la seva posició quan s'activa.

En el Jugador escena, seleccioneu el node Camera2D. Adjunteu-hi un script nou i anomeneu-lo camera_shake.gd.

Aquesta imatge mostra el diàleg "Adjuntar script de node" a Godot, on s'està creant un script nou per a un node Camera2D; el camp "Hereta" s'estableix a "Camera2D", i el "Camí" s'especifica com a "res://Scripts/camera_shake.gd", amb missatges de validació que confirmen que el camí és vàlid i que es crearà un fitxer nou; una fletxa vermella assenyala el botó "Crear" ressaltat, que indica el següent pas per generar el fitxer de script com a part de la implementació de l'efecte de sacsejada de la pantalla quan el jugador pateix danys.

Obriu l'script camera_shake.gd i substituïu-ne el contingut pel codi següent:

extends 
Camera2D
var 
intensity : float = 0
func 
_ready():
# Listen for damage events from the parent Player node

get_parent().OnUpdateHealth.connect(_danyar_agitar)

# Kick off a shake whenever health changes
func 
_damage_shake(health : int): intensity = 3
func 
_process(delta):
if 
intensity > 0:
# Gradually reduce the shake strength each frame 
intensity = lerpf(intensity, 0, delta * 10) offset = _get_random_offset()
# Generate a random camera offset within the current intensity range
func 
_get_random_offset() -> Vector2:
var 
x = randf_range(-intensity, intensity) 
var 
y = randf_range(-intensity, intensity) 
return 
Vector2(x, y)

Així és com funciona la lògica de sacsejada:

Torna a provar el joc. Ara, prendre danys hauria de sentir-se molt més significatiu amb el flaix vermell i la sacsejada de la càmera treballant a l'uníson.

Evitar la caiguda infinita

Com a darrer pas per a la lògica del jugador, abordem un problema comú als jocs de plataformes: caure del mapa. Actualment, si el jugador cau a una fossa, cau per sempre. Afegir una comprovació de seguretat evita que el joc es bloquegi en aquesta situació.

Afegirem una comprovació a l'script del reproductor per detectar si han caigut per sota d'un determinat llindar. Obriu player.gd i modifiqueu la funció _process per incloure aquesta comprovació:

if 
global_position.y > 200: game_over()

Aquesta lògica senzilla comprova la posició vertical del jugador. Si global_position.y supera els 200 (que està per sota del nivell del nostre nivell), activem la funció game_over per restablir el nivell.

Paral·laxi del fons

Ara centrem la nostra atenció en el medi ambient. Un fons estàtic pot fer que fins i tot un nivell ben dissenyat se senti pla. El nostre fons actual pot no cobrir tot el nivell si el jugador es mou molt cap a la dreta, tampoc. Arreglarem la mida, enrajolarem el fons per cobrir el nivell i implementarem un efecte de paral·laxi per simular la profunditat.

Canviar la mida i la posició

Abans d'enrajolar el fons, ens hem d'assegurar que cada sprite té la mida adequada i està correctament alineat. Seleccionem el BackgroundSprite a l'escena principal.

A l'Inspector, aneu a Transformar secció. Estableix el Escala a (0,5, 0,5) per reduir la pixelació i coincidir amb la resolució del nostre joc. Estableix el Posició a (0, 0) per centrar-lo.

La imatge mostra el tauler d'inspector d'un Sprite2D anomenat "BackgroundSprite", destacant la secció Transformació on la posició s'estableix a (x: 0,0 px, y: 0,0 px) i l'escala s'estableix a (x: 0,5, y: 0,5), alineant-se amb les instruccions de la lliçó per centrar i canviar la mida de l'sprillax per a la configuració visual i polir.

Creació d'un fons repetible

Per assegurar-nos que el fons cobreix tot el nivell, hem de crear una franja perfecta d'imatges de fons.

Dupliqueu el BackgroundSprite (Ctrl+D). Mou el duplicat cap a la dreta ajustant la seva posició. Per als actius proporcionats en aquest projecte, un desplaçament de 512 píxels funciona perfectament.

Repetiu aquest procés, creant duplicats a les posicions +512, +1024, -512, etc., fins que el fons ocupi tota la longitud del vostre nivell.

La imatge mostra una escena de joc en 2D a l'editor de Godot, que mostra un fons de rajoles horitzontals compost per un cel blau clar que es repeteix i sprites blancs de muntanya, que s'estenen pel nivell per evitar retalls. Un quadre de selecció rosa destaca un grup d'elements en primer pla, com ara icones de cor vermell i caixes marrons, amb l'etiqueta "Puntuació: 500" visible a sota. L'escena es veu amb un zoom del 38,6%, amb línies de quadrícula i eixos de coordenades (X i Y) visibles per a referència espacial. Aquesta configuració reflecteix l'enfocament de la lliçó a crear un fons de rajoles sense fissures que més tard s'animarà amb un efecte de paral·laxi agrupant els sprites sota un node "Fons" i el moviment d'script mitjançant "background_parallax.gd".

Organitzacio dels nodes del fons

Tenir diversos nodes de sprites que desordena l'arbre de l'escena és desordenat. Agrupem-los sota un sol progenitor perquè siguin més fàcils de gestionar i es puguin moure junts.

Creeu un nou Node2D i anomeneu-lo Fons.

Aquesta imatge mostra el diàleg "Crea un nou node" de Godot, on l'usuari ha escrit "node2d" a la barra de cerca i seleccionat la classe "Node2D" de la llista de coincidències; una fletxa vermella apunta des del Node2D seleccionat al botó "Crear", que indica el següent pas per crear un node pare anomenat "Fons" per organitzar els sprites de fons tal com es descriu a la lliçó per implementar el desplaçament de paral·laxi.

Al tauler de l'arbre de l'Escena de Godot, el nou node "Fons" Node2D es ressalta amb un quadre vermell i s'assenyala amb una fletxa vermella, que indica que s'ha afegit com a node pare per organitzar els sprites de fons; Els nodes germans visibles inclouen "Main", "Player", "Coins", "Enemies" i "EndFlag", que confirma l'estructura jeràrquica per implementar el fons de paral·laxi tal com es descriu a la lliçó.

Hem d'assegurar-nos que el node Fons està situat a (0, 0).

Al tauler de l'inspector de Godot, es mostra la secció Transformació d'un Node2D anomenada "Background", amb la seva propietat Posició ressaltada (específicament, les coordenades x i y s'estableixen en 0,0 px), alineant-se amb la instrucció de la lliçó per centrar el node de fons després d'agrupar els sprites enrajolats a sota per a la implementació de paral·laxi.

Un cop col·locats correctament, seleccioneu tots els vostres nodes de sprite de fons i arrossegueu-los al node Fons per fer-los fills.

Al tauler de l'arbre de l'Escena de Godot, el Node2D "Background" s'amplia per revelar els seus nodes fills: "BackgroundSprite", "BackgroundSprite4", "BackgroundSprite5", "BackgroundSprite2" i "BackgroundSprite3", confirmant que els sprites de fons s'han agrupat amb èxit sota els elements "de fons" organitzats com a fons ordenats. al joc de plataformes 2D.

Implementació de l'script de paral·laxi

La paral·laxi és una tècnica on les capes de fons es mouen més lentament que les capes de primer pla, creant una il·lusió de distància. Fins i tot un sol

La capa de moviment més lent afegeix una sorprenent quantitat de profunditat a una escena 2D. Implementarem un script senzill per gestionar-ho.

Adjunteu un nou script al node Fons anomenat background_parallax.gd.

Aquesta imatge mostra el diàleg "Adjunta l'script del node" de Godot, on s'està creant un nou GDScript per a un Node2D per implementar l'efecte de fons de paral·laxi; el camp Ruta mostra "res://Scripts/background_parallax.gd", indicant la ubicació i el nom del fitxer de l'script tal com s'especifica a la lliçó, i una fletxa vermella apunta des d'aquest camí al botó "Crea" ressaltat, que indica el següent pas per generar el fitxer de l'script.

Afegiu el codi següent a l'script:

extends 
Node2D
# Controls how much slower the background moves relative to the player (0.7 = 70% speed)
var 
parallax : float = 0.7 @onready 
var 
player = $"./Player"
func 
_process (delta):
# Offset the background by a fraction of the player's position to simulate depth

global_position = player.global_position * parallax

Això és el que fa el codi:

Deseu l'script i executeu el joc. A mesura que mous el personatge, ara el fons hauria de desplaçar-se suaument a un ritme diferent al de les plataformes, donant a l'escena una bona sensació de profunditat.

Àudio

Les imatges són només la meitat de l'experiència. Per polir realment el joc, necessitem so. La retroalimentació d'àudio reforça el que el jugador veu a la pantalla i fa que accions com recollir monedes o rebre un cop se sentin realment gratificants. Implementarem efectes de so per recollir monedes i fer malbé mitjançant el node AudioStreamPlayer que hem afegit anteriorment.

Inspeccio dels recursos d'àudio

Comencem per verificar els sons amb els quals hem de treballar. Navegueu a la carpeta d'àudio del vostre sistema de fitxers. Hauríeu de veure dos fitxers: Coin.wav i Take Damage.wav.

La imatge mostra el moll del sistema de fitxers del motor Godot, destacant la carpeta "Àudio" a "res://", que conté dos fitxers d'efectes de so: "coin.wav" i "take_damage.wav", els actius exactes a què es fa referència a la lliçó per reproduir àudio en recollir una moneda o fer malbé. Els camins dels fitxers que es mostren coincideixen amb els utilitzats als exemples d'script (p. ex., preload ("res://Audio/take_damage.wav")), confirmant la seva ubicació per a la integració amb el node AudioStreamPlayer a l'escena del reproductor.

Nota de Godot: precàrrega vs càrrega

preload("res://path") loads a resource at compile time, embedding it into the script. The resource is available instantly with zero load delay, which is perfect for small assets like sound effects and textures that you know you will need. load("res://path") loads at runtime and can accept variable paths, but introduces a brief delay the first time it is called.

Per als actius del joc que s'utilitzen sempre (com els nostres danys i els sons de les monedes),

preload is the right choice.

Més informació: Referència de GDScript (https://docs.godotengine.org/en/4.6/tutorials/scripting/gdscript/gdscript_b asics.html#preload)

Reproducrem aquests sons mitjançant el node AudioStreamPlayer situat al nostre Jugador escena.

Al moll de l'Escena de l'Editor de Godot, el node Player s'amplia per revelar els seus nodes fills, amb el node AudioStreamPlayer ressaltat i emfatitzat per un quadre vermell i una fletxa, que indica que és el node utilitzat per reproduir efectes de so al joc; això coincideix amb la instrucció de la lliçó per utilitzar $AudioStreamPlayer a l'script player.gd per activar esdeveniments d'àudio com ara fer malbé o recollir monedes.

Actualitzacio de l'script del jugador

Hem de modificar player.gd per carregar aquests sons i reproduir-los en els moments adequats.

Primer, anem a obtenir una referència al reproductor d'àudio. Afegiu aquesta variable a la part superior del vostre script:

@onready 
var 
audio : AudioStreamPlayer = $AudioStreamPlayer

A continuació, hem de carregar prèviament els fitxers de so a la memòria. Això garanteix que juguin a l'instant sense cap retard de càrrega. Afegeix aquestes variables:

var 
take_damage_sfx : AudioStream = preload("res://Audio/take_damage.wav")
var 
coin_sfx : AudioStream = preload("res://Audio/coin.wav")

Ara, creem una funció d'ajuda per reproduir un so específic. Aquesta funció assignarà el flux de so al reproductor i activarà la reproducció.

# Play a one-shot sound effect through the shared AudioStreamPlayer
func 
play_sound(sound : AudioStream): audio.stream = sound audio.play()

Activar els sons

Finalment, hem de cridar play_sound a les nostres funcions de joc existents. Aquí és on tot s'uneix: ara cada acció produirà una resposta tant visual com auditiva.

Actualitzeu la funció take_damage per reproduir el so de dany:

func 
take_damage(amount : int): health -= amount OnUpdateHealth.emit(health)

_damage_flash() play_sound(take_damage_sfx)

# Defer game_over to avoid freeing nodes mid-physics step
if 
health <= 0: call_deferred("game_over")

A continuació, actualitzeu la funció augmente_score per reproduir el so de la moneda:

func 
increase_score(amount : int): PlayerStats.score += amount OnUpdateScore.emit(PlayerStats.score) play_sound(coin_sfx)

Reprodueix àudio

Executeu el joc per darrera vegada. Recull una moneda i topa amb un enemic. Hauríeu d'escoltar els efectes de so corresponents, acompanyats del flaix visual i el moviment de la pantalla que hem implementat anteriorment.

Amb aquestes addicions, el vostre joc hauria de sentir-se molt més polit i atractiu. En el següent capítol, treballarem per afegir un nivell addicional al nostre joc per mantenir-lo atractiu per als jugadors.

Disseny de nivells

En aquest capítol, ampliarem el nostre joc creant un segon nivell. Un joc de plataformes necessita més d'una etapa per mantenir els jugadors compromesos i, gràcies al nostre disseny modular, afegir contingut nou és un procés senzill. Duplicarem el nostre nivell existent, modificarem el seu disseny i imatges per crear un tema desert i ajustarem els comportaments dels enemics per oferir nous reptes.

També abordarem un error crític relacionat amb la nostra bandera final. Actualment, la transició d'escenes durant un esdeveniment de col·lisió pot provocar errors al motor físic de Godot. Ho presentarem com un repte que heu de resoldre, seguit d'un recorregut detallat de la solució.

Creacio de nivells nous

La manera més eficient de crear contingut addicional és basar-nos en el que ja tenim. Els desenvolupadors de jocs professionals sovint dupliquen i reelaboren els nivells existents en lloc de començar des de zero, ja que l'estructura bàsica (arbre de l'escena, capes de fons, capes de rajoles) ja està provada i funcionant. Seguirem el mateix enfocament: duplicarem el nostre primer nivell i transformarem-lo en alguna cosa nova.

Duplicar el primer nivell

El nostre primer pas és fer una còpia de l'escena de nivell existent. Això ens proporciona un punt de partida totalment funcional que podem transformar en una experiència totalment nova.

Per començar, navegueu a Escenes carpeta al moll FileSystem. Feu clic amb el botó dret a sobre Nivell 1 (o level_1.tscn) i seleccioneu Duplicat.

Imatge

Godot demanarà un nom per al nou fitxer. Canvieu el nom a level_2.tscn i feu clic D'acord.

La imatge mostra un diàleg "Duplicar fitxer" d'un editor de desenvolupament de jocs, on l'usuari està canviant el nom d'un fitxer d'escena copiat. El camí base es mostra com a "res://Scenes" i el camp "Nom" conté "level_2.tscn", que indica que el fitxer duplicat s'està canviant de nom per representar el segon nivell. Un missatge de validació verd a continuació confirma que "El nom del fitxer és vàlid" i una fletxa vermella apunta al botó "D'acord" ressaltat, indicant que l'usuari ha de confirmar el canvi de nom per continuar amb la creació del nivell 2 tal com es descriu a la lliçó.

Seguiu endavant i feu doble clic al fitxer nou per obrir-lo. Ara teniu una còpia exacta del nivell 1 que serveix de base per al nivell 2.

Modificar el fons

Per donar-li al nou nivell una identitat diferent, canviarem l'entorn d'un bosc a un desert. Seleccioneu el BackgroundSprite node (i qualsevol altre node de fons que pugueu haver agrupat). A l'Inspector, podem arrossegar l'esprit de fons del desert des del Sprites carpeta a la Textura propietat.

Al tauler FileSystem de l'editor Godot, el fitxer "backgroundDesert.png" està seleccionat a la carpeta "res://Sprites/Backgrounds", i al panell Inspector, la propietat "Textura" d'un node Sprite2D anomenat "BackgroundSprite" s'està assignant aquesta imatge de fons del desert, enllaçant visualment la selecció de fitxers amb la seva aplicació a l'escena del bosc com a nivell de creació. 2.

Aquest senzill canvi diferencia immediatament el to visual del nivell.

A la vista d'escena 2D de l'editor Godot, l'usuari està editant "level_2(*)", amb la finestra gràfica ampliada al 110,0% i mostrant un disseny de nivell temàtic del desert amb plataformes d'art de píxels, monedes, enemics i tres indicadors de salut en forma de cor per sobre d'una etiqueta de text "Puntuació: 500"; el mapa de fitxes s'ha modificat des del tema del bosc original mitjançant fitxes del desert, i els elements del joc com monedes i enemics es col·loquen a través del terreny, amb un quadre de selecció visible al voltant d'una part de l'estructura de la plataforma, que indica l'edició activa de la ubicació o les propietats del node com a part de la personalització del nivell duplicat.

Editeu el TileMap

Amb els antecedents al seu lloc, el següent pas és redissenyar el disseny físic perquè el nivell 2 ofereixi els seus propis reptes de plataformes. Seleccioneu el TileMapLayer node al moll d'escena.

Al tauler Escena de l'editor Godot, la jerarquia de nodes per a "level_2(*)" es mostra sota el node arrel "Principal", amb el node "TileMapLayer" ressaltat i tancat en un quadre vermell, indicant que és el focus actual per a l'edició; una fletxa vermella apunta des del node "BackgroundSprite5" fins a "TileMapLayer", guiant visualment l'usuari a seleccionar aquest node a continuació com a part de la modificació de la disposició de les rajoles del nivell per al nou nivell 2 de tema desert.

Volem netejar l'antic traçat del bosc. Seleccioneu el Goma d'esborrar a la barra d'eines TileMap (o premeu E). Per accelerar les coses, podeu utilitzar el Rectangle eina de selecció per esborrar grans blocs de fitxes alhora.

A la interfície d'edició de TileMap de l'editor de Godot, l'usuari està modificant la disposició de "level_2(*)" seleccionant eines per editar el mapa de mosaic: l'eina rectangle amb contorn vermell (per seleccionar o esborrar regions rectangulars) i l'eina llapis (per col·locar fitxes) es destaquen a la barra d'eines sota la finestra gràfica; la finestra mostra un nivell d'art de píxels amb temàtica del desert amb plataformes, monedes, enemics, tres icones de cor i una etiqueta "Puntuació: 500", superposada amb una quadrícula i un rectangle de selecció vermell que indica l'àrea de dibuix actual (61x19 fitxes a la posició 52,11); el tauler TileMap a la part inferior mostra les fitxes de temàtica del desert disponibles a "Rajoles base" i "Rajoles alternatives", confirmant que l'usuari està substituint les fitxes del bosc originals per actius del desert com a part de la creació d'un disseny únic de nivell 2.

Un cop el llenç estigui clar, canvieu a Pintar (o premeu P) i seleccioneu les fitxes amb temàtica del desert del vostre TileSet. Dibuixa un disseny nou que ofereixi diferents reptes de plataformes en comparació amb el primer nivell.

A la interfície d'edició de TileMap de l'editor Godot, l'usuari col·loca fitxes amb temàtica del desert per dissenyar el nivell 2; l'eina llapis està activa (indicada per la icona ressaltada a la barra d'eines) i s'està seleccionant una fitxa a les coordenades d'Atles (1, 3) del conjunt de quadres, amb la seva font etiquetada com a "0" i el valor alternatiu "0", mentre que un quadre vermell destaca l'àrea de destinació de la quadrícula del mapa de fitxes on s'estan dibuixant noves fitxes per construir el disseny de nivell.

No dubteu a experimentar amb la verticalitat, les mides dels buits i la col·locació de la plataforma per crear un nivell que sigui divertit de navegar.

A la vista d'escena 2D de l'editor Godot de "level_2(*)", la finestra s'amplia fins al 146,4%, mostrant un nivell de tema desert amb plataformes d'art de píxels, tres indicadors de salut en forma de cor i una etiqueta "Puntuació: 500"; Les línies de quadrícula visibles i els contorns de selecció indiquen l'edició activa dels nodes del mapa de fitxes i dels elements del joc, com ara monedes i enemics, que reflecteixen l'enfocament de la lliçó a modificar els dissenys de nivell duplicats i a posicionar els components del joc després de canviar el fons i el conjunt de fitxes perquè coincideixin amb el tema del desert.

Posicionar elements del joc

Amb el terreny establert, hem de col·locar els nostres objectes interactius perquè el nivell sigui jugable. Cada element (la bandera final, les monedes i els enemics) té un propòsit de joc específic, de manera que la seva ubicació afecta directament la sensació del nivell.

Bandera final

Mourem el EndFlag node fins al final del vostre nou camí. Això defineix l'objectiu per al qual està treballant el jugador.

A la vista d'escena 2D de l'editor Godot de "level_2(*)", ampliada al 313,8%, un quadre vermell destaca la bandera final i la moneda adjacent col·locades damunt d'una plataforma de rajoles amb temàtica del desert; això il·lustra el pas de col·locar els elements essencials del joc després de modificar el mapa de fitxes, amb siluetes de palmeres de fons i un terreny llunyà visibles per reforçar el tema del desert presentat anteriorment a la lliçó.

Monedes

A continuació, reposicioneu les monedes per guiar el jugador a través del nivell o recompenseu l'exploració. Si necessiteu més monedes, simplement dupliqueu un node de moneda existent (Ctrl + D). Si en tens massa, elimina els extres.

A la vista d'escena 2D de l'editor Godot de "level_2(*)" amb un zoom del 214,4%, les fletxes vermelles indiquen la col·locació dels nodes de monedes a sobre de plataformes de fitxes amb temàtica del desert, demostrant el pas de posicionar els elements del joc col·leccionables després de l'edició del mapa de les fitxes; l'escena inclou tres indicadors de salut del cor amb art de píxels i una etiqueta "Puntuació: 500", amb línies de quadrícula visibles per ajudar l'alineació, reforçant l'enfocament del tutorial a modificar els dissenys de nivell duplicats per a la varietat de joc.

Enemics

Finalment, col·loquem els enemics. Com que hem exportat les variables de moviment al nostre script enemy.gd, podem personalitzar cada instància de l'enemic directament a l'Inspector sense tocar cap codi.

Per exemple, podeu fer que un enemic es mogui horitzontalment en lloc de verticalment configurant-lo Direcció de moviment El valor Y a 0 i el seu valor X a 300. També podeu ajustar el Velocitat de moviment per crear amenaces més ràpides o més lentes.

Al panell Inspector de l'editor Godot, les propietats d'un node "Enemic4" s'estan configurant per ajustar el seu comportament de moviment per al nivell 2; el vector "Direcció de moviment" s'estableix a x=300,0 i y=0,0, que indica un moviment horitzontal cap a la dreta, mentre que "Velocitat de moviment" està establert a 35,0, controlant la rapidesa amb què es mou l'enemic. Aquests paràmetres es destaquen en un quadre vermell per emfatitzar el seu paper a l'hora de modificar els patrons de moviment dels enemics com a part del disseny de nivells.

Aquesta flexibilitat us permet crear diferents escenaris de joc utilitzant la mateixa escena enemiga.

A la vista de l'escena 2D de l'editor Godot de "level_2(*)" amb un zoom del 161,1%, es mostra el disseny de nivell completat amb temàtica del desert, que inclou plataformes d'art de píxels construïts a partir de fitxes del desert, tres indicadors de salut en forma de cor situats per sobre d'una etiqueta de text "Puntuació: 500" i elements del joc col·locats estratègicament, com ara monedes, una bandera i una plataforma llunyana; les línies de quadrícula visibles i els contorns de selecció indiquen una edició activa, confirmant la duplicació i modificació correcta del nivell 1 en un nivell 2 diferent amb una nova geometria del mapa de fitxes i objectes de joc posicionats tal com es descriu a la lliçó.

Canviar els colors del fons

Per distingir encara més els nivells visualment, podem tintar els sprites de fons utilitzant el Modular propietat. Això ens permet reutilitzar la mateixa textura però donar-li un estat d'ànim completament diferent (per exemple, una posta de sol o un tema nocturn).

Per accedir a aquesta configuració, seleccioneu els vostres sprites de fons. A l'Inspector, sota el Visibilitat (o CanvasItem), feu clic al quadre de color que hi ha al costat Modular.

Al panell Inspector de l'editor Godot, les propietats del node Sprite2D es mostren amb cinc instàncies seleccionades; una fletxa vermella assenyala el camp de propietat "Modular", que està ressaltat en un quadre vermell i actualment buit, indicant que està preparat per introduir-se. Aquest pas probablement segueix la modificació del fons o dels sprites per al nivell 2, on l'ajust del color del modular pot matisar o alterar l'aspecte dels sprites per millorar el tema del desert.

Ajustem el color a alguna cosa que complementi el tema del desert, com ara un taronja o un groc càlids.

A la vista de l'escena en 2D de l'editor Godot de "level_2(*)" amb un zoom del 133,1%, el nivell completat de temàtica del desert es mostra amb plataformes d'art de píxels construïdes a partir de fitxes del desert, tres indicadors de salut en forma de cor per sobre d'una etiqueta de text "Puntuació: 500" i elements del joc que inclouen monedes i enemics situats al disseny; les línies de quadrícula visibles i els contorns de selecció indiquen una edició activa, mentre que la barra de pestanyes superior mostra les escenes "nivell_1", "jugador" i "nivell_2" obertes, confirmant que l'usuari està treballant a l'escena de segon nivell duplicada i modificada tal com s'indica al tutorial.

Podeu aplicar aquesta mateixa tècnica al nivell 1. Per exemple, podeu modular el fons del bosc amb una lleugera tonalitat verda per millorar l'atmosfera exuberant.

Al panell Inspector de l'editor Godot, es mostren cinc nodes Sprite2D seleccionats amb les seves propietats compartides visibles; el camp de propietat "Modular" està ressaltat en un quadre vermell i actualment està buit, indicant que està preparat per a l'entrada per ajustar el to de color dels sprites de fons; aquest pas segueix la substitució del fons del bosc per sprites temàtics del desert per diferenciar visualment el nivell 2 del nivell 1.

A la vista de l'escena en 2D de l'editor Godot de "level_2(*)" amb un zoom del 133,1%, es mostra el disseny de nivell completat amb temàtica del desert, que inclou plataformes d'art de píxels construïdes amb fitxes del desert, tres indicadors de salut en forma de cor situats per sobre d'una etiqueta de text "Puntuació: 500" i elements del joc que inclouen monedes i enemics col·locats pel terreny; Les línies de quadrícula visibles i els contorns de selecció indiquen l'edició activa o la revisió final de les posicions dels nodes dins de l'escena, confirmant la duplicació i modificació correcta del Nivell 1 en un Nivell 2 diferent amb un nou disseny de mapa de mosaics i col·locació d'elements del joc tal com es descriu a la lliçó.

Preneu-vos un moment per revisar els dos nivells per assegurar-vos que se sentin diferents i ofereixen una bona progressió en dificultat.

Repte: modificar la bandera final

Actualment, si jugues al joc i xoques amb la bandera final, Godot pot produir el següent error al depurador:

end_flag.gd:9 @ _on_body_entered(): eliminar un node CollisionObject durant una devolució de trucada física no està permès i provocarà un comportament no desitjat. Elimina amb call_deferred() en lloc d'això.

Aquest error es produeix perquè la funció _on_body_entered s'activa durant un pas de física (quan Godot està calculant col·lisions). Intentar canviar l'escena, que implica suprimir els nodes del nivell actual, mentre el motor físic encara està processant aquest nivell no és segur.

El teu repte: Corregiu aquest error a l'script end_flag.gd perquè la transició de nivell estigui lliure d'errors.

Pista: Recordeu com vam gestionar la funció game_over a l'script del jugador quan el jugador va patir danys. Vam haver d'utilitzar un mètode específic per retardar l'acció fins que fos segura.

Preneu-vos un moment per intentar resoldre-ho pel vostre compte abans de llegir la solució següent.

Solucio del repte

Passem per la solució. La idea bàsica és el mateix patró que hem utilitzat anteriorment a l'script del reproductor: ajornar qualsevol modificació de l'arbre d'escenes fins que s'hagi acabat el pas de la física.

Per solucionar l'error amb el nostre Bandera final, hem de fer referència a com hem gestionat la funció take_damage al nostre script de reproductor. Quan vam trucar a game_over, vam embolicar la trucada a call_deferred perquè el motor esperés fins que acabés el pas de la física:

func 
take_damage (amount : int):

...

# Defer game_over to avoid freeing nodes mid-physics step
if 
health <= 0: call_deferred("game_over")

call_deferred indica a Godot que espere fins al final del fotograma actual (un cop s'hagin completat els càlculs físics) per executar la funció. Això evita que el motor intenti calcular la física dels objectes que s'estan suprimint.

Per aplicar aquest mateix patró a end_flag.gd, primer hauríem d'encapsular la lògica de càrrega d'escenes a la seva pròpia funció.

Obriu end_flag.gd i creeu una funció nova anomenada _load_new_scene:

func 
_load_new_scene 
(): get_tree().change_scene_to_packed(scene_to_load)

Ara, actualitzeu la funció _on_body_entered per cridar aquesta nova funció

call_diferred:

func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return
# Defer the scene change to avoid modifying the tree during a physics callback

call_deferred("_load_new_scene")

Amb aquest canvi, es detecta la col·lisió, s'acaba el marc i aleshores l'escenari canvia amb seguretat. Ara hauríeu de poder completar els nivells sense cap error.

Enhorabona per crear un joc de plataformes 2D complet i multinivell! En el següent capítol, crearem un menú principal per lligar-ho tot.

Creació del menú principal

En aquest capítol final del projecte, configurarem l'escena del menú principal per al nostre joc. El menú és la primera pantalla que veuen els jugadors quan inicien l'aplicació, de manera que serveix com a porta d'entrada a tota l'experiència de joc. Comptarà amb un botó "Jugar" per iniciar el joc i un botó "Surt" per tancar-lo.

Construirem aquesta interfície utilitzant els nodes de la interfície d'usuari de Godot, l'estilarem amb un fons i fonts personalitzades i escriurem un script per gestionar les interaccions dels botons. Finalment, integrarem el menú en el bucle del joc perquè en completar el joc o perdre'l torni el jugador a aquesta pantalla.

Creacio de l'escena del menu

Cada pantalla diferent d'un projecte Godot viu en la seva pròpia escena. El nostre menú no és una excepció, així que ara crearem una escena d'IU dedicada.

A la barra de menú superior, feu clic a Escena i seleccioneu Nova Escena.

La imatge mostra la barra de menú superior de l'editor Godot amb el menú "Escena" obert, destacant l'opció "Nova escena" (drecera de teclat Ctrl+N), que és el primer pas per crear l'escena del menú principal tal com s'indica a la lliçó; aquesta acció inicia el procés de configuració d'una nova escena anomenada "Menú" amb un node arrel de la interfície d'usuari, que es desarà com a menu.tscn a la carpeta Escenes.

En el Crea un node arrel diàleg, seleccioneu Interfície d'usuari. Això crea un control

node com a arrel, que és el tipus base per a tots els elements d'IU a Godot.

Aquesta imatge mostra el diàleg "Crea un node arrel" de l'editor Godot, al qual s'accedeix després de seleccionar "Nova escena", amb l'opció "Interfície d'usuari" destacada i seleccionada (indicada per un cercle verd) com a tipus de node arrel per a la nova escena del menú, alineant-se amb les instruccions de la lliçó per configurar un menú principal mitjançant una escena basada en IU.

Canvieu el nom del node arrel a Menú.

Aquesta imatge mostra el moll d'escena de l'editor Godot després de crear una nova escena, mostrant el node arrel anomenat "Menú" amb un cercle verd que indica que està seleccionat; això confirma l'èxit de la creació de l'escena del menú principal tal com s'indica, que servirà com a primera pantalla del joc i que més tard contindrà elements de la interfície d'usuari com els botons de reproducció i sortida.

Finalment, deseu la nova escena com a menu.tscn dins del vostre Escenes carpeta.

Aquesta imatge mostra el diàleg "Desa l'escena com a" del motor Godot, on l'usuari està desant una escena de menú acabada de crear; el camp Path mostra "res://Scenes", que indica el directori de destinació, i el camp Fitxer conté "menu.tscn", confirmant que l'escena s'està desant amb el nom de fitxer correcte tal com s'indica a la lliçó per configurar el menú principal. Una fletxa vermella connecta visualment la selecció del camí amb l'entrada del nom del fitxer, emfatitzant la ubicació de desar i el pas de nomenclatura del fitxer. El panell del navegador de fitxers de dalt mostra els fitxers d'escenes existents com "end_flag.tscn" i "level_1.tscn", reforçant que aquesta nova escena s'està afegint a la carpeta Escenes del projecte. El botó Desa és visible a sota del camp del nom del fitxer, a punt per finalitzar l'acció.

Afegir una imatge de fons

Un fons gris senzill no és molt acollidor, així que afegim una imatge de fons per definir el to visual del menú. Crea una nova TextureRect node com a fill del node Menú.

Aquesta imatge mostra el diàleg "Crea nou node" de l'editor Godot, on l'usuari ha escrit "textu" a la barra de cerca i seleccionat el node "TextureRect" de la llista de coincidències, un control que s'utilitza per mostrar textures com imatges de fons. El tauler de descripció confirma que és una subclasse de Control i explica la seva funció: mostrar una textura que pot escalar, enrajolar o centrar-se dins dels seus límits. Una fletxa vermella apunta des de l'entrada "TextureRect" seleccionada al botó "Crea" a la part inferior, indicant el següent pas per afegir aquest node com a fill del node Control del menú per configurar el fons del menú, tal com s'indica a la lliçó.

En el Sistema de fitxers dock, navegueu a la carpeta Sprites/Backgrounds i arrossegueu la imatge forest_background.png a la Textura propietat del node TextureRect a l'Inspector.

Aquesta imatge mostra el moll del sistema de fitxers de l'editor Godot i el tauler d'inspector durant el pas d'afegir una imatge de fons a l'escena del menú: al sistema de fitxers, l'usuari ha navegat a res://Sprites/Backgrounds i ha seleccionat "backgroundForest.png" (ressaltat amb un quadre vermell), mentre que a l'Inspector, la propietat del node TextureRect es mostra "també destacada amb la propietat del node TextureRect" amb la mateixa imatge "Tex ressaltada". quadre vermell), confirmant que l'actiu correcte està enllaçat al node tal com s'indica per configurar el fons del menú.

Volem que aquest fons cobreixi tota la pantalla, independentment de la mida de la finestra. Per aconseguir-ho, utilitzarem ancoratges.

  1. Seleccioneu el node TextureRect.
  2. A la barra d'eines a la part superior de la finestra gràfica, feu clic a Anchor Preset botó (la icona del cercle verd).
  3. Seleccioneu el Full Rect opció (la icona inferior dreta al menú desplegable).

Aquesta imatge mostra el menú desplegable Anchor Preset de l'editor Godot, obert des del botó d'ancoratge circular verd de la barra d'eines superior, amb l'opció "Full Rect" ressaltada i seleccionada (indicada per un quadre vermell) per ancorar el node TextureRect a tota la finestra del joc; aquesta configuració garanteix que la imatge de fons canviï de mida per omplir la pantalla, tal com s'indica als passos actualitzats de la lliçó per crear l'escena del menú principal.

Nota de Godot: àncores i interfície d'usuari sensible

Les àncores defineixen com es posiciona un node de control i es redimensiona en relació al seu pare. Cada àncora és un valor entre 0 i 1 que representa un percentatge de la mida del pare. Una àncora de (0, 0) significa la cantonada superior esquerra; (1, 1) significa la part inferior dreta.

El preajust "Full Rect" estableix les quatre àncores perquè el node s'estingui per omplir completament el seu pare, per això la nostra imatge de fons cobreix tota la pantalla. El preajust "Centre" situa el node al punt mitjà del pare, que és perfecte per a títols i botons.

Més informació: Mida i ancoratges (https://docs.godotengine.org/en/4.6/tutorials/ui/size_and_anchors.html)

A continuació, hem d'assegurar-nos que la imatge s'escala correctament sense distorsió. A l'Inspector, localitzeu el Mode d'expansió propietat i establiu-la Ajust a l'alçada. Això garanteix que la imatge canviï de mida en funció de la resolució vertical mantenint la seva relació d'aspecte.

Aquesta imatge mostra el tauler d'inspector de l'editor Godot per a un node TextureRect, destacant la propietat "Mode d'expansió" establerta a "Ajusta alçada" (indicada per un quadre vermell i una fletxa), que canvia la mida de la imatge de fons per adaptar-se a l'alçada de la pantalla mantenint la relació d'aspecte, un pas clau per fer que el fons del menú respongui a diferents resolucions tal com s'indica a la lliçó.

Canvieu el nom del node TextureRect a Fons per mantenir la nostra escena organitzada.

Aquesta imatge mostra el moll d'escena de l'editor Godot amb el node arrel "Menú" expandit, mostrant el seu node fill anomenat "Background", que és un node TextureRect (indicat per la seva icona) i seleccionat actualment (ressaltat en blau); això confirma l'èxit del canvi de nom i la col·locació jeràrquica del node d'imatge de fons sota el control de menú tal com s'indica, preparant-lo per als ajustos de disseny per omplir la pantalla.

El vostre fons ara hauria d'omplir tota l'àrea de la pantalla, tal com es mostra a continuació.

Aquesta imatge mostra la finestra 2D de l'editor Godot que mostra l'escena del "menú (*)", on s'ha redimensionat un node TextureRect anomenat "Fons" per omplir tota l'àrea de la pantalla, indicat pel seu quadre delimitador que s'estén a les vores de la finestra gràfica i s'alinea amb les guies d'ancoratge vermelles a la part superior, inferior, esquerra i dreta. El node mostra la imatge forest_background.png, amb pins estilitzats contra un cel i un terra blaus clars, confirmant l'èxit de l'assignació i l'ancoratge. El botó d'ancoratge circular verd de la barra d'eines superior està actiu, cosa que reflecteix que s'ha aplicat el valor predefinit d'ancoratge "Full Rect" i el mode d'expansió del node està configurat en "Ajusta l'alçada" (tal com s'ha configurat anteriorment), assegurant que el fons s'escala de manera sensible a la resolució de la finestra mantenint la relació d'aspecte.

Afegir un titol

Amb el fons al seu lloc, afegim el títol del joc perquè els jugadors sàpiguen a què estan a punt de jugar. Crea una nova Etiqueta node com a fill del node Menú.

Aquesta imatge mostra el diàleg "Crea nou node" de l'editor Godot, on l'usuari ha escrit "lab" a la barra de cerca i seleccionat el node "Etiqueta" de la llista de coincidències, un control per mostrar text sense format tal com es descriu a la lliçó per afegir un títol a l'escena del menú. El tauler de descripció confirma que és una subclasse de Control i assenyala que no admet en negreta, cursiva o text enriquit. Una fletxa vermella apunta des de l'entrada "Etiqueta" seleccionada al botó "Crea" a la part inferior, indicant el següent pas per crear una instancia del node com a fill del node Control del menú, que s'alinea amb les instruccions de la lliçó per crear i canviar el nom del node Etiqueta a "Títol" abans d'establir el seu text i propietats d'alineació.

Canvieu el nom d'aquest node a Títol.

Aquesta imatge mostra el dock Scene de l'editor Godot amb el node arrel "Menú" expandit, mostrant els seus nodes fills: "Background" (un node TextureRect) i "Títol" (un node Label), que actualment està seleccionat i ressaltat en blau; això confirma la creació correcta i la col·locació jeràrquica de l'element de text del títol sota el node Menú tal com s'indica per a la configuració de l'escena del menú principal.

A l'Inspector, configureu el Text propietat a Joc de plataformes 2D (o el teu títol preferit).

Aquesta imatge mostra el panell Inspector de l'editor Godot amb el node Etiqueta "Títol" seleccionat, mostrant les seves propietats a la secció "Text"; el camp "Text" està definit en "Joc de plataformes 2D", que correspon a la instrucció de la lliçó per assignar aquest text del títol al node Etiqueta del menú per mostrar-lo a la pantalla.

Per centrar el títol a la pantalla, tornarem a utilitzar àncores.

  1. Desplaceu-vos cap avall fins a Disseny secció a l'inspector.
  2. Canvia el Mode de disseny a Àncores.
  3. Estableix el Àncores preestablerts a Centre.

Aquesta imatge mostra el tauler d'inspector de l'editor Godot amb el node Etiqueta "Títol" seleccionat, centrant-se en la seva secció de disseny: el "Mode de disseny" està configurat en "Àncores" i el "Preestablert d'àncores" està configurat com a "Centre", tal com s'indiquen els quadres vermells i una fletxa vermella que apunta des de la capçalera de Disseny cap a les instruccions de configuració d'aquesta lliçó al centre de la pantalla per al text de la lliçó. disseny.

Això centra el node en si, però el text dins del node encara pot estar alineat a l'esquerra. Per solucionar-ho, canvieu tots dos Alineació horitzontal i Alineació vertical propietats a Centre.

Al tauler d'inspector de l'editor Godot, amb el node Etiqueta "Títol" seleccionat, la imatge destaca la secció "Configuració de l'etiqueta" on les propietats "Alineació horitzontal" i "Alineació vertical" estan configurades a "Centre", tal com s'indica amb quadres vermells i una fletxa vermella que apunta a aquests camps, assegurant que el text "Joc de plataformes 2D" es troba al centre de l'etiqueta visual de l'etiqueta de la vista centrada en 2D a la pantalla.

Ara el text està col·locat correctament, però és petit i senzill.

A la finestra 2D de l'editor Godot, l'escena "menú (*)" mostra un node d'etiqueta anomenat "Títol" amb el text "Joc de plataformes en 2D", centrat a la pantalla mitjançant àncores i paràmetres d'alineació; l'etiqueta està inclosa en un quadre delimitador taronja amb nanses de canvi de mida vermelles, que indica que està seleccionada i col·locada sobre una imatge de fons a pantalla completa d'arbres i núvols estilitzats, confirmant la configuració correcta del disseny segons les instruccions de la lliçó.

Per estilitzar-lo, localitza el Configuració de l'etiqueta propietat a l'inspector. A continuació, seleccioneu el menú desplegable i trieu Nova configuració de l'etiqueta.

Al tauler Inspector de l'editor Godot, amb el node Etiqueta "Títol" seleccionat, la imatge destaca la secció "Configuració de l'etiqueta" on la propietat "Alineació horitzontal" s'estableix a "Centre", tal com s'indica amb un quadre vermell i una gran fletxa vermella que assenyala aquest camp desplegable; Aquesta configuració, combinada amb el centratge vertical configurat anteriorment, garanteix que el text del títol "2D Platformer Game" estigui totalment centrat a la pantalla per a una correcta alineació visual a l'escena del menú principal.

Feu clic al nou recurs per ampliar-ne les propietats. Configureu els paràmetres següents per fer que el títol destaqui (no dubteu a experimentar, però, i seleccioneu altres paràmetres si creieu que funcionen millor):

Aquesta imatge mostra el tauler d'inspector de l'editor Godot amb el node Etiqueta "Títol" seleccionat, mostrant les seves propietats "Configuració de l'etiqueta": l'interlineat s'estableix a 3,0 px, l'espai entre paràgrafs a 0,0 px, la mida de la lletra a 48 px, la mida del contorn a 5 px amb un color verd i la mida de l'ombra a 5 px amb un desplaçament de x=1,0 px; aquests paràmetres s'estan configurant per fer que el text del títol sigui més visible a la pantalla després de centrar-lo a l'escena del menú.

El títol ara hauria de ser gran, llegible i visualment atractiu.

Aquesta imatge mostra la finestra 2D de l'editor Godot durant la configuració de l'escena del "menú", mostrant el fons i el títol del menú principal completat: una imatge de fons blau clar de temàtica forestal omple tota la pantalla (resolució de 1152 x 648), amb el node Label centrat titulat "Joc de plataformes 2D" representat en text groc amb contorn visible i efectes d'ombra; la barra d'eines superior mostra que l'escena està en mode DEBUG al projecte "Godot2DPlatformerCourse", confirmant que s'ha aplicat el disseny de la interfície d'usuari i els passos d'estil visual de la lliçó.

Afegir botons

Ara necessitem els elements interactius que permetin als jugadors començar el joc o sortir. Crea una nova Botó node com a fill del node Menú.

Al diàleg "Crea un nou node" de l'editor Godot, l'usuari ha escrit "botó" a la barra de cerca i el node "Botó" es selecciona de les coincidències a la categoria Control; una fletxa vermella apunta des de l'entrada "Botó" seleccionada al botó "Crea" a la part inferior del diàleg, indicant el següent pas per crear una instancia d'aquest node de botó temàtic estàndard (que pot contenir text i una icona) com a part de la creació dels botons de reproducció i sortida del menú principal.

Canvieu el nom d'aquest node a PlayButton.

Aquesta imatge mostra el moll d'escena de l'editor Godot amb el node arrel "Menú" expandit, mostrant els seus nodes fills: "Background" (un TextureRect), "Títol" (una etiqueta) i "PlayButton" (un node Button, actualment seleccionat i ressaltat en blau), confirmant l'estructura jeràrquica de l'escena del menú principal a mesura que avança cap als elements interactius del botó de la lliçó a mesura que avança cap a la lliçó.

Per a aquest botó, configureu el Text propietat a Jugar.

Al tauler d'inspector de l'editor Godot, el node seleccionat és "PlayButton", un control de botó, amb la seva propietat Text establerta a "Reprodueix" al camp editable de la secció "Text", que reflecteix el pas de la lliçó de configurar el text de l'etiqueta del botó de reproducció per a l'escena del menú principal.

Igual que el títol, volem centrar aquest botó a la pantalla. En el Disseny secció, canvieu el Mode de disseny a Àncores i el Àncores preestablerts a Centre.

Aquesta imatge mostra el tauler d'inspector de l'editor Godot amb el node "PlayButton" seleccionat, ressaltant la seva configuració de disseny: a la secció ampliada "Disposició" (marcada amb un quadre vermell), una fletxa vermella apunta a la propietat "Mode de disseny" establerta a "Ancores" i la propietat "Ancores preestablerts" establerta a "Centre", indicant que aquest botó de configuració principal està configurat com a part del botó de configuració principal. IU del menú.

A la finestra gràfica, arrossegueu el botó cap avall perquè quedi a sota del títol. També podeu canviar la mida per fer-lo més gran i fer-lo més fàcil de fer clic.

A la finestra 2D de l'editor Godot, l'escena "menú (*)" mostra el menú principal amb un fons de bosc blau clar i un títol centrat que diu "Joc de plataformes 2D"; a sota del títol, es selecciona un node de botó gris fosc amb l'etiqueta "Reprodueix", que es mostra amb nanses de canvi de mida vermelles i un pivot de rotació verd al centre, que indica que s'està posicionant o ajustant com a part de la configuració dels elements interactius del menú.

Per crear el botó Surt, només heu de duplicar el botó de reproducció (Ctrl + D) i canviar el nom de la còpia a QuitButton.

Aquesta imatge mostra el dock Scene de l'editor Godot amb el node arrel "Menú" ampliat, mostrant els seus nodes fills: "Background" (un TextureRect), "Títol" (una etiqueta) i dos nodes Button, "PlayButton" i "QuitButton", amb "QuitButton" seleccionat i ressaltat en blau; això confirma l'estructura jeràrquica de l'escena del menú principal segons les instruccions, on el botó Surt s'ha afegit com a germà al botó Reproduir sota el node de control del menú.

A continuació, canvieu el Text propietat del botó nou a Surt.

Al tauler d'inspector de l'editor Godot, el node seleccionat és "QuitButton", un control de botó, amb la seva propietat Text establerta a "Surt" al camp editable de la secció "Text", que reflecteix el pas de la lliçó de configurar el text de l'etiqueta del botó de sortida per a l'escena del menú principal. El node apareix a la pestanya "Node" i la barra de cerca "Propietats del filtre" és visible a sobre de la llista de propietats.

Finalment, col·loqueu el QuitButton a sota del PlayButton.

Aquesta imatge mostra la finestra 2D de l'editor Godot que mostra l'escena del menú principal completa anomenada "menú", amb una imatge de fons de bosc blau clar a pantalla completa, un títol groc centrat que diu "Joc de plataformes 2D" amb un contorn fosc i dos nodes de botons gris fosc apilats verticalment etiquetats "Reproduir" i "Surt" situats a sota del títol; l'escena està configurada amb l'ancoratge i l'alineació adequats per garantir la capacitat de resposta, tal com s'indica a la lliçó per configurar la pantalla inicial del joc.

Programacio del menu

Tenim les imatges al seu lloc, però els botons encara no fan res. Adjuntem un script per connectar la lògica del botó.

Seleccioneu el node del menú arrel i adjunteu un script nou. Deseu-lo com a menu.gd al fitxer Guions carpeta.

Aquesta imatge mostra el diàleg "Adjuntar script del node" de l'editor Godot, on s'està creant un nou GDScript per a un node de control; el camp Path s'estableix a "res://Scripts/menu.gd", indicant que l'script es desarà a la carpeta Scripts amb aquest nom de fitxer, i el botó "Crea" es ressalta amb un quadre vermell i una fletxa, indicant el següent pas per generar el fitxer de script com a part de la configuració de la funcionalitat de l'escena del menú principal.

Utilitzarem senyals per detectar quan es prem els botons. Com a actualització, els senyals permeten a un node notificar a altres parts de l'escena que ha passat alguna cosa, sense que aquestes parts hagin de comprovar cada fotograma.

  1. Seleccioneu el botó de reproducció.
  2. Aneu a la Node acobla i fes doble clic al senyal premut().

Al panell Inspector de l'editor Godot, la pestanya Senyals està activa (resaltada amb un quadre vermell), mostrant els senyals disponibles per al node BaseButton seleccionat; el senyal premut() es ressalta específicament amb un quadre vermell i un cursor del ratolí passant sobre ell, indicant que l'usuari està a punt de connectar aquest senyal, un pas clau per configurar la funcionalitat del botó per a l'escena del menú principal tal com s'indica a la lliçó.

  1. Connecteu-lo al node Menú. Això crearà el

funció _on_play_button_pressed al vostre script.

Aquesta imatge mostra el diàleg "Connexió d'un senyal a un mètode" de Godot, on el senyal premut() d'un node Button s'està connectant a un mètode d'script. El camp "Des del senyal" mostra "premut()" i a "Connecta a l'script", es selecciona el node "Menú" (ressaltat amb un quadre vermell), que indica l'script de destinació. El camp "Mètode del receptor" conté el nom del mètode "_on_play_button_pressed", que es cridarà quan es prem el botó. Una gran fletxa vermella apunta des del "PlayButton (Connexió des de)" seleccionat a la llista de nodes al botó "Connexió" a la part inferior (també destacat amb un quadre vermell), il·lustrant el pas final per establir la connexió del senyal per a la funcionalitat del botó de reproducció a l'escena del menú principal.

Repetiu aquest procés per al QuitButton, connectant el seu senyal pressed() a l'script per crear _on_quit_button_pressed.

Aquesta imatge mostra el diàleg "Connecta un senyal a un mètode" de Godot, on el senyal premut() d'un node Button s'està connectant a un mètode d'script per al node "Menú" (ressaltat en vermell). El camp Mètode del receptor conté el text "_on_quit_button_pressed", que indica el nom de la funció GDScript que s'anomenarà quan es prem el botó. Una gran fletxa vermella apunta des del node "Menú" seleccionat al botó "Connexió" (també destacat en vermell), que finalitza la connexió del senyal, un pas clau per fer que el botó Surt funcioni a l'escena del menú principal.

Ara, afegiu la lògica a aquestes funcions:

extends 
Control
func 
_on_play_button_pressed():
# Reset persistent score before starting a new game
PlayerStats.score = 0 get_tree().change_scene_to_file("res://Scenes/level_1.tscn")
func 
_on_quit_button_pressed(): get_tree().quit()

Integrar el menú al bucle del joc

Per completar el flux del joc, hem d'assegurar-nos que el jugador pot accedir al menú i que els nivells passen correctament. Al final d'aquesta secció, el joc passarà perfectament des del menú a través dels dos nivells i de nou.

Provar el menu

Abans d'ajustar els nostres nivells, assegurem-nos que el menú en si funciona. Executeu l'escena del menú directament (premeu F6).

  1. Feu clic Surt per confirmar que el joc es tanca.
  2. Torna-ho a executar i fes clic Jugar per confirmar que es carrega el nivell 1.

Si tot es veu bé aquí, podem treballar amb la resta del bucle.

Connectar nivells

Els nostres següents passos són enllaçar els nostres nivells mitjançant la lògica EndFlag que vam crear als capítols anteriors.

Obert Nivell 1 i seleccioneu el EndFlag node. A Inspector, assigneu

level_2.tscn al Escena per carregar propietat.

Al tauler d'inspector de l'editor Godot, sota el node "EndFlag", es mostra el recurs de l'script "end_flag.gd" amb una icona d'engranatge que indica que es pot editar; al costat, la propietat "Escena per carregar" mostra una vista prèvia en miniatura d'una escena amb un cotxe vermell sobre un fons d'herba, cosa que suggereix que aquest és el nivell o l'escena que es carregarà quan s'activa la bandera final, d'acord amb la configuració de la lògica de progressió del joc al tutorial.

Igualment, obert Nivell 2 i seleccioneu-ne EndFlag. Assigna menu.tscn al fitxer Escena per carregar propietat. Això crea un bucle complet: Menu -> Level 1 -> Level 2

-> Menu.

Al tauler d'inspector de l'editor Godot, es selecciona el node "EndFlag", que mostra el seu recurs d'script "end_flag.gd" i una propietat "Escena per carregar" que fa referència a una miniatura de vista prèvia de l'escena, probablement el nivell o l'escena següent que es carregarà en activar aquesta marca. A continuació, es mostra un node "Area2D" a Monitorització amb la casella de selecció activada, que indica que està configurat per detectar col·lisions o solapaments, que es poden utilitzar per activar la condició final o la transició d'escena al joc. Aquesta configuració s'alinea amb la implementació de la lògica de joc per fer la transició entre escenes, com ara completar un nivell o assolir un objectiu.

Si haguéssiu de crear més nivells, com a repte per a vosaltres mateixos, simplement els connectaríeu d'una manera similar.

Actualitzar la logica de Game Over

Finalment, quan el jugador perd, volem tornar-los al menú principal en lloc de simplement tornar a carregar el nivell.

Obriu l'script player.gd i actualitzeu la funció game_over:

func 
game_over(): get_tree().change_scene_to_file("res://Scenes/menu.tscn")

Ara, si el jugador es queda sense salut o cau del mapa, es tornarà a enviar a la pantalla de títol per tornar-ho a provar.

Ara tens un bucle de joc totalment funcional amb un menú principal polit! Amb això, el nostre projecte ja està enllestit.

Paraules finals

Felicitats. Has arribat al final d'aquest llibre, però el més important és que has arribat al començament del teu viatge com a desenvolupador de jocs.

Llegir un llibre tècnic és un compromís, però seguir i escriure el codi tu mateix és un èxit important. Vau començar amb una carpeta buida i una pantalla en blanc. Ara, tens un joc de plataformes en 2D totalment funcional amb un personatge jugable, enemics, un sistema de puntuació i una interfície d'usuari polida. Aquesta transformació és l'essència del desenvolupament del joc.

Abans de tancar aquest llibre i obrir un projecte nou, dediquem un moment a reflexionar sobre el conjunt d'eines que heu creat i a veure on podeu anar a continuació.

El que has aconseguit

Heu fet més que copiar codi; has après els patrons fonamentals que impulsen Godot. Tot i que ens hem centrat en un gènere específic, les habilitats que has practicat s'apliquen a gairebé qualsevol joc que crearàs en el futur.

Has dominat el sistema d'escenes. Vas aprendre que a Godot tot és una escena. Vas crear objectes complexos com el jugador i l'enemic combinant nodes especialitzats més petits. També heu après a estructurar aquestes escenes de manera dinàmica, cosa que us permet omplir nivells amb centenars d'objectes sense reescriure codi per alterar configuracions específiques.

Vas controlar el motor de la física. En treballar amb CharacterBody2D i Area2D, heu après a gestionar les col·lisions, la gravetat i els vectors de moviment. Vas anar més enllà de la simple animació per crear un personatge que se senti sensible i fonamentat en el món del joc.

Heu connectat sistemes amb senyals. Una de les habilitats més crítiques de Godot és desacoblar el vostre codi. Vau utilitzar senyals per fer saber a la interfície d'usuari quan va canviar la salut o quan el jugador va recollir una moneda, assegurant-vos que la vostra lògica de joc es mantingués neta i modular.

Has polit l'experiència. Un joc és més que lògica. Heu après a utilitzar AnimationPlayer, AudioStreamPlayer i els efectes de sacsejada de la càmera

afegeix "suc" al teu projecte. Aquests detalls converteixen un prototip funcional en una experiència atractiva.

Cap on continuar

La transició de seguir un tutorial a crear les teves pròpies idees pot resultar descoratjador. La millor manera de superar aquesta bretxa és fer passos petits i concrets.

Aquí teniu quatre maneres de continuar el vostre creixement.

Amplia aquest projecte

La manera més senzilla de practicar és modificar el codi que ja enteneu. Prova d'afegir una funció nova al joc que acabes d'acabar:

Participar en un joc jam

Els embussos de joc són esdeveniments en què creeu un joc des de zero en un temps limitat (normalment de 48 hores a una setmana) basat en un tema. Aquesta és una de les maneres més ràpides d'aprendre. La limitació de temps us obliga a centrar-vos en acabar un projecte en lloc de perfeccionar-lo.

Llocs web com itch.io allotgen desenes de confitures cada setmana. Busqueu melmelades que donen la benvinguda explícita als principiants.

Explora la documentació

Aquest llibre cobria l'essencial, però Godot és vast. La documentació oficial és el teu millor amic. Sempre que us pregunteu "Puc fer X?", la resposta sol estar a la referència de classe.

Preneu l'hàbit de llegir la documentació dels nodes que encara no heu utilitzat. És possible que descobriu un node RayCast2D o Timer que resol un problema que us costava solucionar manualment.

Visiteu la documentació aquí: docs.godotengine.org (https://docs.godotengine.org)

Reconstrueix-ho sense la guia

Intenta recrear la mecànica bàsica del moviment d'aquest joc en un projecte nou sense mirar el codi font. Probablement us quedareu atrapats, i això és bo. Quan heu de buscar la solució o llegir vosaltres mateixos els missatges d'error, el coneixement es manté.

Continua aprenent

Si preferiu l'aprenentatge pràctic i centrat en projectes a Godot i la programació, consulteu la nostra biblioteca de cursos completa a Zenva Academy (https://academy.zenva.com). El catàleg inclou més de 300 cursos i més de 40 vies d'aprenentatge, orientant els estudiants des dels fonaments bàsics fins a temes avançats.

Reflexions finals

El desenvolupament del joc és una pràctica de perseverança. Hi haurà errors que us deixaran caure durant dies. Hi haurà funcions que resulten més difícils del que semblaven. Això és normal. Tots els desenvolupadors professionals, des de creadors independents fins a veterans de l'AAA, s'enfronten a aquests mateixos reptes.

La diferència és que ara teniu un flux de treball. Sabeu com dividir un gran problema en petits nodes, com escriure el seu comportament i com combinar-los en una escena.

Tens les eines. Tens el coneixement. Ara, ves a construir alguna cosa divertida.

Referència completa del codi font

En aquesta darrera secció, proporcionem el codi font complet de tots els scripts creats al llarg del desenvolupament de 2D Platformer. Aquesta referència està pensada per ajudar-vos a depurar el vostre propi codi, verificar la vostra lògica o servir com a base per expandir el projecte amb les vostres pròpies característiques.

Si necessiteu comprovar la configuració o els actius de l'escena, recordeu que podeu descarregar els fitxers complets del projecte mitjançant l'enllaç que hi ha a la Introducció capítol.

background_parallax.gd

Camí del fitxer: res://Scripts/background_parallax.gd

Aquest script gestiona l'efecte de desplaçament de paral·laxi per al fons. Calcula la posició del fons multiplicant la posició global del jugador per un factor de paral·laxi (0,7), fent que el fons es mogui més lentament que el primer pla per crear una sensació de profunditat.

extends 
Node2D
# Controls how much slower the background moves relative to the player (0.7 = 70% speed)
var 
parallax : float = 0.7 @onready 
var 
player = $"./Player"
func 
_process (
_delta
):
# Offset the background by a fraction of the player's position to simulate depth

global_position = player.global_position * parallax

camera_shake.gd

Camí del fitxer: res://Scripts/camera_shake.gd

Adjunt al node Camera2D, aquest script crea un efecte de sacsejada de la pantalla quan el jugador pateix danys. Escolta el senyal OnUpdateHealth del reproductor. Quan s'activa, estableix un valor d'intensitat que disminueix amb el temps, aplicant un desplaçament aleatori a la posició de la càmera a cada fotograma.

extends 
Camera2D
var 
intensity : float = 0
func 
_ready ():
# Listen for damage events from the parent Player node

get_parent().OnUpdateHealth.connect(_danyar_agitar)

# Kick off a shake whenever health changes
func 
_damage_shake 
(
_health 
: int): intensity = 3
func 
_process (delta):
if 
intensity > 0:
# Gradually reduce the shake strength each frame

intensity = lerpf(intensity, 0, delta * 10) offset = _get_random_offset()

# Generate a random camera offset within the current intensity range
func 
_get_random_offset 
() -> Vector2:
var 
x = randf_range(-intensity, intensity) 
var 
y = randf_range(-intensity, intensity) 
return 
Vector2(x, y)

coin.gd

Camí del fitxer: res://Scripts/coin.gd

Aquest script controla el comportament visual i la lògica de col·lisió de les monedes col·leccionables. Utilitza una ona sinusoïdal basada en el temps del sistema per girar el sprite (mitjançant l'escala) i pujar-lo cap avall. Quan el jugador entra a l'àrea de la moneda, activa l'augment de la puntuació i elimina la moneda de l'escena.

extends 
Area2D
var 
rotate_speed : float = 3.0 
var 
bob_height : float = 5.0 
var 
bob_speed : float = 5.0
@onready 
var 
start_pos : Vector2 = global_position @onready 
var 
sprite : Sprite2D = $Sprite
func 
_physics_process(
_delta
):
var 
time = Time.get_unix_time_from_system()
# Simulate a spinning effect by oscillating the horizontal scale with a sine wave

sprite.scale.x = sin(time * rotate_speed)

# Bob the coin up and down using a sine wave mapped to a 0-to-bob_height range
var 
y_pos = ((1 + sin(time * bob_speed)) / 2) * bob_height global_position.y = start_pos.y - y_pos
func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return

body.increase_score(1) queue_free()

end_flag.gd

Camí del fitxer: res://Scripts/end_flag.gd

Aquest script gestiona la lògica de finalització del nivell. Exporta una variable PackedScene, que us permet assignar el següent nivell directament a l'Inspector. Quan el jugador entra a l'àrea de la bandera, utilitza call_deferred per carregar de manera segura la nova escena, evitant errors físics durant la transició.

extends 
Area2D
@export 
var 
scene_to_load : PackedScene
func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return
# Defer the scene change to avoid modifying the tree during a physics callback

call_deferred("_load_new_scene")

func 
_load_new_scene 
(): get_tree().change_scene_to_packed(scene_to_load)

enemy.gd

Camí del fitxer: res://Scripts/enemy.gd

Aquest script controla la IA enemiga. Mou l'enemic cap endavant i cap enrere entre la seva posició inicial i una posició objectiu definida per move_direction. També detecta col·lisions amb el jugador i causa danys.

extends 
Area2D
@export 
var 
move_direction : Vector2 @export 
var 
move_speed : float = 20
@onready 
var 
start_pos : Vector2 = global_position
@onready 
var 
target_pos : Vector2 = global_position + move_direction
func 
_ready ():

$AnimationPlayer.play("fly")

func 
_physics_process(delta):
# Move steadily toward the current target position

global_position = global_position.move_toward(target_pos, move_speed * delta)

# When the enemy arrives, swap the target to create a patrol loop
if 
global_position == target_pos:
if 
target_pos == start_pos:

target_pos = start_pos + move_direction

else:

target_pos = start_pos

func 
_on_body_entered(body):
if not 
body.is_in_group("Player"):
return

body.take_damage(1)

Camí del fitxer: res://Scripts/menu.gd

Aquest script gestiona les interaccions del menú principal. Es connecta als botons "Reproduir" i "Surt". Prement "Reproduir" restableix la puntuació global i carrega el primer nivell, mentre que prement "Surt" tanca l'aplicació.

extends 
Control
func 
_on_play_button_pressed():
# Reset persistent score before starting a new game
PlayerStats.score = 0 get_tree().change_scene_to_file("res://Scenes/level_1.tscn")
func 
_on_quit_button_pressed(): get_tree().quit()

player.gd

Camí del fitxer: res://Scripts/player.gd

Aquest és el guió bàsic del personatge del jugador. Gestiona el moviment basat en la física (gravetat, acceleració, fricció, salt), gestiona la salut i la puntuació, reprodueix animacions i efectes de so i gestiona l'estat del joc. També emet senyals (OnUpdateHealth, OnUpdateScore) per actualitzar la IU.

extends 
CharacterBody2D
signal 
OnUpdateHealth (health : int) 
signal 
OnUpdateScore (score : int)
@export 
var 
move_speed : float = 100 @export 
var 
acceleration : float = 50 @export 
var 
braking : float = 20 @export 
var 
gravity : float = 500 @export 
var 
jump_force : float = 200
@export 
var 
health : int = 3
var 
move_input : float
@onready 
var 
sprite : Sprite2D = $Sprite
@onready 
var 
anim : AnimationPlayer = $AnimationPlayer @onready 
var 
audio : AudioStreamPlayer = $AudioStreamPlayer
var 
take_damage_sfx : AudioStream = preload("res://Audio/take_damage.wav")
var 
coin_sfx : AudioStream = preload("res://Audio/coin.wav")
func 
_physics_process(delta):
# Apply gravity only when airborne
if not 
is_on_floor():

velocity.y += gravity * delta

move_input = Input.get_axis("move_left", "move_right")

# Smoothly accelerate toward target speed, or brake to a stop
if 
move_input != 0:

velocity.x = lerp(velocity.x, move_input * move_speed, acceleration * delta)

else:

velocity.x = lerp(velocity.x, 0.0, braking * delta)

# Only allow jumping while grounded
if 
Input.is_action_pressed("jump") 
and 
is_on_floor(): velocity.y = -jump_force

move_and_slide()

func 
_process(
_delta
):
# Flip the sprite to face the direction of movement
if 
velocity.x != 0:

sprite.flip_h = velocity.x > 0

# Trigger game over if the player falls off the map
if 
global_position.y > 200: game_over()

_manage_animation()

# Select the correct animation based on the player's current state
func 
_manage_animation 
():
if not 
is_on_floor(): anim.play("jump") 
elif 
move_input != 0: anim.play("move")

else:

anim.play("idle")

func 
take_damage (amount : int):

health -= amount OnUpdateHealth.emit(health)

_damage_flash() play_sound(take_damage_sfx)

# Defer game_over to avoid freeing nodes mid-physics step
if 
health <= 0: call_deferred("game_over")
func 
game_over (): get_tree().change_scene_to_file("res://Scenes/menu.tscn")
func 
increase_score (amount : int): PlayerStats.score += amount OnUpdateScore.emit(PlayerStats.score) play_sound(coin_sfx)
# Briefly tint the sprite red to signal damage
func 
_damage_flash 
(): sprite.modulate = Color.RED

await get_tree().create_timer(0.05).timeout sprite.modulate = Color.WHITE

# Play a one-shot sound effect through the shared AudioStreamPlayer
func 
play_sound (sound : AudioStream): audio.stream = sound

audio.play()

player_stats.gd

Camí del fitxer: res://Scripts/player_stats.gd

Aquest és un script de càrrega automàtica (Singleton) que persisteix durant els canvis d'escena. Emmagatzema la puntuació del jugador perquè no es reiniciï quan es recarregui o canviï un nivell.

extends 
Node
var 
score : int = 0

player_ui.gd

Camí del fitxer: res://Scripts/player_ui.gd

Aquest script gestiona la pantalla d'atenció al públic (HUD). Es connecta als senyals d'actualització del jugador per actualitzar la pantalla de salut (mostrant/amagant les icones del cor) i l'etiqueta de text de la puntuació en temps real.

extends 
CanvasLayer
@onready 
var 
health_container = $HealthContainer 
var 
hearts : Array = []
@onready 
var 
score_text : Label = $ScoreText @onready 
var 
player = get_parent()
func 
_ready ():

hearts = health_container.get_children()

# Subscribe to the player's health and score signals 
player.OnUpdateHealth.connect(
_update_hearts
) player.OnUpdateScore.connect(
_update_score
)
# Show the correct starting values on the first frame

_update_hearts(player.health)

_update_score(PlayerStats.score)

# Show or hide each heart icon based on current health
func 
_update_hearts 
(health : int):
for 
i 
in 
len(hearts): hearts[i].visible = i < health
func 
_update_score 
(score : int): score_text.text = "Score: " + str(score)