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.js
export default class MenuScene extends Phaser.Scene { // ... }
-
src/scenes/GameScene.js
import Player from '../objects/Player.js'; export default class GameScene extends Phaser.Scene { // ... }
-
src/objects/Player.js
export default class Player extends Phaser.Physics.Arcade.Sprite { // ... }
-
src/main.js
import 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.js
en 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