Empezando con Phaser 3
Phaser es un entorno de programación que tiene como objetivo ayudar a crear juegos de forma rápida en HTML5. Fue creado específicamente para aprovechar los beneficios de los navegadores modernos, tanto de escritorio como móviles. El único requisito del navegador es el soporte de canvas.
Incluye una amplia y detallada documentación, características y ejemplos para que se pueda avanzar rápidamente en el desarrollo del juego. Es compatible con WebGL y es Open Source.
Podemos acceder a más información y a toda la documentación desde su página web https://phaser.io/
Herramientas
A continuación os mostraré el conjunto de herramientas que vamos a ir utilizando a lo largo del tutorial.
Visual Studio Code
Podemos utilizar cualquier IDE de desarrollo que tenga soporte para TypeScript. En mi caso Visual Studio Code es la herramienta que utilizaré. Se puede instalar desde su página web https://code.visualstudio.com/.
Node
También necesitamos node y npm para poder crear, compilar y ejecutar el proyecto generado en TypeScript. Si fueramos a trabajar directamente con javascript no sería necesario, pero al tratarse de TypeScript necesitaremos compilar el proyecto. Se puede instalar desde su página web https://nodejs.org/
Comprueba que tienes instalada esta herramienta ejecutando en consola el comando node --version
y npm --version
Yarn
Es la herramienta que utilizaremos para gestionar las dependencias de librerías del proyecto. Se podría utilizar directamente npm, pero hemos decidido elegir la opción de yarn por ser un poco más cómodo de utilizar. Se puede instalar desde su página web https://yarnpkg.com/.
Comprueba que tienes instalada esta herramienta ejecutando en consola el comando yarn --version
Creación de proyecto
Ahora que ya tenemos todas las herramientas necesarias instaladas, vamos a crear el proyecto para nuestro juego. Podemos crear el proyecto de cero paso a paso, o bien descargarnos una plantilla con todos los pasos configurados.
Creación mediante plantilla
Lo más rápido es acceder a la plantilla rápida que he creado en el repositorio https://github.com/dummysoft/template_phaser3 donde podréis hacer un fork o descargar el proyecto en zip. Lo descomprimís en el directorio que queráis y ya tenéis el proyecto listo para ser abierto con el IDE.
Creado
Si has creado el proyecto mediante una plantilla, puedes saltarte los siguientes pasos de creación manual, dependencias y configuración, hasta el siguiente punto de "Hello World"
Creación manual del proyecto
Lo primero será crear el directorio donde desarrollaremos nuestro juego. Una vez tenemos la carpeta creada, debemos inicializar el proyecto con el comando yarn init
dentro de la carpeta del juego. Nos irá lanzando preguntas como el nombre del proyecto, la versión y la descripción. Esto creará un fichero package.json
que contiene la información del proyecto.
Añadir dependencias
A continuación se deben añadir las dependencias que vamos a utilizar en nuestro proyecto. Para ello vamos a ejecutar los siguientes comandos
yarn add --dev copy-webpack-plugin ts-loader typescript webpack webpack-cli webpack-dev-server
yarn add phaser
El primer comando añadirá las dependencias necesarias para configurar y ejecutar un proyecto web, y el segundo comando añadirá la dependencia con la librería de Phaser. Al no poner ninguna versión, se descargará siempre la última versión disponible de cada una de las librerías, lo que puede provocar que el resto del tutorial no funcione. Este tutorial lo he realizado con las siguientes versiones
"devDependencies": {
"copy-webpack-plugin": "6.0.1",
"ts-loader": "7.0.5",
"typescript": "3.9.3",
"webpack": "4.43.0",
"webpack-cli": "3.3.11",
"webpack-dev-server": "3.11.0"
},
"dependencies": {
"phaser": "3.23.0"
}
Si alguna no coincide y queréis modificarla, se puede editar el fichero package.json
. Recordad que si modificáis el fichero de dependencias, tendréis que refrescarlas utilizando el comando yarn
Configurar webpack
El siguiente paso será configurar el plugin webpack para poder ejecutar un servidor web en local que nos sirva los recursos web. Para ello tendremos que crear un fichero llamado webpack.config.js
que deberá tener el siguiente contenido. También os podéis descargar el contenido del fichero desde el siguiente enlace a Github que os dejo a continuación https://github.com/dummysoft/template_phaser3/blob/master/webpack.config.js
const path = require('path');
const webpack = require('webpack');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
app: './src/Main.ts',
vendors: ['phaser']
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
devtool: 'inline-source-map',
resolve: {
extensions: [ '.ts', '.tsx', '.js' ]
},
output: {
filename: 'app.bundle.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development',
devServer: {
contentBase: path.resolve(__dirname, 'dist'),
https: false,
host: '0.0.0.0',
port: 8080,
disableHostCheck: true,
},
plugins: [
new CopyPlugin({
patterns: [
{ from: path.resolve(__dirname, 'index.html'),
to: path.resolve(__dirname, 'dist') },
{ from: 'assets', to: 'assets', noErrorOnMissing: true},
],
}),
new webpack.DefinePlugin({
'typeof CANVAS_RENDERER': JSON.stringify(true),
'typeof WEBGL_RENDERER': JSON.stringify(true)
}),
],
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
Básicamente con este fichero le estamos diciendo que módulos/librerías debe incluir en el compilado, como debe compilar y que directorios debe incluir y donde debe copiar todos los recursos. Además, también tenemos una sección donde configuraremos el servidor de desarrollo que se ejecutará en local, puerto, permisos y protocolo http o https.
Si queréis indagar más en el formato de este fichero podéis visitar la web del plugin https://webpack.js.org/ donde encontraréis más información.
Configurar TypeScript
El último paso para configurar el entorno es definir como debe compilar TypeScript. Para ello, creamos un fichero con nombre tsconfig.json
donde pegaremos el siguiente contenido.
{
"compilerOptions": {
"target": "es5",
"sourceMap": true
},
"include": [
"**/*.ts"
]
}
En este fichero se indica donde está el código fuente y cual es la versión de TypeScript que vamos a utilizar en el proyecto.
Añadir scripts para ejecución
Para terminar la configuración, debemos crear los scripts de código, y antes de eso debemos crear dos directorios dentro de la carpeta del juego:
assets
que es donde alojaremos los recursos del juegosrc
que es donde alojaremos el código TypeScript del juego
Dentro de la carpeta src
crearemos un fichero Main.ts
donde escribiremos la rutina principal del juego. Por ahora vamos a copiar el siguiente contenido y más adelante ya explicaré el código.
import * as Phaser from 'phaser';
const gameConfig: Phaser.Types.Core.GameConfig = {
title: 'demo',
type: Phaser.AUTO,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
width: 800,
height: 600,
parent: 'content'
},
backgroundColor: '#000000',
scene: [],
};
const Game = new Phaser.Game(gameConfig);
También crearemos un fichero index.html
donde pondremos la página inicial de nuestro juego. Por ahora copiaremos el siguiente contenido.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo</title>
<meta name="viewport"
content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta http-equiv="cleartype" content="on">
<style>
html,
body {
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
}
</style>
</head>
<body>
<div id="content" style="height: 100vh;"></div>
<script src="vendors.app.bundle.js"></script>
<script src="app.bundle.js"></script>
</body>
</html>
Por último, vamos a crear dos scripts sencillos para poder lanzar el proyecto mediante un comando sencillo. Para ello editamos el fichero package.json
y le añadimos al final un bloque de scripts.
{
...
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server"
}
}
Con esto nos aseguramos que ejecutando el comando yarn build
compilará nuestro código fuente para generar la distribución de nuestro juego, y ejecutando el comando yarn dev
compilará el código y levantará un servidor web local en el puerto 8080, donde podrémos acceder e ir probando nuestro juego.
Creado
A partir de este punto ya tienes el proyecto creado y configurado de forma manual. Ya puedes pasar al siguiente punto de "Hello World"
Hello Word
Estructura de proyecto
Una vez creado el proyecto, vamos a desarrollar nuestro primer HelloWorld. Pero antes vamos a echar un ojo a la estructura del proyecto que tenemos creado. Tanto si has descargado el template desde Github como si has seguido los pasos manuales, deberías tener la siguiente estructura de proyecto
Los información más relevante de esta estructura es la siguiente:
package.json
contiene la configuración del proyecto y los scripts de generacióntsconfig.son
contiene la configuración de TypeScriptwebpack.config.js
contiene la configuración del servidor web localassets
contiene los recursos del juego (imágenes, música, datos)src
contiene el código fuente del juegoMain.ts
es la clase principal que se ejecutará nada más abrir el juego
Creamos una nueva Scene
Ojo
En este ejemplo no comentaré muy en profundidad el código fuente, simplemente quiero que sea un ejemplo de crear un juego en el que aparezca algo en pantalla. En las siguientes secciones de este tutorial ya explicaré más a fondo el significado de cada clase y objeto.
Para esta pequeña demo de "HelloWorld" vamos a mostrar un texto en la pantalla y una imagen estática. Lo primero que debemos hacer es crear una nueva clase HelloWorldScene.ts
donde codificaremos el funcionamiento de nuestra pantalla o escena. El fichero debe contener lo siguiente:
const sceneConfig: Phaser.Types.Scenes.SettingsConfig = {
key: 'scene-helloworld',
};
export class HelloWorldScene extends Phaser.Scene {
constructor() {
super(sceneConfig);
}
public preload() {
this.load.image('logo', 'http://labs.phaser.io/assets/sprites/phaser3-logo.png');
}
public create() {
this.add.text(this.cameras.main.centerX, 70, 'Hello Word').setOrigin(0.5, 0.5).setFontSize(64);
this.add.sprite(this.cameras.main.centerX, this.cameras.main.centerY, 'logo');
}
}
Añadimos Scene al Game
Y ahora, añadiremos esta escena al juego principal. Abrimos el fichero Main.ts
y en la propiedad scene
añadimos la clase que acabamos de crear:
...
const gameConfig: Phaser.Types.Core.GameConfig = {
title: 'demo',
type: Phaser.AUTO,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
width: 800,
height: 600,
parent: 'content'
},
backgroundColor: '#000000',
scene: [HelloWorldScene],
};
...
Si ahora ejecutamos el juego en el navegador, veremos una pantalla con un texto en la parte superior y una imagen centrada en la pantalla.