Organizar el código es fundamental para cualquier proyecto de software, y en el desarrollo de juegos con Phaser no es la excepción. Una buena organización facilita el mantenimiento, la escalabilidad y la colaboración en equipo. En esta sección aprenderás cómo estructurar tu código de manera eficiente utilizando las mejores prácticas de la industria.
Conceptos Clave
- Modularidad: Separar el código en archivos y módulos independientes según su funcionalidad.
- Reutilización: Escribir funciones y clases reutilizables para evitar duplicación.
- Legibilidad: Mantener el código claro y fácil de entender.
- Escalabilidad: Permitir que el proyecto crezca sin volverse inmanejable.
- Separación de responsabilidades: Cada parte del código debe tener una función clara y específica.
Estructura Recomendada de Carpetas y Archivos
Una estructura típica para un proyecto Phaser puede ser la siguiente:
| Carpeta/Archivo | Descripción |
|---|---|
index.html |
Archivo principal HTML que carga el juego |
src/ |
Código fuente del juego |
src/main.js |
Punto de entrada del juego |
src/scenes/ |
Escenas del juego (menú, juego, game over, etc.) |
src/objects/ |
Clases de objetos personalizados (jugador, enemigos) |
src/utils/ |
Funciones y utilidades generales |
assets/ |
Imágenes, sonidos y otros recursos |
package.json |
Dependencias y scripts del proyecto (si usas npm) |
Ejemplo de Organización de Código
Supongamos que tienes un juego simple con una escena de menú y una escena de juego. Así podrías organizarlo:
/mi-juego/
│
├── index.html
├── src/
│ ├── main.js
│ ├── scenes/
│ │ ├── MenuScene.js
│ │ └── GameScene.js
│ ├── objects/
│ │ └── Player.js
│ └── utils/
│ └── helpers.js
└── assets/
├── images/
└── sounds/Ejemplo Práctico: Separando Escenas y Objetos
- Archivo principal (
main.js)
main.js)import MenuScene from './scenes/MenuScene.js';
import GameScene from './scenes/GameScene.js';
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
scene: [MenuScene, GameScene],
physics: {
default: 'arcade',
arcade: { debug: false }
}
};
const game = new Phaser.Game(config);Explicación:
Aquí importamos las escenas y las agregamos al arreglo scene en la configuración de Phaser. Esto permite que Phaser gestione las transiciones entre escenas.
- Escena de Menú (
scenes/MenuScene.js)
scenes/MenuScene.js)export default class MenuScene extends Phaser.Scene {
constructor() {
super({ key: 'MenuScene' });
}
create() {
this.add.text(300, 250, 'Presiona ESPACIO para Jugar', { fontSize: '24px', fill: '#fff' });
this.input.keyboard.once('keydown-SPACE', () => {
this.scene.start('GameScene');
});
}
}Explicación:
Esta clase define la escena del menú. Al presionar la barra espaciadora, se inicia la escena del juego.
- Escena de Juego (
scenes/GameScene.js)
scenes/GameScene.js)import Player from '../objects/Player.js';
export default class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
}
create() {
this.player = new Player(this, 400, 300);
}
update() {
this.player.update();
}
}Explicación:
Aquí se instancia el jugador usando una clase personalizada y se llama a su método update en cada frame.
- Objeto Jugador (
objects/Player.js)
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);
this.setCollideWorldBounds(true);
this.cursors = scene.input.keyboard.createCursorKeys();
}
update() {
this.setVelocity(0);
if (this.cursors.left.isDown) {
this.setVelocityX(-160);
} else if (this.cursors.right.isDown) {
this.setVelocityX(160);
}
if (this.cursors.up.isDown) {
this.setVelocityY(-160);
} else if (this.cursors.down.isDown) {
this.setVelocityY(160);
}
}
}Explicación:
La clase Player hereda de Phaser.Physics.Arcade.Sprite y encapsula toda la lógica del jugador, incluyendo el movimiento.
Ejercicio Práctico
Ejercicio:
Organiza el siguiente código en archivos separados siguiendo la estructura recomendada. El código consiste en una escena de menú y una escena de juego donde aparece un jugador que puede moverse.
// Código base (todo en un archivo)
class MenuScene extends Phaser.Scene {
// ...
}
class GameScene extends Phaser.Scene {
// ...
}
class Player extends Phaser.Physics.Arcade.Sprite {
// ...
}
const config = {
// ...
};
const game = new Phaser.Game(config);Instrucciones:
- Crea una carpeta
src/con subcarpetasscenes/yobjects/. - Mueve cada clase a su propio archivo.
- Ajusta los imports y exports para que el código funcione correctamente.
Solución
-
src/scenes/MenuScene.jsexport default class MenuScene extends Phaser.Scene { // ... } -
src/scenes/GameScene.jsimport Player from '../objects/Player.js'; export default class GameScene extends Phaser.Scene { // ... } -
src/objects/Player.jsexport default class Player extends Phaser.Physics.Arcade.Sprite { // ... } -
src/main.jsimport MenuScene from './scenes/MenuScene.js'; import GameScene from './scenes/GameScene.js'; const config = { // ... scene: [MenuScene, GameScene], }; const game = new Phaser.Game(config);
Errores comunes:
- Olvidar ajustar las rutas de importación (por ejemplo, usar
./objects/Player.jsen vez de soloPlayer.js). - No exportar las clases con
export default. - No importar las escenas en el archivo principal.
Consejo:
Utiliza nombres descriptivos para tus archivos y carpetas. Mantén cada archivo enfocado en una sola responsabilidad.
Resumen
En esta sección aprendiste:
- La importancia de organizar el código en proyectos de juegos.
- Cómo estructurar carpetas y archivos en un proyecto Phaser.
- Cómo separar escenas y objetos en módulos independientes.
- Cómo importar y exportar clases para mantener el código limpio y escalable.
Una buena organización te permitirá trabajar de manera más eficiente y facilitará la colaboración en proyectos más grandes. En la siguiente sección, aprenderás a gestionar múltiples escenas y cómo navegar entre ellas de forma efectiva.
Phaser - Desarrollo de Juegos con JavaScript
Módulo 1: Introducción al Desarrollo de Juegos y Phaser
- ¿Qué es el Desarrollo de Juegos?
- Descripción general de Phaser
- Configurando tu Entorno de Desarrollo
- Tu Primer Proyecto con Phaser
Módulo 2: Fundamentos de Phaser
- Entendiendo el Bucle de Juego
- Configuración del Juego y Escenas
- Cargando y Mostrando Imágenes
- Trabajando con Texto
- Manejo de Entrada (Teclado y Ratón)
Módulo 3: Sprites y Animación
- ¿Qué son los Sprites?
- Añadiendo y Moviendo Sprites
- Fundamentos de Animación de Sprites
- Grupos de Sprites y Gestión
Módulo 4: Física e Interactividad en el Juego
- Introducción a la Física en Phaser
- Habilitando Física en Sprites
- Colisiones y Superposiciones
- Objetos Interactivos y Eventos
Módulo 5: Mundo del Juego y Cámara
- Creando Tilemaps y Mundos de Juego
- Desplazamiento y Control de Cámara
- Capas y Gestión de Profundidad
Módulo 6: Audio e Interfaz de Usuario
Módulo 7: Arquitectura del Juego y Gestión de Estados
- Organizando el Código del Juego
- Gestionando Múltiples Escenas
- Guardando y Cargando el Estado del Juego
Módulo 8: Características Avanzadas de Jugabilidad
- Efectos de Partículas
- Tweens y Animaciones
- Temporizadores y Eventos Retardados
- IA y Comportamiento de Enemigos
