Organitzar el codi és fonamental per mantenir un projecte escalable, fàcil de mantenir i col·laboratiu. En aquest tema aprendràs com estructurar el teu codi de joc amb Phaser, utilitzant bones pràctiques de programació i patrons habituals en el desenvolupament de jocs.
Conceptes clau
- Modularitat: Dividir el codi en fitxers i mòduls lògics.
- Separació de responsabilitats: Cada part del codi ha de tenir una funció clara.
- Reutilització: Escriure codi que pugui ser reutilitzat en diferents parts del joc.
- Llegibilitat: Utilitzar noms clars i comentaris per facilitar la comprensió.
- Escalabilitat: Preparar l’estructura per afegir noves funcionalitats fàcilment.
Estructura bàsica d’un projecte Phaser
Una bona organització de carpetes i fitxers pot ser la següent:
Carpeta/Fitxer | Contingut |
---|---|
index.html |
Punt d’entrada del joc (carrega Phaser i el teu codi JS) |
src/ |
Codi font del joc |
src/scenes/ |
Escenes del joc (menú, joc principal, game over, etc.) |
src/objects/ |
Classes d’objectes personalitzats (jugador, enemics, projectils, etc.) |
src/utils/ |
Funcions auxiliars i utilitats |
assets/ |
Recursos multimèdia (imatges, sons, tilemaps, etc.) |
package.json |
Configuració de dependències (si utilitzes npm) |
Exemple d’estructura:
project/ │ ├── index.html ├── src/ │ ├── main.js │ ├── scenes/ │ │ ├── BootScene.js │ │ ├── MenuScene.js │ │ └── GameScene.js │ ├── objects/ │ │ ├── Player.js │ │ └── Enemy.js │ └── utils/ │ └── helpers.js └── assets/ ├── images/ ├── audio/ └── tilemaps/
Separació de responsabilitats amb escenes
Phaser utilitza el concepte d’escenes per dividir el flux del joc (menú, joc, pantalla de puntuació, etc.). Cada escena hauria d’estar en el seu propi fitxer i classe.
Exemple bàsic d’una escena:
// src/scenes/GameScene.js export default class GameScene extends Phaser.Scene { constructor() { super({ key: 'GameScene' }); } preload() { this.load.image('player', 'assets/images/player.png'); } create() { this.player = this.add.sprite(100, 100, 'player'); } update(time, delta) { // Lògica de joc } }
Explicació:
constructor
: Defineix la clau de l’escena.preload()
: Carrega recursos.create()
: Inicialitza objectes.update()
: S’executa cada frame per actualitzar la lògica.
Crear objectes personalitzats
Per mantenir el codi net, crea classes per als teus objectes de joc (jugador, enemics, etc.) i importa-les a les escenes.
// src/objects/Player.js export default class Player extends Phaser.Physics.Arcade.Sprite { constructor(scene, x, y) { super(scene, x, y, 'player'); scene.add.existing(this); scene.physics.add.existing(this); } moveLeft() { this.setVelocityX(-160); } moveRight() { this.setVelocityX(160); } }
Com utilitzar-lo a l’escena:
Utilitzar funcions auxiliars
Les funcions que es repeteixen o que són utilitats generals (per exemple, calcular distàncies, generar números aleatoris, etc.) han d’anar a fitxers dins de src/utils/
.
// src/utils/helpers.js export function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
Exemple pràctic: Organització d’una escena amb objectes
// src/scenes/GameScene.js import Player from '../objects/Player.js'; import { randomInt } from '../utils/helpers.js'; export default class GameScene extends Phaser.Scene { create() { this.player = new Player(this, 100, 100); // Exemple d’ús d’una funció auxiliar let randomX = randomInt(0, 800); // Crear un enemic a una posició aleatòria } }
Exercicis pràctics
Exercici 1: Crea una nova escena
Enunciat:
Crea una nova escena anomenada MenuScene
dins la carpeta src/scenes/
. Aquesta escena ha de mostrar el text "Benvingut al Joc!" al centre de la pantalla.
Solució:
// src/scenes/MenuScene.js export default class MenuScene extends Phaser.Scene { constructor() { super({ key: 'MenuScene' }); } create() { this.add.text(400, 300, 'Benvingut al Joc!', { fontSize: '32px', color: '#ffffff' }).setOrigin(0.5); } }
Consell:
Assegura’t d’afegir la nova escena a la configuració del joc perquè es pugui mostrar.
Exercici 2: Refactoritza el codi del jugador
Enunciat:
Mou la lògica del jugador a una classe separada Player.js
dins de src/objects/
i utilitza-la a la teva escena principal.
Solució:
// src/objects/Player.js export default class Player extends Phaser.Physics.Arcade.Sprite { constructor(scene, x, y) { super(scene, x, y, 'player'); scene.add.existing(this); scene.physics.add.existing(this); } } // src/scenes/GameScene.js import Player from '../objects/Player.js'; create() { this.player = new Player(this, 100, 100); }
Error comú:
Oblidar-se d’afegir l’objecte a la física o a l’escena pot fer que no aparegui o no funcioni correctament.
Resum
- Organitzar el codi en fitxers i carpetes lògiques facilita el manteniment i l’escalabilitat.
- Utilitza escenes per separar les diferents parts del joc.
- Crea classes per als objectes del joc i utilitza funcions auxiliars per a tasques repetitives.
- Segueix una estructura clara i coherent per facilitar la col·laboració i el creixement del projecte.
Amb aquests fonaments, estaràs preparat per gestionar projectes de jocs més grans i complexos de manera eficient. El següent tema tractarà la gestió de múltiples escenes per a una experiència de joc més rica i organitzada.
Phaser - Desenvolupament de jocs amb JavaScript
Mòdul 1: Introducció al desenvolupament de jocs i Phaser
- Què és el desenvolupament de jocs?
- Visió general de Phaser
- Configuració del teu entorn de desenvolupament
- El teu primer projecte amb Phaser
Mòdul 2: Fonaments de Phaser
- Entendre el bucle del joc
- Configuració del joc i escenes
- Carregar i mostrar imatges
- Treballar amb text
- Gestió d’entrada (teclat i ratolí)
Mòdul 3: Sprites i animació
- Què són els sprites?
- Afegir i moure sprites
- Fonaments de l’animació de sprites
- Grups de sprites i gestió
Mòdul 4: Física i interactivitat en el joc
- Introducció a la física a Phaser
- Activar la física en els sprites
- Col·lisions i superposicions
- Objectes interactius i esdeveniments
Mòdul 5: Món del joc i càmera
Mòdul 6: Àudio i interfície d’usuari
Mòdul 7: Arquitectura del joc i gestió d’estats
Mòdul 8: Funcionalitats avançades de joc
- Efectes de partícules
- Tweens i animacions
- Timers i esdeveniments retardats
- IA i comportament dels enemics