En aquesta secció, aprendràs a construir un joc complet utilitzant Phaser, aplicant tots els coneixements adquirits al llarg del curs. El procés es divideix en passos clars i seqüencials, des de la creació de l’estructura bàsica fins a la implementació de mecàniques, interfície i poliment final.


  1. Definició de l’estructura bàsica del joc

Conceptes clau:

  • Escenes: Separar el joc en diferents escenes (menú, joc, fi de partida).
  • Configuració inicial: Definir la mida, el renderitzador i altres opcions bàsiques.
  • Organització del codi: Mantenir el codi modular i fàcil de mantenir.

Exemple de codi: Configuració inicial i escenes

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: [MenuScene, GameScene, GameOverScene],
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 },
            debug: false
        }
    }
};

const game = new Phaser.Game(config);

Explicació:

  • type: Selecciona automàticament el renderitzador (WebGL o Canvas).
  • width i height: Dimensions de la pantalla del joc.
  • scene: Llista d’escenes que utilitzarà el joc.
  • physics: Configuració del sistema físic (en aquest cas, Arcade Physics).

  1. Creació de les escenes principals

Llistat d’escenes típiques:

  • MenuScene: Pantalla d’inici amb botó per començar.
  • GameScene: On es desenvolupa l’acció principal.
  • GameOverScene: Mostra el resultat i permet reiniciar.

Exemple de codi: Estructura d’una escena

class MenuScene extends Phaser.Scene {
    constructor() {
        super({ key: 'MenuScene' });
    }

    create() {
        this.add.text(300, 250, 'El Meu Joc', { fontSize: '32px', fill: '#fff' });
        const startButton = this.add.text(350, 350, 'Començar', { fontSize: '24px', fill: '#0f0' })
            .setInteractive()
            .on('pointerdown', () => this.scene.start('GameScene'));
    }
}

Explicació:

  • this.add.text: Afegeix text a la pantalla.
  • .setInteractive(): Fa que el text sigui clicable.
  • .on('pointerdown', ...): Defineix l’acció quan es fa clic.

  1. Disseny del món del joc i afegir jugadors/sprites

Passos:

  • Carregar recursos (imatges, spritesheets).
  • Afegir el jugador i altres objectes.
  • Definir la lògica de moviment i col·lisions.

Exemple de codi: Afegir un jugador

class GameScene extends Phaser.Scene {
    constructor() {
        super({ key: 'GameScene' });
    }

    preload() {
        this.load.image('player', 'assets/player.png');
    }

    create() {
        this.player = this.physics.add.sprite(400, 300, 'player');
        this.cursors = this.input.keyboard.createCursorKeys();
    }

    update() {
        if (this.cursors.left.isDown) {
            this.player.setVelocityX(-160);
        } else if (this.cursors.right.isDown) {
            this.player.setVelocityX(160);
        } else {
            this.player.setVelocityX(0);
        }

        if (this.cursors.up.isDown) {
            this.player.setVelocityY(-160);
        } else if (this.cursors.down.isDown) {
            this.player.setVelocityY(160);
        } else {
            this.player.setVelocityY(0);
        }
    }
}

Explicació:

  • preload(): Carrega la imatge del jugador.
  • create(): Afegeix el sprite i configura les tecles de moviment.
  • update(): Controla el moviment segons les tecles premudes.

  1. Implementació de mecàniques bàsiques (col·leccionables, enemics, puntuació)

Llistat de mecàniques habituals:

  • Col·leccionables: Objectes que el jugador pot recollir.
  • Enemics: Objectes que el jugador ha d’evitar o derrotar.
  • Puntuació: Comptador de punts.

Taula: Exemples de mecàniques i implementació

Mecànica Exemple de codi Explicació breu
Col·leccionable this.physics.add.overlap(player, coin, collectCoin); Detecta col·lisió amb moneda
Enemic this.physics.add.collider(player, enemy, hitEnemy); Detecta col·lisió amb enemic
Puntuació score += 10; scoreText.setText('Punts: ' + score); Actualitza la puntuació

Exemple de codi: Col·leccionable

preload() {
    this.load.image('coin', 'assets/coin.png');
}

create() {
    this.coin = this.physics.add.sprite(200, 200, 'coin');
    this.physics.add.overlap(this.player, this.coin, this.collectCoin, null, this);
    this.score = 0;
    this.scoreText = this.add.text(16, 16, 'Punts: 0', { fontSize: '24px', fill: '#fff' });
}

