Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.
Cargamos el escenario usando Tiled
preload() {
this.load.tilemapTiledJSON('level1', '../img/map.json');
this.load.image('nombreDelTilesetEnPhaser', '../img/tiles-galactico.jpg');
}
create() {
const map = this.make.tilemap({key: 'level1'});
const tileset = map.addTilesetImage('nombreDelTilesetEnTiled', 'nombreDelTilesetEnPhaser');
this.backgroundLayer = map.createDynamicLayer('backgroundLayer', tileset, 0, 0);
}
Cargamos los 4 players
this.load.spritesheet('player0', '../img/player0.png', {frameWidth: 32, frameHeight: 32});
this.load.spritesheet('player1', '../img/player1.png', {frameWidth: 32, frameHeight: 32});
this.load.spritesheet('player2', '../img/player2.png', {frameWidth: 32, frameHeight: 32});
this.load.spritesheet('player3', '../img/player3.png', {frameWidth: 32, frameHeight: 32});
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.physics.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}`);
}
}
Mover los coches hacia delante
this.players[i].velocidad = 0;
update(){
for (let i = 0; i < this.n_jugadores; i++) {
const player = this.players[i];
if (player.velocidad <= 200) {
player.velocidad += 7;
}
player.body.setAcceleration(
player.velocidad * Math.cos(Phaser.Math.DegToRad(player.angle - 180)),
player.velocidad * Math.sin(Phaser.Math.DegToRad(player.angle - 180))
);
}
}
Rotar player
this.cursors = this.input.keyboard.createCursorKeys();
update(){
...
if (this.cursors.left.isDown) player.rotation -= 0.05;
else if (this.cursors.right.isDown) player.rotation += 0.05;
}
Controles visuales
this.load.image('leftbtn', '../img/flecha.png');
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() {
this.playersGroup = this.physics.add.group();
for (let i = 0; i < this.n_jugadores; i++) {
this.players[i] = this.playersGroup.create(this.coordenadasPlayers[i].x, this.coordenadasPlayers[i].y, `car${i}`);
...
}
this.physics.add.collider(this.playersGroup, this.playersGroup );
this.physics.add.collider(this.playersGroup, this.backgroundLayer);
}
controlesVisuales(n) {
this.players[n].setData('direccionHorizontal', 0);
const leftbtn = this.add.sprite(this.coordenadasPlayers[n].leftbtn.x, this.coordenadasPlayers[n].leftbtn.y, 'leftbtn').setInteractive();
leftbtn.angle = this.coordenadasPlayers[n].leftbtn.rotacion;
const rightbtn = this.add.sprite(this.coordenadasPlayers[n].rightbtn.x, this.coordenadasPlayers[n].rightbtn.y, 'leftbtn').setInteractive();
rightbtn.angle = this.coordenadasPlayers[n].leftbtn.rotacion;
rightbtn.flipX = true;
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++) {
const player = this.players[i];
...
if (this.cursors.left.isDown || this.players[i].getData('direccionHorizontal') === -1)
player.rotation -=0.05;
else if (this.cursors.right.isDown || this.players[i].getData('direccionHorizontal') === 1)
player.rotation +=0.05;
}
}
Colisión con las paredes
this.backgroundLayer.setCollisionBetween(5, 11);
this.backgroundLayer.setCollisionBetween(16, 21);
this.backgroundLayer.setCollisionBetween(27, 32);
this.backgroundLayer.setCollisionBetween(38, 88);
creaPlayers() {
this.playersGroup = this.physics.add.group();
for (let i = 0; i < this.n_jugadores; i++) {
this.players[i] = this.playersGroup.create(this.coordenadasPlayers[i].x, this.coordenadasPlayers[i].y, `car${i}`);
...
this.physics.add.collider(this.playersGroup, this.playersGroup );
this.physics.add.collider(this.playersGroup, this.backgroundLayer);
}
}
Marcadores
pintarMarcador() {
this.add.text(200, 275, 'P1:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.add.text(280, 275, 'P2:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.add.text(200, 315, 'P3:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.add.text(280, 315, 'P4:', {fontFamily: 'font1', fontSize: 24, color: '#00ff00'});
this.marcadorCoche0 = this.add.text(240, 275, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
this.marcadorCoche1 = this.add.text(320, 275, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
this.marcadorCoche2 = this.add.text(240, 315, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
this.marcadorCoche3 = this.add.text(320, 315, '0', {fontFamily: 'font1', fontSize: 24, color: '#ffffff'});
}
Detectar vueltas colocando una marca en el suelo
La posición y tamaño de esta marca habrá sido definida con Tiled.
create(){
...
this.pintarMeta(map, this.playersGroup);
}
creaPlayers() {
...
for (let i = 0; i < this.n_jugadores; i++) {
...
this.players[i].numero = i;
this.players[i].marcador = 0;
...
pintarMeta(map, coches){
const metaIN = this.findObjectsByType('meta', map, 'metas')[0];
const metaObjIN = this.add.zone(metaIN.x, metaIN.y + 32, metaIN.width, metaIN.height).setOrigin(0, 0);
this.physics.world.enable(metaObjIN);
this.physics.add.overlap(coches, metaObjIN, this.entraArea, null, this);
}
findObjectsByType(type, tilemap, layer) {
const result = [];
tilemap.objects.forEach(function (element) {
if (element.name === layer) {
element.objects.forEach(function (element2) {
if (element2.type === type) {
element2.y -= tilemap.tileHeight;
result.push(element2);
}
});
}
});
return result;
}
entraArea(objectZone1, objectCar) {
objectCar.marcador++;
this['marcadorCoche' + objectCar.numero].setText(objectCar.marcador);
}
Evitar que el jugador haga trampas
create(){
...
this.createMarkers();
}
createMarkers (){
this.markers = this.physics.add.staticGroup();
this.markers.create(128, 460, '__DEFAULT').setSize(128, 8).setData('id', 0).setData('direction', Phaser.UP);
this.markers.create(128, 200, '__DEFAULT').setSize(128, 8).setData('id', 1).setData('direction', Phaser.UP);
this.markers.create(800, 64, '__DEFAULT').setSize(8, 64).setData('id', 2).setData('direction', Phaser.RIGHT);
this.markers.create(900, 360, '__DEFAULT').setSize(96, 8).setData('id', 3).setData('direction', Phaser.DOWN);
this.markers.create(416, 32*14, '__DEFAULT').setSize(8, 96).setData('id', 4).setData('direction', Phaser.LEFT);
this.physics.add.overlap(this.playersGroup, this.markers, this.hitMarker, null, this);
}
hitMarker (player, marker) {
let id = marker.getData('id');
let nextMarker = player.getData('nextMarker');
/*Si la id del marker coincide con el siguiente marker que debe atravesar el usuario...*/
if (id === nextMarker) {
player.setData('nextMarker', id + 1);
}
}
entraArea(objectZone1, objectCar) {
let nextMarker = objectCar.getData('nextMarker');
if (nextMarker === this.markers.getChildren().length){
objectCar.marcador++;
this['marcadorCoche' + objectCar.numero].setText(objectCar.marcador)
objectCar.setData('nextMarker', 0);
}
}
creaPlayers() {
...
for (let i = 0; i < this.n_jugadores; i++) {
this.players[i] = this.playersGroup.create(this.coordenadasPlayers[i].x, this.coordenadasPlayers[i].y, `car${i}`);
this.players[i].setData('nextMarker', 0);
Contar correctamente las vueltas
entraArea(objectZone1, objectCar) {
let nextMarker = objectCar.getData('nextMarker');
if (nextMarker === this.markers.getChildren().length){
objectCar.marcador++;
if(objectCar.marcador ==3){
alert('3 vueltas completadas!');
}
this['marcadorCoche' + objectCar.numero].setText(objectCar.marcador)
objectCar.setData('nextMarker', 0);
}
}
Escena final
class GanarEscena extends Phaser.Scene {
constructor() {
super({key:'ganarScene'});
}
preload() {
this.load.image(‘fin’, '../img/ganar-juego.jpg');
}
create() {
this.add.image(480, 320, 'fin');
this.input.keyboard.on('keydown', event => {
if (event.keyCode === 32) {
this.scene.volverAJugar();
}
});
this.input.on('pointerdown', () => this.volverAJugar())
}
volverAJugar() {
this.scene.start('Escena');
}
}