Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.
Carga background
Cargamos la imagen de fondo del juego.
Carga jugadores con función
preload(){
...
this.load.spritesheet('player0', '../img/player0.png', {frameWidth: 64, frameHeight: 32});
...
}
create() {
...
this.coordenadasPlayers = [
{x: 280, y: 500},
{x: 360, y: 500},
{x: 300, y: 550},
{x: 380, y: 550},
];
this.players = [];
this.n_jugadores = 4;
this.creaPlayers();
}
creaPlayers() {
for (let i = 0; i < this.n_jugadores; i++) {
//Creamos el jugador. Lo almacenamos en un array de jugadores porque nos será más fácil en adelante aplicar funcionalidades a todos los jugadores
this.players[i] = this.matter.add.sprite(this.coordenadasPlayers[i].x, this.coordenadasPlayers[i].y, `player${i}`);
//Creamos la animación del jugador
this.anims.create({
key: `volar${i}`,
frames: this.anims.generateFrameNumbers(`player${i}`, {start: 0, end: 1}),
frameRate: 10,
repeat: -1,
});
//Vinculamos la animación al jugador creado y comenzamos su reproducción.
//El primer parámetro de la función volar es el nombre de la animación, y el segundo, si la animación se va a ejecutar indefinidamente
this.players[i].play(`volar${i}`, true);
}
}
const config = {
...
physics: {
default: 'matter',
matter: {
gravity: {
y: 0,
},
},
},
};
Mover jugador hacia delante
update() {
for (let i = 0; i < this.n_jugadores; i++) {
this.players[i].thrust(-0.001);
}
}
Rotar
create(){
...
this.cursors = this.input.keyboard.createCursorKeys();
}
update() {
for (let i = 0; i < this.n_jugadores; i++) {
this.players[i].thrust(-0.003);
if (this.cursors.left.isDown)
this.players[i].setAngularVelocity(-0.065);
else if (this.cursors.right.isDown)
this.players[i].setAngularVelocity(0.065);
}
}
}
Controles visuales
create(){
this.coordenadasPlayers = [
{x: 280, y: 500, leftbtn: {x: 30, y: 540, rotacion :45}, rightbtn: {x: 90, y: 600, rotacion :45}},
{x: 360, y: 500, leftbtn: {x: 870, y: 30, rotacion :45}, rightbtn: {x: 930, y: 90, rotacion :45}},
{x: 300, y: 550, leftbtn: {x: 30, y: 90, rotacion :-45}, rightbtn: {x: 90, y: 30, rotacion :-45}},
{x: 380, y: 550, leftbtn: {x: 870, y: 600, rotacion :-45}, rightbtn: {x: 930, y: 540, rotacion :-45}}
];
...
}
creaPlayers() {
for (let i = 0; i < this.n_jugadores; i++) {
//Código del bucle que no pongo porque ocupa mucho
this.controlesVisuales(i);
}
}
controlesVisuales(n) {
this.players[n].setData('direccionHorizontal', 0);
const leftbtn = this.add.sprite(this.coordenadasPlayers[n].leftbtn.x, this.coordenadasPlayers[n].leftbtn.y, 'flecha').setInteractive();
leftbtn.angle = this.coordenadasPlayers[n].leftbtn.rotacion;
const rightbtn = this.add.sprite(this.coordenadasPlayers[n].rightbtn.x, this.coordenadasPlayers[n].rightbtn.y, 'flecha').setInteractive();
rightbtn.angle = this.coordenadasPlayers[n].rightbtn.rotacion;
rightbtn.flipX = true;
}
Añadir funcionalidad a los controles visuales
create(){
...
this.cursors = this.input.keyboard.createCursorKeys();
}
controlesVisuales(n) {
...
rightbtn.on('pointerdown', function() {
this.scene.players[n].setData('direccionHorizontal', 1);
});
leftbtn.on('pointerdown', function() {
this.scene.players[n].setData('direccionHorizontal', -1);
});
rightbtn.on('pointerup', function() {
this.scene.players[n].setData('direccionHorizontal', 0);
});
leftbtn.on('pointerup', function() {
this.scene.players[n].setData('direccionHorizontal', 0);
});
}
update() {
for (let i = 0; i < this.n_jugadores; i++) {
this.players[i].thrust(-0.003);
if (this.cursors.left.isDown || this.players[i].getData('direccionHorizontal') === -1)
this.players[i].setAngularVelocity(-0.065);
else if (this.cursors.right.isDown || this.players[i].getData('direccionHorizontal') === 1)
this.players[i].setAngularVelocity(0.065);
}
}
Physics Editor
preload(){
...
this.load.image('ladoizquierdo', '../img/ladoizquierdo.png');
this.load.image('ladoderecho', '../img/ladoderecho.png');
this.load.image('centro', '../img/centro.png');
this.load.image('luna', '../img/luna.png');
this.load.image('saturno', '../img/saturno.png');
this.load.image('astronauta', '../img/astronauta.png');
this.load.json('muros', '../img/muros.json');
}
create(){
...
const muros = this.cache.json.get('muros');
const ladoizquierda = this.matter.add.sprite(181, 303, 'ladoizquierdo', null, {shape: muros.ladoizquierdo});
const ladoderecha = this.matter.add.sprite(797, 314.5, 'ladoderecho', null, {shape: muros.ladoderecho});
const centro = this.matter.add.sprite(472, 344, 'centro', null, {shape: muros.centro});
const luna = this.matter.add.sprite(170, 160, 'luna', null, {shape: muros.luna});
const astronauta = this.matter.add.sprite(717, 240, 'astronauta', null, {shape: muros.astronauta});
const saturno = this.matter.add.sprite(740, 150, 'saturno', null, {shape: muros.saturno});
}
La luna rebota
luna.setBounce(1.5);
Detectar vueltas
create(){
...
this.matter.add.rectangle(175, 500, 135, 30, {
isSensor: true,
marker: 1,
angle: -0.25 * Math.PI
});
//collisionstart detecta la colisión entre cualquier forma y cualquier forma
this.matter.world.on('collisionstart', (event) => {
// La variable pairs almacena todos los objetos que están colisionando
var pairs = event.pairs;
for (var i = 0; i < pairs.length; i++) {
// Estamos detectando la colisión entre objetos de cualquier tipo. Por tanto, también estamos detectando la colisión entre jugadores y objetos de diversa índole que no interesan. El siguiente condicional filtra para sólo tener en cuenta las colisiones donde uno de los elementos colisionados tiene la propiedad isSensor con valor True
if (pairs[i].isSensor) {
alert('colision');
}
}
});
}
Poner marcador
pintarMarcador() {
this.add.text(400, 275, 'P1:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.add.text(480, 275, 'P2:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.add.text(400, 315, 'P3:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.add.text(480, 315, 'P4:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.marcadorCoche0 = this.add.text(440, 275, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
this.marcadorCoche1 = this.add.text(520, 275, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
this.marcadorCoche2 = this.add.text(440, 315, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
this.marcadorCoche3 = this.add.text(520, 315, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
}
Aumentar marcador
for (var i = 0; i < pairs.length; i++) {
if (pairs[i].isSensor) {
// En las dos siguientes líneas estamos haciendo una deconstrucción de una propiedad en Javascript. En lugar de este código podíamos haber hecho también: const bodyA = pairs[i].bodyA
const {bodyA} = pairs[i];
const {bodyB} = pairs[i];
// Cuando se produce la colisión que nos interesa detectar, uno de los elementos que colisionan será el area que colocamos en el paso anterior y el otro será el jugador. El jugador no tiene la propiedad isSensor a true, por tanto, utilizaremos esa propiedad para evaluar quien es quien. De esta forma, la variable zone almacenará el area, mientras que la variable playerBody almacenará el jugador.
let zone;
let playerBody;
if (bodyA.isSensor) {
zone = bodyA;
playerBody = bodyB;
} else if (bodyB.isSensor) {
zone = bodyB;
playerBody = bodyA;
}
const playerSprite = playerBody.gameObject;
const playerKey = playerSprite.texture.key;
const playerIndex = playerKey.substr(-1);
playerSprite.data.values.marcador++;
this[`marcadorCoche${playerIndex}`].text = `${playerSprite.getData('marcador')}`;
}
}
creaPlayers() {
...
this.players[i].setData('marcador', 0);
}
Evitar que el jugador haga trampas
create() {
...
this.matter.add.rectangle(450, 150, 30, 60, {isSensor: true, marker: 2});
this.matter.add.rectangle(760, 400, 90, 30, {isSensor: true, marker: 3});
this.matter.add.rectangle(500, 505, 30, 70, {isSensor: true, marker: 4});
...
if (pairs[i].isSensor) {
...
const playerIndex = playerKey.substr(-1);
if (playerSprite.getData('marker') === zone.marker) {
if (zone.marker === 4) {
playerSprite.setData('marker', 1);
} else {
if (zone.marker === 1) {
playerSprite.data.values.marcador++;
this[`marcadorCoche${playerIndex}`].text = playerSprite.getData('marcador');
}
playerSprite.data.values.marker++;
}
}
}
}
this.players[i].setData('marker', 2)
Alguien gana el juego
if (playerSprite.getData('marcador') === 2) {
alert(`gano el player ${playerKey}`);
this.scene.start('ganarScene');
}
Con portada
class EscenaPortada extends Phaser.Scene {
constructor() {
super({key: 'EscenaPortada'});
}
preload() {
this.load.image('portada', '../img/portada/portada.jpg');
this.load.image('2jugadores', '../img/portada/2.png');
this.load.image('3jugadores', '../img/portada/3.png');
this.load.image('4jugadores', '../img/portada/4.png');
}
create() {
this.add.sprite(480, 320, 'portada');
const opcion2Jugadores = this.add.sprite(280, 550, '2jugadores').setInteractive();
const opcion3Jugadores = this.add.sprite(480, 550, '3jugadores').setInteractive();
const opcion4Jugadores = this.add.sprite(680, 550, '4jugadores').setInteractive();
opcion2Jugadores.on('pointerdown', () => this.opcionJugador(2));
opcion3Jugadores.on('pointerdown', () => this.opcionJugador(3));
opcion4Jugadores.on('pointerdown', () => this.opcionJugador(4));
}
opcionJugador(nJugadores) {
this.scene.start('EscenaJuego', {nJugadores});
}
}
class Escena extends Phaser.Scene {
constructor() {
super({key: 'EscenaJuego'});
}
init(data){
this.n_jugadores = data.nJugadores;
}
Cargar música
this.load.audio('musica', '../img/Loyalty_Freak_Music_-_13_-_Ghost_Surf_Rock.mp3');
const musica = this.sound.add('musica');
musica.play({
volume: 1
})