collectCoin(player, coin) {
    coin.disableBody(true, true);
    this.score += 10;
    this.scoreText.setText('Punts: ' + this.score);
}

  1. Gestió de l’estat de la partida i finalització

Passos:

  • Detectar quan el jugador perd o guanya.
  • Passar a l’escena de fi de partida.
  • Mostrar la puntuació final i opcions de reinici.

Exemple de codi: Fi de partida

hitEnemy(player, enemy) {
    this.physics.pause();
    player.setTint(0xff0000);
    this.scene.start('GameOverScene', { score: this.score });
}
class GameOverScene extends Phaser.Scene {
    constructor() {
        super({ key: 'GameOverScene' });
    }

    init(data) {
        this.finalScore = data.score;
    }

    create() {
        this.add.text(300, 250, 'Fi de la partida', { fontSize: '32px', fill: '#fff' });
        this.add.text(320, 300, 'Puntuació: ' + this.finalScore, { fontSize: '24px', fill: '#fff' });
        this.add.text(320, 350, 'Prem qualsevol tecla per reiniciar', { fontSize: '18px', fill: '#fff' });

        this.input.keyboard.once('keydown', () => {
            this.scene.start('MenuScene');
        });
    }
}

  1. Afegir interfície d’usuari i polir el joc

Recomanacions:

  • Mostra la puntuació i vides de manera clara.
  • Afegeix sons i efectes visuals.
  • Ajusta la dificultat i la resposta dels controls.

Exercici pràctic

Enunciat:
Crea una escena de joc on el jugador pugui moure’s amb les fletxes, recollir monedes i evitar enemics. Quan el jugador col·lisiona amb un enemic, el joc ha d’acabar i mostrar la puntuació final.

Solució orientativa

// Preload
this.load.image('player', 'assets/player.png');
this.load.image('coin', 'assets/coin.png');
this.load.image('enemy', 'assets/enemy.png');

// Create
this.player = this.physics.add.sprite(400, 300, 'player');
this.coin = this.physics.add.sprite(200, 200, 'coin');
this.enemy = this.physics.add.sprite(600, 300, 'enemy');
this.cursors = this.input.keyboard.createCursorKeys();
this.score = 0;
this.scoreText = this.add.text(16, 16, 'Punts: 0', { fontSize: '24px', fill: '#fff' });

this.physics.add.overlap(this.player, this.coin, () => {
    this.coin.disableBody(true, true);
    this.score += 10;
    this.scoreText.setText('Punts: ' + this.score);
}, null, this);

this.physics.add.collider(this.player, this.enemy, () => {
    this.physics.pause();
    this.player.setTint(0xff0000);
    this.scene.start('GameOverScene', { score: this.score });
}, null, this);

// Update
if (this.cursors.left.isDown) {
    this.player.setVelocityX(-160);
} else if (this.cursors.right.isDown) {
    this.player.setVelocityX(160);
} else {
    this.player.setVelocityX(0);
}

if (this.cursors.up.isDown) {
    this.player.setVelocityY(-160);
} else if (this.cursors.down.isDown) {
    this.player.setVelocityY(160);
} else {
    this.player.setVelocityY(0);
}

Errors comuns i consells:

  • Oblidar carregar els recursos: Assegura’t que les imatges estiguin a la carpeta correcta i es carreguin al preload().
  • No reiniciar l’estat del joc: Quan es reinicia la partida, assegura’t de restablir la puntuació i la posició dels objectes.
  • Col·lisions no funcionen: Comprova que els objectes tinguin física activada i que utilitzes overlap o collider segons correspongui.

Resum

En aquest tema has après a construir un joc complet amb Phaser, des de la configuració inicial fins a la implementació de mecàniques bàsiques, gestió d’escenes i poliment final. Has vist exemples pràctics i una solució orientativa per consolidar els coneixements. Ara ja estàs preparat per crear i personalitzar els teus propis jocs, afegint noves funcionalitats i millorant l’experiència de joc!

Pròxim pas:
Passa a la secció de polir i finalitzar el teu joc per donar-li un acabat professional i preparar-lo per ser presentat.

Phaser - Desenvolupament de jocs amb JavaScript

Mòdul 1: Introducció al desenvolupament de jocs i Phaser

Mòdul 2: Fonaments de Phaser

Mòdul 3: Sprites i animació

Mòdul 4: Física i interactivitat en el joc

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

Mòdul 9: Desplegament i optimització

Mòdul 10: Projecte final

© Copyright 2024. Tots els drets reservats