De todo un poco
This commit is contained in:
parent
3444bc59ed
commit
68177c2ffa
Binary file not shown.
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 197 KiB |
|
|
@ -10,17 +10,24 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="sub-container">
|
||||
<canvas id="mapa" tabindex="0"></canvas>
|
||||
<div class="parent">
|
||||
<div class="div1">
|
||||
<div class="logo" style="width: fit-content;">
|
||||
<h1 style="font-size: 5rem;display: inline;">BattleShip</h1>
|
||||
<i style="font-size: 2rem;" class="ti ti-medal-2"></i>
|
||||
<i style="font-size: 2rem;" class="ti ti-medal-2"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sub-container">
|
||||
<canvas id="minimapa" tabindex="1"></canvas>
|
||||
<textarea id="chat" readonly>Battleship</textarea>
|
||||
<input type="text" name="" id="">
|
||||
<div class="div2"> <canvas id="mapa" tabindex="-1"></canvas></div>
|
||||
<div class="div3"> <canvas id="minimapa" tabindex="-1"></canvas></div>
|
||||
<div class="div4" tabindex="-1"> </div>
|
||||
<div class="div5" tabindex="-1">
|
||||
<div id="logchat"> </div>
|
||||
<input id="chatinput" type="text">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="socket.io/socket.io.js"></script>
|
||||
<script type="module" src="./js_game/battleship.js"></script>
|
||||
|
||||
</html>
|
||||
63
public/js_game/barco.js
Normal file
63
public/js_game/barco.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
export const BarcoTipo = Object.freeze({
|
||||
FRAGATA: 1,
|
||||
DESTRUCTOR: 2,
|
||||
ACORAZADO: 3,
|
||||
PORTAAVIONES: 4,
|
||||
});
|
||||
|
||||
class Barco {
|
||||
constructor(x, y, longitud, orientacion, barcoImg, tipoNave) {
|
||||
this.barcoImg = barcoImg;
|
||||
this.tipoNave = tipoNave;
|
||||
this.xIni = this.x = x;
|
||||
this.yIni = this.y = y;
|
||||
this.longitud = longitud;
|
||||
this.orientacionIni = this.orientacion = orientacion;
|
||||
this.seleccionado = false;
|
||||
this.posIncorrecta = true;
|
||||
}
|
||||
clickado(clickX, clickY) {
|
||||
if (this.orientacion === 'VERTICAL') {
|
||||
return (
|
||||
clickX === this.x && clickY >= this.y && clickY < this.y + this.longitud
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
clickY === this.y && clickX >= this.x && clickX < this.x + this.longitud
|
||||
);
|
||||
}
|
||||
}
|
||||
saveIniPos() {
|
||||
this.orientacionIni = this.orientacion;
|
||||
this.xIni = this.x;
|
||||
this.yIni = this.y;
|
||||
}
|
||||
restoreIniPos() {
|
||||
this.orientacion = this.orientacionIni;
|
||||
this.x = this.xIni;
|
||||
this.y = this.yIni;
|
||||
}
|
||||
setXY(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
giraBarco() {
|
||||
this.orientacion === 'VERTICAL'
|
||||
? (this.orientacion = 'HORIZONTAL')
|
||||
: (this.orientacion = 'VERTICAL');
|
||||
}
|
||||
draw(ctx) {
|
||||
this.orientacion === 'VERTICAL'
|
||||
? ctx.drawImage(this.barcoImg[0], this.x * 64, this.y * 64)
|
||||
: ctx.drawImage(this.barcoImg[1], this.x * 64, this.y * 64);
|
||||
if (this.seleccionado) {
|
||||
ctx.fillStyle = this.posIncorrecta
|
||||
? 'rgba(255, 0, 0, 0.2)'
|
||||
: 'rgba(187, 187, 0, 0.2)';
|
||||
this.orientacion === 'VERTICAL'
|
||||
? ctx.fillRect(this.x * 64, this.y * 64, 64, 64 * this.longitud)
|
||||
: ctx.fillRect(this.x * 64, this.y * 64, 64 * this.longitud, 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
export default Barco;
|
||||
|
|
@ -1,6 +1,178 @@
|
|||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const gameId = urlParams.get('game_id');
|
||||
const userId = localStorage.getItem('userId');
|
||||
import { TableroEditor, TableroVisor } from './tablero.js';
|
||||
const barcosImg = new Image();
|
||||
barcosImg.src = '/assets/barcos.png';
|
||||
|
||||
const socket = io('/batalla', { closeOnBeforeunload: true, auth: { userId, gameId } });
|
||||
barcosImg.onload = function () {
|
||||
iniciaJuego();
|
||||
};
|
||||
|
||||
function getSprites(spriteSheet) {
|
||||
const sprites = {
|
||||
PORTAAVIONES: [
|
||||
{ x: 0, y: 0, width: 64, height: 256 },
|
||||
{ x: 64, y: 192, width: 256, height: 64 },
|
||||
],
|
||||
ACORAZADO: [
|
||||
{ x: 64, y: 0, width: 64, height: 192 },
|
||||
{ x: 128, y: 128, width: 192, height: 64 },
|
||||
],
|
||||
DESTRUCTOR: [
|
||||
{ x: 128, y: 0, width: 64, height: 128 },
|
||||
{ x: 192, y: 64, width: 128, height: 64 },
|
||||
],
|
||||
FRAGATA: [
|
||||
{ x: 192, y: 0, width: 64, height: 64 },
|
||||
{ x: 256, y: 0, width: 64, height: 64 },
|
||||
],
|
||||
|
||||
OCEANO: [
|
||||
{ x: 320, y: 0, width: 32, height: 32 },
|
||||
{ x: 384, y: 0, width: 32, height: 32 },
|
||||
{ x: 416, y: 0, width: 32, height: 32 },
|
||||
{ x: 320, y: 32, width: 32, height: 32 },
|
||||
{ x: 352, y: 64, width: 32, height: 32 },
|
||||
{ x: 416, y: 64, width: 32, height: 32 },
|
||||
{ x: 320, y: 96, width: 32, height: 32 },
|
||||
{ x: 352, y: 96, width: 32, height: 32 },
|
||||
{ x: 416, y: 96, width: 32, height: 32 },
|
||||
|
||||
{ x: 448, y: 0, width: 32, height: 32 },
|
||||
{ x: 512, y: 0, width: 32, height: 32 },
|
||||
{ x: 544, y: 0, width: 32, height: 32 },
|
||||
{ x: 448, y: 32, width: 32, height: 32 },
|
||||
{ x: 480, y: 64, width: 32, height: 32 },
|
||||
{ x: 544, y: 64, width: 32, height: 32 },
|
||||
{ x: 448, y: 96, width: 32, height: 32 },
|
||||
{ x: 480, y: 96, width: 32, height: 32 },
|
||||
{ x: 544, y: 96, width: 32, height: 32 },
|
||||
|
||||
{ x: 576, y: 0, width: 32, height: 32 },
|
||||
{ x: 640, y: 0, width: 32, height: 32 },
|
||||
{ x: 672, y: 0, width: 32, height: 32 },
|
||||
{ x: 576, y: 32, width: 32, height: 32 },
|
||||
{ x: 608, y: 64, width: 32, height: 32 },
|
||||
{ x: 672, y: 64, width: 32, height: 32 },
|
||||
{ x: 576, y: 96, width: 32, height: 32 },
|
||||
{ x: 608, y: 96, width: 32, height: 32 },
|
||||
{ x: 672, y: 96, width: 32, height: 32 },
|
||||
],
|
||||
};
|
||||
|
||||
const spritesObj = {};
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
for (const key in sprites) {
|
||||
if (Object.hasOwnProperty.call(sprites, key)) {
|
||||
const spriteArray = sprites[key];
|
||||
spritesObj[key] = spriteArray.map((sprite) => {
|
||||
canvas.width = sprite.width;
|
||||
canvas.height = sprite.height;
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(
|
||||
spriteSheet,
|
||||
sprite.x,
|
||||
sprite.y,
|
||||
sprite.width,
|
||||
sprite.height,
|
||||
0,
|
||||
0,
|
||||
sprite.width,
|
||||
sprite.height,
|
||||
);
|
||||
const spriteImage = new Image();
|
||||
spriteImage.src = canvas.toDataURL();
|
||||
return spriteImage;
|
||||
});
|
||||
}
|
||||
}
|
||||
return spritesObj;
|
||||
}
|
||||
|
||||
function iniciaJuego() {
|
||||
const canvasMapa = document.getElementById('mapa');
|
||||
const canvasMiniMapa = document.getElementById('minimapa');
|
||||
const sprites = getSprites(barcosImg);
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const gameId = urlParams.get('game_id');
|
||||
const userId = localStorage.getItem('userId');
|
||||
|
||||
const socket = io('/batalla', {
|
||||
closeOnBeforeunload: true,
|
||||
auth: { userId, gameId },
|
||||
});
|
||||
|
||||
let tablero = null;
|
||||
|
||||
const OnChangeState = (snapshotJugador) => {
|
||||
switch (snapshotJugador.estado) {
|
||||
case 'ENPREPARACION':
|
||||
ENPREPARACION(snapshotJugador);
|
||||
break;
|
||||
case 'ENCURSO':
|
||||
ENCURSO(snapshotJugador);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handlers = {
|
||||
connect: () => {
|
||||
gameLoop();
|
||||
},
|
||||
disconnect: () => {
|
||||
window.close();
|
||||
},
|
||||
|
||||
OnChangeState,
|
||||
};
|
||||
|
||||
Object.entries(handlers).forEach(([event, handler]) => {
|
||||
socket.on(event, handler);
|
||||
});
|
||||
|
||||
const ENPREPARACION = (snapshotJugador) => {
|
||||
muestraBoton('Fijar Flota',()=>{
|
||||
console.log(JSON.stringify(tablero.mapaFlota.barcos));
|
||||
socket.emit('sendFlota', tablero.mapaFlota.barcos,handlers.OnChangeState);
|
||||
});
|
||||
addMsgChat('Situa tu flota en el mapa y pulsa el boton para continuar');
|
||||
tablero = new TableroEditor(canvasMapa, canvasMiniMapa, sprites, [
|
||||
snapshotJugador.mapaFlota,
|
||||
snapshotJugador.mapaDeAtaques,
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function addMsgChat(msg) {
|
||||
const divChat = document.querySelector('#logchat');
|
||||
const pMsg = document.createElement('p');
|
||||
pMsg.textContent = msg;
|
||||
divChat.appendChild(pMsg);
|
||||
divChat.scrollTop = divChat.scrollHeight;
|
||||
}
|
||||
function muestraBoton(msg, callback) {
|
||||
const divContent = document.querySelector('.div4');
|
||||
divContent.innerHTML = `<button class="button button-orange prepasradoBtn"> --${msg}-- </button>`;
|
||||
const preparadoBtn = divContent.querySelector('.prepasradoBtn');
|
||||
preparadoBtn.addEventListener('click', callback);
|
||||
}
|
||||
function muestraAviso(msg) {
|
||||
const divContent = document.querySelector('.div4');
|
||||
divContent.innerHTML = `<span class="avisoMsg parpadea"> -- ${msg} -- </span>`;
|
||||
}
|
||||
function limpiaContenedorAvisos() {
|
||||
const divContent = document.querySelector('.div4');
|
||||
divContent.innerHTML = '';
|
||||
}
|
||||
|
||||
function gameLoop() {
|
||||
if (tablero) tablero.draw();
|
||||
window.requestAnimationFrame(gameLoop);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
266
public/js_game/mapa.js
Normal file
266
public/js_game/mapa.js
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
import Barco from './barco.js';
|
||||
import Oceano from './oceano.js';
|
||||
|
||||
class MapaBase {
|
||||
constructor(canvas, size, scale, sprites) {
|
||||
this.canvas = canvas;
|
||||
this.canvas.width = size;
|
||||
this.canvas.height = size;
|
||||
this.width = size / scale;
|
||||
this.height = size / scale;
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
this.scale = scale;
|
||||
this.ctx.scale(this.scale, this.scale);
|
||||
this.sprites = sprites;
|
||||
this.oceano = new Oceano(this.width, this.height, 32, sprites['OCEANO']);
|
||||
this.casillaSize = 64;
|
||||
this.numFilas = 10;
|
||||
this.numColumnas = 10;
|
||||
}
|
||||
draw() {
|
||||
this.ctx.clearRect(0, 0, this.width, this.height);
|
||||
this.oceano.draw(this.ctx);
|
||||
}
|
||||
}
|
||||
class MapaVisor extends MapaBase {
|
||||
celdas = [];
|
||||
barcos = [];
|
||||
constructor(canvas, size, scale, sprites, barcos, celdas) {
|
||||
super(canvas, size, scale, sprites);
|
||||
this.celdas = celdas;
|
||||
//this.inicializarCeldas();
|
||||
|
||||
this.setBarcos(barcos);
|
||||
}
|
||||
inicializarCeldas() {
|
||||
for (let i = 0; i < this.numFilas; i++) {
|
||||
this.celdas[i] = new Array(this.numColumnas).fill(0);
|
||||
}
|
||||
}
|
||||
|
||||
setBarcos(barcos) {
|
||||
const barcosArray = Array.isArray(barcos) ? barcos : [barcos];
|
||||
for (const barco of barcosArray) {
|
||||
this.barcos.push(
|
||||
new Barco(
|
||||
barco.x,
|
||||
barco.y,
|
||||
barco.longitud,
|
||||
barco.orientacion,
|
||||
this.sprites[barco.tipoNave],
|
||||
barco.tipoNave,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
draw() {
|
||||
super.draw();
|
||||
this.barcos.forEach((barco) => {
|
||||
barco.draw(this.ctx);
|
||||
});
|
||||
this.ctx.beginPath();
|
||||
for (let i = 1; i < this.numFilas; i++) {
|
||||
const y = i * this.casillaSize;
|
||||
this.ctx.moveTo(5, y);
|
||||
this.ctx.lineTo(this.casillaSize * this.numColumnas - 5, y);
|
||||
}
|
||||
for (let i = 1; i < this.numColumnas; i++) {
|
||||
const x = i * this.casillaSize;
|
||||
this.ctx.moveTo(x, 5);
|
||||
this.ctx.lineTo(x, this.casillaSize * this.numFilas - 5);
|
||||
}
|
||||
|
||||
this.ctx.strokeStyle = 'rgba(0, 255, 0, 0.6)';
|
||||
this.ctx.stroke();
|
||||
|
||||
this.ctx.fillStyle = 'red';
|
||||
this.ctx.font = 'bold 24px Arial';
|
||||
for (let fila = 0; fila < this.numFilas; fila++) {
|
||||
for (let columna = 0; columna < this.numColumnas; columna++) {
|
||||
const valor = this.celdas[fila][columna];
|
||||
const posX = columna * this.casillaSize + this.casillaSize / 2.3;
|
||||
const posY = fila * this.casillaSize + this.casillaSize / 1.5;
|
||||
this.ctx.fillText(valor, posX, posY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MapaAtaque extends MapaVisor {
|
||||
constructor(canvas, size, scale, sprites, barcos, celdas) {
|
||||
super(canvas, size, scale, sprites, barcos, celdas);
|
||||
canvas.addEventListener('click', this.getPosClick);
|
||||
}
|
||||
|
||||
calcularCoordenadas(event) {
|
||||
const rect = this.canvas.getBoundingClientRect();
|
||||
const x = Math.floor(
|
||||
(event.clientX - rect.left) / (this.casillaSize * this.scale),
|
||||
);
|
||||
const y = Math.floor(
|
||||
(event.clientY - rect.top) / (this.casillaSize * this.scale),
|
||||
);
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
getPosClick = (event) => {
|
||||
const { x, y } = this.calcularCoordenadas(event);
|
||||
console.log(x, y);
|
||||
};
|
||||
|
||||
draw() {
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
class MapaEditor extends MapaVisor {
|
||||
barcoSeleccionado;
|
||||
constructor(canvas, size, scale, sprites, barcos, celdas) {
|
||||
super(canvas, size, scale, sprites, barcos, celdas);
|
||||
canvas.addEventListener('click', this.getPosClick);
|
||||
canvas.addEventListener('contextmenu', this.giraBarcoSeleccionado);
|
||||
canvas.addEventListener('mousemove', this.mueveBarcoSeleccionado);
|
||||
document.addEventListener('keydown', this.handleKeyDown);
|
||||
}
|
||||
fijaBarco(barco) {
|
||||
barco.seleccionado = false;
|
||||
const incFila = barco.orientacion === 'VERTICAL' ? 1 : 0;
|
||||
const incColumna = barco.orientacion === 'HORIZONTAL' ? 1 : 0;
|
||||
for (let i = 0; i < barco.longitud; i++) {
|
||||
const fila = barco.y + i * incFila;
|
||||
const columna = barco.x + i * incColumna;
|
||||
this.celdas[fila][columna] = barco.longitud;
|
||||
}
|
||||
this.barcos.push(barco);
|
||||
}
|
||||
calcularCoordenadas(event) {
|
||||
const rect = this.canvas.getBoundingClientRect();
|
||||
const x = Math.floor(
|
||||
(event.clientX - rect.left) / (this.casillaSize * this.scale),
|
||||
);
|
||||
const y = Math.floor(
|
||||
(event.clientY - rect.top) / (this.casillaSize * this.scale),
|
||||
);
|
||||
return { x, y };
|
||||
}
|
||||
//Acuerdate!!!! funcion de flecha en los callBack para no tener problemas con el contexto this
|
||||
handleKeyDown = (event) => {
|
||||
const canvasFocused = document.activeElement === this.canvas;
|
||||
if (canvasFocused && event.key === 'Escape' && this.barcoSeleccionado) {
|
||||
this.barcoSeleccionado.restoreIniPos();
|
||||
this.posicionaBarcoSeleccionado();
|
||||
}
|
||||
};
|
||||
//Acuerdate!!!! funcion de flecha en los callBack para no tener problemas con el contexto this
|
||||
giraBarcoSeleccionado = (event) => {
|
||||
event.preventDefault();
|
||||
if (this.barcoSeleccionado) {
|
||||
if (
|
||||
this.barcoSeleccionado.x + this.barcoSeleccionado.longitud <=
|
||||
this.numColumnas &&
|
||||
this.barcoSeleccionado.y + this.barcoSeleccionado.longitud <=
|
||||
this.numFilas
|
||||
) {
|
||||
this.barcoSeleccionado.giraBarco();
|
||||
this.barcoSeleccionado.posIncorrecta = this.sePuedeColocar();
|
||||
}
|
||||
}
|
||||
};
|
||||
//Acuerdate!!!! funcion de flecha en los callBack para no tener problemas con el contexto this
|
||||
getPosClick = (event) => {
|
||||
const { x, y } = this.calcularCoordenadas(event);
|
||||
if (!this.barcoSeleccionado) {
|
||||
const index = this.barcos.findIndex((barco) => barco.clickado(x, y));
|
||||
if (index != -1) this.seleccionaBarco(index);
|
||||
} else {
|
||||
this.posicionaBarcoSeleccionado();
|
||||
}
|
||||
};
|
||||
seleccionaBarco(index_barco) {
|
||||
this.barcoSeleccionado = this.barcos[index_barco];
|
||||
this.barcoSeleccionado.seleccionado = true;
|
||||
this.barcoSeleccionado.saveIniPos();
|
||||
this.barcos.splice(index_barco, 1);
|
||||
const incFila = this.barcoSeleccionado.orientacion === 'VERTICAL' ? 1 : 0;
|
||||
const incColumna =
|
||||
this.barcoSeleccionado.orientacion === 'HORIZONTAL' ? 1 : 0;
|
||||
for (let i = 0; i < this.barcoSeleccionado.longitud; i++) {
|
||||
const fila = this.barcoSeleccionado.y + i * incFila;
|
||||
const columna = this.barcoSeleccionado.x + i * incColumna;
|
||||
this.celdas[fila][columna] = 0;
|
||||
}
|
||||
}
|
||||
//Acuerdate!!!! funcion de flecha en los callBack para no tener problemas con el contexto this
|
||||
mueveBarcoSeleccionado = (event) => {
|
||||
if (this.barcoSeleccionado) {
|
||||
const { x, y } = this.calcularCoordenadas(event);
|
||||
if (!this.colisionBorde(x, y)) this.barcoSeleccionado.setXY(x, y);
|
||||
this.barcoSeleccionado.posIncorrecta = this.sePuedeColocar();
|
||||
}
|
||||
};
|
||||
posicionaBarcoSeleccionado() {
|
||||
if (!this.barcoSeleccionado.posIncorrecta) {
|
||||
this.fijaBarco(this.barcoSeleccionado);
|
||||
this.barcoSeleccionado = null;
|
||||
}
|
||||
}
|
||||
colisionBorde(x, y) {
|
||||
const barco = this.barcoSeleccionado;
|
||||
const longitud = barco.longitud;
|
||||
const orientacion = barco.orientacion;
|
||||
return orientacion === 'VERTICAL'
|
||||
? x < 0 || x >= this.numColumnas || y < 0 || y + longitud > this.numFilas
|
||||
: x < 0 || x + longitud > this.numColumnas || y < 0 || y > this.numFilas;
|
||||
}
|
||||
sePuedeColocar() {
|
||||
const x = this.barcoSeleccionado.x;
|
||||
const y = this.barcoSeleccionado.y;
|
||||
const longitud = this.barcoSeleccionado.longitud;
|
||||
const orientacion = this.barcoSeleccionado.orientacion;
|
||||
let suma = 0;
|
||||
if (orientacion === 'VERTICAL') {
|
||||
for (let f = -1; f <= longitud; f++) {
|
||||
for (let c = -1; c < 2; c++) {
|
||||
const fila = y + f;
|
||||
const columna = x + c;
|
||||
if (
|
||||
fila >= 0 &&
|
||||
fila < this.celdas.length &&
|
||||
columna >= 0 &&
|
||||
columna < this.celdas[0].length
|
||||
) {
|
||||
suma += this.celdas[fila][columna];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let f = -1; f < 2; f++) {
|
||||
for (let c = -1; c <= longitud; c++) {
|
||||
const fila = y + f;
|
||||
const columna = x + c;
|
||||
if (
|
||||
fila >= 0 &&
|
||||
fila < this.celdas.length &&
|
||||
columna >= 0 &&
|
||||
columna < this.celdas[0].length
|
||||
) {
|
||||
suma += this.celdas[fila][columna];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return suma;
|
||||
}
|
||||
|
||||
esFlotaValida() {
|
||||
return true;
|
||||
}
|
||||
|
||||
draw() {
|
||||
super.draw();
|
||||
if (this.barcoSeleccionado) this.barcoSeleccionado.draw(this.ctx);
|
||||
}
|
||||
}
|
||||
|
||||
export { MapaBase, MapaVisor, MapaAtaque, MapaEditor };
|
||||
52
public/js_game/oceano.js
Normal file
52
public/js_game/oceano.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
class Oceano {
|
||||
constructor(width, height, celdaSize, sprites) {
|
||||
this.sprites = sprites;
|
||||
this.celdaSize = celdaSize;
|
||||
this.filas = Math.floor(height / celdaSize);
|
||||
this.columnas = Math.floor(width / celdaSize);
|
||||
this.nFramesAnim = 3;
|
||||
this.animFrame = 0;
|
||||
this.gameFrame = 0;
|
||||
|
||||
this.lastColumnIndex = this.columnas - 1;
|
||||
this.lastRowIndex = this.filas - 1;
|
||||
this.lastColumnX = this.lastColumnIndex * this.celdaSize;
|
||||
this.lastRowY = this.lastRowIndex * this.celdaSize;
|
||||
}
|
||||
|
||||
update() {}
|
||||
|
||||
draw(ctx) {
|
||||
this.animFrame = Math.floor(this.gameFrame / 10) % this.nFramesAnim;
|
||||
this.gameFrame++;
|
||||
const frame = this.animFrame * 9;
|
||||
|
||||
// Dibujar los bordes superior e inferior
|
||||
ctx.drawImage(this.sprites[0 + frame], 0, 0);
|
||||
ctx.drawImage(this.sprites[2 + frame], this.lastColumnX, 0);
|
||||
ctx.drawImage(this.sprites[6 + frame], 0, this.lastRowY);
|
||||
ctx.drawImage(this.sprites[8 + frame], this.lastColumnX, this.lastRowY);
|
||||
|
||||
// Dibujar los bordes laterales
|
||||
for (let y = 1; y < this.lastRowIndex; y++) {
|
||||
ctx.drawImage(this.sprites[3 + frame], 0, y * this.celdaSize);
|
||||
ctx.drawImage(
|
||||
this.sprites[5 + frame],
|
||||
this.lastColumnX,
|
||||
y * this.celdaSize
|
||||
);
|
||||
}
|
||||
for (let x = 1; x < this.lastColumnIndex; x++) {
|
||||
ctx.drawImage(this.sprites[1 + frame], x * this.celdaSize, 0);
|
||||
ctx.drawImage(this.sprites[7 + frame], x * this.celdaSize, this.lastRowY);
|
||||
}
|
||||
// Dibujar el contenido interno
|
||||
for (let y = 1; y < this.lastRowIndex; y++) {
|
||||
for (let x = 1; x < this.lastColumnIndex; x++) {
|
||||
ctx.drawImage(this.sprites[4], x * this.celdaSize, y * this.celdaSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Oceano;
|
||||
53
public/js_game/tablero.js
Normal file
53
public/js_game/tablero.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { MapaVisor,MapaEditor, MapaAtaque } from './mapa.js';
|
||||
class TableroBase {
|
||||
constructor(canvasMapa, canvasMiniMapa,sprites){
|
||||
this.canvasMapa = canvasMapa;
|
||||
this.canvasMiniMapa = canvasMiniMapa;
|
||||
this.sprites = sprites;
|
||||
}
|
||||
}
|
||||
class TableroEditor extends TableroBase{
|
||||
constructor(canvasMapa, canvasMiniMapa,sprites, [mapaFlota, mapaAtaques] ){
|
||||
super(canvasMapa, canvasMiniMapa,sprites)
|
||||
const { barcos: barcosMapaFlota, celdas: celdasMapaFlota } = mapaFlota;
|
||||
const { barcos: barcosMapaAtaques, celdas: celdasMapaAtaques } = mapaAtaques;
|
||||
this.mapaFlota = new MapaEditor(canvasMapa, 640, 1,sprites,barcosMapaFlota,celdasMapaFlota);
|
||||
this.mapaDeAtaques = new MapaVisor(canvasMiniMapa, 320, 0.5, sprites,barcosMapaAtaques,celdasMapaAtaques);
|
||||
}
|
||||
draw() {
|
||||
this.mapaFlota.draw();
|
||||
this.mapaDeAtaques.draw();
|
||||
}
|
||||
}
|
||||
|
||||
class TableroVisor extends TableroBase{
|
||||
constructor(canvasMapa, canvasMiniMapa,sprites, [mapaFlota, mapaAtaques] ){
|
||||
super(canvasMapa, canvasMiniMapa,sprites)
|
||||
const { barcos: barcosMapaFlota, celdas: celdasMapaFlota } = mapaFlota;
|
||||
const { barcos: barcosMapaAtaques, celdas: celdasMapaAtaques } = mapaAtaques;
|
||||
this.mapaFlota = new MapaVisor(canvasMiniMapa, 320, 0.5,sprites,barcosMapaFlota,celdasMapaFlota);
|
||||
this.mapaDeAtaques = new MapaVisor(canvasMapa, 640, 1, sprites,barcosMapaAtaques,celdasMapaAtaques);
|
||||
}
|
||||
draw() {
|
||||
this.mapaFlota.draw();
|
||||
this.mapaDeAtaques.draw();
|
||||
}
|
||||
}
|
||||
|
||||
class TableroAtaque extends TableroBase{
|
||||
constructor(canvasMapa, canvasMiniMapa,sprites, [mapaFlota, mapaAtaques] ){
|
||||
super(canvasMapa, canvasMiniMapa,sprites)
|
||||
const { barcos: barcosMapaFlota, celdas: celdasMapaFlota } = mapaFlota;
|
||||
const { barcos: barcosMapaAtaques, celdas: celdasMapaAtaques } = mapaAtaques;
|
||||
this.mapaFlota = new MapaVisor(canvasMiniMapa, 320, 0.5,sprites,barcosMapaFlota,celdasMapaFlota);
|
||||
this.mapaDeAtaques = new MapaAtaque(canvasMapa, 640, 1, sprites,barcosMapaAtaques,celdasMapaAtaques);
|
||||
}
|
||||
draw() {
|
||||
this.mapaFlota.draw();
|
||||
this.mapaDeAtaques.draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export {TableroBase,TableroEditor,TableroVisor}
|
||||
|
|
@ -4,10 +4,14 @@
|
|||
}
|
||||
|
||||
* {
|
||||
/* box-sizing: content-box; */
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
}
|
||||
h1,h2,h3,h4 {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
|
@ -20,96 +24,165 @@ body {
|
|||
}
|
||||
|
||||
body {
|
||||
padding: 1rem;
|
||||
background: linear-gradient(to bottom right, #0f2027, #203a43, #2c5364);
|
||||
color: white;
|
||||
font-family: 'ITC Machine Std Bold', sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#container {
|
||||
height: 100%;
|
||||
color: #bf360c;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
#sub-container {
|
||||
height: 648px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 4px solid #2c5364;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#input-container {
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
gap: 0.4rem;
|
||||
max-width: fit-content;
|
||||
flex-direction: column;
|
||||
border: 4px solid #2c5364;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Estilo del botón */
|
||||
#input-container input[type="button"] {
|
||||
/* Estilo base para los botones */
|
||||
.button {
|
||||
width: 100%;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 1rem;
|
||||
font-family: 'ITC Machine Std Bold', sans-serif;
|
||||
font-size: 2rem;
|
||||
border: none;
|
||||
border-radius: 0.4rem;
|
||||
background-color: #ff5722; /* Color de fondo naranja */
|
||||
color: white; /* Color del texto blanco */
|
||||
cursor: pointer; /* Cambia el cursor al pasar sobre el botón */
|
||||
transition: background-color 0.3s ease; /* Transición suave al cambiar de color */
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
/* Estilo del botón al pasar el cursor */
|
||||
#input-container input[type="button"]:hover {
|
||||
background-color: #e64a19; /* Color de fondo naranja más oscuro al pasar el cursor */
|
||||
/* Estilo para el botón naranja */
|
||||
.button-orange {
|
||||
background-color: #ff5722;
|
||||
}
|
||||
|
||||
/* Estilo del botón al hacer clic */
|
||||
#input-container input[type="button"]:active {
|
||||
background-color: #bf360c; /* Color de fondo naranja más oscuro al hacer clic */
|
||||
/* Estilo para el botón naranja claro al pasar el cursor */
|
||||
.button-orange:hover {
|
||||
background-color: #e64a19;
|
||||
}
|
||||
|
||||
/* Estilo para el botón naranja oscuro al hacer clic */
|
||||
.button-orange:active {
|
||||
background-color: #bf360c;
|
||||
}
|
||||
|
||||
.avisoMsg {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.parpadea {
|
||||
animation-name: parpadeo;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
-webkit-animation-name: parpadeo;
|
||||
-webkit-animation-duration: 2s;
|
||||
-webkit-animation-timing-function: linear;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.parent {
|
||||
height: 744px;
|
||||
display: grid;
|
||||
grid-template-columns: min-content min-content;
|
||||
grid-template-rows: auto 328px 55px auto;
|
||||
grid-column-gap: 4px;
|
||||
}
|
||||
.div1 {
|
||||
grid-area: 1 / 1 / 2 / 3;
|
||||
}
|
||||
.div2 {
|
||||
grid-area: 2 / 1 / 5 / 2;
|
||||
width: 648px;
|
||||
height: 648px;
|
||||
border: 4px solid #2c5364;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.div3 {
|
||||
grid-area: 2 / 2 / 3 / 3;
|
||||
width: 328px;
|
||||
height: 328px;
|
||||
border: 4px solid #2c5364;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.div4 {
|
||||
grid-area: 3 / 2 / 4 / 3;
|
||||
display: flex;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
.div5 {
|
||||
grid-area: 4 / 2 / 5 / 3;
|
||||
border: 4px solid #2c5364;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
#mapa {
|
||||
width: 640px;
|
||||
height: 640px;
|
||||
background-color: #2c5364;
|
||||
}
|
||||
|
||||
#minimapa {
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
flex-shrink: 0;
|
||||
background-color: #2c5364;
|
||||
}
|
||||
|
||||
#chat {
|
||||
font-family: 'ITC Machine Std Bold', sans-serif;
|
||||
resize: none;
|
||||
width: 320px;
|
||||
#logchat {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0.1rem;
|
||||
padding-right: 0.4rem;
|
||||
font-family: 'roboto', sans-serif;
|
||||
font-size: small;
|
||||
font-weight: bold;
|
||||
border-radius: 0.4rem;
|
||||
background-color: transparent;
|
||||
color: antiquewhite;
|
||||
overflow-y: auto;
|
||||
}
|
||||
#logchat p {
|
||||
margin: 0;
|
||||
}
|
||||
#chatinput {
|
||||
font-family: 'roboto', sans-serif;
|
||||
padding: 0.4rem;
|
||||
font-weight: bold;
|
||||
border-radius: 0 0 0.4rem 0.4rem;
|
||||
background-color: transparent;
|
||||
color: wheat;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.basic-input{
|
||||
font-family: 'ITC Machine Std Bold', sans-serif;
|
||||
padding: 0.4rem;
|
||||
font-size: larger;
|
||||
border-radius: 0.4rem;
|
||||
background-color: #2c5364;
|
||||
color:wheat;
|
||||
outline: none;
|
||||
@-moz-keyframes parpadeo {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@-webkit-keyframes parpadeo {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes parpadeo {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,41 @@
|
|||
import { OnGatewayConnection, OnGatewayDisconnect, WebSocketGateway } from '@nestjs/websockets';
|
||||
import {
|
||||
OnGatewayConnection,
|
||||
OnGatewayDisconnect,
|
||||
SubscribeMessage,
|
||||
WebSocketGateway,
|
||||
} from '@nestjs/websockets';
|
||||
import { BatallaService } from './batalla.service';
|
||||
import { Socket } from 'socket.io';
|
||||
import Barco from 'src/battleship/barco';
|
||||
|
||||
@WebSocketGateway({ namespace: 'batalla' })
|
||||
export class BatallaGateway implements OnGatewayConnection, OnGatewayDisconnect {
|
||||
export class BatallaGateway
|
||||
implements OnGatewayConnection, OnGatewayDisconnect
|
||||
{
|
||||
constructor(private readonly batallaService: BatallaService) {}
|
||||
|
||||
handleConnection(client: Socket) {
|
||||
const {userId,gameId}=client.handshake.auth
|
||||
|
||||
const { userId, gameId } = client.handshake.auth;
|
||||
if (this.batallaService.existePartidaUsuario(gameId,userId)){
|
||||
client.emit('OnChangeState',this.batallaService.getSnapshotJugador(gameId,userId));
|
||||
}else{
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
handleDisconnect(client: Socket) {}
|
||||
|
||||
@SubscribeMessage('sendFlota')
|
||||
handleMsg(client: Socket, barcos:Barco[]) {
|
||||
const { userId, gameId } = client.handshake.auth;
|
||||
console.log(barcos);
|
||||
console.log(barcos[0] instanceof Barco);
|
||||
const snapshotJugador = this.batallaService.getSnapshotJugador(gameId,userId);
|
||||
snapshotJugador.prepararFlota(barcos);
|
||||
}
|
||||
|
||||
|
||||
handleDisconnect(client: Socket) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -5,7 +5,18 @@ import { UsuariosService } from 'src/shared/usuarios.service';
|
|||
@Injectable()
|
||||
export class BatallaService {
|
||||
constructor(
|
||||
private readonly usuariosService: UsuariosService,
|
||||
private readonly partidasService: PartidasService,
|
||||
) {}
|
||||
|
||||
existePartidaUsuario(uuidPartida:string,uuidJugador:string){
|
||||
return this.partidasService.existePartida(uuidPartida,uuidJugador);
|
||||
}
|
||||
|
||||
|
||||
getSnapshotJugador(uuidPartida:string,uuidJugador:string){
|
||||
return this.partidasService.getSnapshotJugador(uuidPartida,uuidJugador);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ export default class Barco {
|
|||
public longitud: number,
|
||||
public orientacion: string,
|
||||
public impactos: number = 0,
|
||||
public destruido = false,
|
||||
public destruido: boolean = false,
|
||||
public tipoNave: string = '',
|
||||
) {}
|
||||
|
||||
recibirImpacto() {
|
||||
|
|
@ -26,4 +27,14 @@ export default class Barco {
|
|||
haSidoDestruido(): boolean {
|
||||
return this.destruido;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
longitud: this.longitud,
|
||||
orientacion: this.orientacion,
|
||||
tipoNave: this.tipoNave,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,55 +1,17 @@
|
|||
import Barco from './barco';
|
||||
import Jugador from './jugador';
|
||||
|
||||
export default class BattleshipGame {
|
||||
public jugadorA: Jugador | null = null;
|
||||
public jugadorB: Jugador | null = null;
|
||||
public jugadorA: Jugador;
|
||||
public jugadorB: Jugador;
|
||||
|
||||
turnoActual: Jugador | null;
|
||||
|
||||
constructor(public idPartida: string) {
|
||||
constructor() {
|
||||
this.turnoActual = null;
|
||||
this.jugadorA=new Jugador();
|
||||
this.jugadorB=new Jugador();
|
||||
this.turnoActual=this.jugadorA;
|
||||
}
|
||||
|
||||
setJugadorA(jugador: Jugador) {
|
||||
this.jugadorA = jugador;
|
||||
}
|
||||
|
||||
setJugadorB(jugador: Jugador) {
|
||||
this.jugadorB = jugador;
|
||||
}
|
||||
|
||||
iniciaPartida() {
|
||||
this.turnoActual = this.jugadorA;
|
||||
// Iniciar el primer turno
|
||||
this.realizarTurno();
|
||||
}
|
||||
realizarTurno() {
|
||||
// Realizar las acciones correspondientes al turno actual
|
||||
// Por ejemplo, mostrar el mapa del turno actual, solicitar un disparo, etc.
|
||||
// Implementa esta parte según sea necesario
|
||||
|
||||
// Luego, alternar el turno al otro jugador
|
||||
this.turnoActual =
|
||||
this.turnoActual === this.jugadorA ? this.jugadorB : this.jugadorA;
|
||||
|
||||
// Verificar si se ha alcanzado el final del juego
|
||||
if (this.haFinalizado()) {
|
||||
this.finalizaPartida();
|
||||
} else {
|
||||
// Si no ha finalizado, continuar con el próximo turno
|
||||
this.realizarTurno();
|
||||
}
|
||||
}
|
||||
haFinalizado(): boolean {
|
||||
// Aquí debes implementar la lógica para verificar si el juego ha finalizado
|
||||
// Por ejemplo, si todos los barcos de uno de los jugadores han sido destruidos
|
||||
// Devuelve true si el juego ha finalizado, de lo contrario, devuelve false
|
||||
// Implementa esta parte según sea necesario
|
||||
return false;
|
||||
}
|
||||
finalizaPartida() {
|
||||
// Aquí debes implementar la lógica para finalizar el juego
|
||||
// Por ejemplo, mostrar el resultado (quién ganó, etc.)
|
||||
// Implementa esta parte según sea necesario
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,35 +5,72 @@ export default class Jugador {
|
|||
public mapaFlota: Mapa = new Mapa();
|
||||
public mapaDeAtaques: Mapa = new Mapa();
|
||||
|
||||
public jugadorPreparado: boolean = false;
|
||||
public estado: string = 'ENPREPARACION';
|
||||
|
||||
public barcos: Barco[] = [
|
||||
new Barco(1, 0, 0, BarcoTipo.PORTAAVIONES, 'VERTICAL'),
|
||||
new Barco(2, 1, 0, BarcoTipo.ACORAZADO, 'VERTICAL'),
|
||||
new Barco(3, 2, 0, BarcoTipo.ACORAZADO, 'VERTICAL'),
|
||||
new Barco(4, 3, 0, BarcoTipo.ACORAZADO, 'VERTICAL'),
|
||||
new Barco(5, 4, 0, BarcoTipo.DESTRUCTOR, 'VERTICAL'),
|
||||
new Barco(6, 5, 0, BarcoTipo.DESTRUCTOR, 'VERTICAL'),
|
||||
new Barco(7, 6, 0, BarcoTipo.DESTRUCTOR, 'VERTICAL'),
|
||||
new Barco(8, 7, 0, BarcoTipo.FRAGATA, 'VERTICAL'),
|
||||
new Barco(9, 8, 0, BarcoTipo.FRAGATA, 'VERTICAL'),
|
||||
new Barco(
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
BarcoTipo.PORTAAVIONES,
|
||||
'VERTICAL',
|
||||
0,
|
||||
false,
|
||||
'PORTAAVIONES',
|
||||
),
|
||||
new Barco(2, 1, 0, BarcoTipo.ACORAZADO, 'VERTICAL', 0, false, 'ACORAZADO'),
|
||||
new Barco(3, 2, 0, BarcoTipo.ACORAZADO, 'VERTICAL', 0, false, 'ACORAZADO'),
|
||||
new Barco(4, 3, 0, BarcoTipo.ACORAZADO, 'VERTICAL', 0, false, 'ACORAZADO'),
|
||||
new Barco(
|
||||
5,
|
||||
4,
|
||||
0,
|
||||
BarcoTipo.DESTRUCTOR,
|
||||
'VERTICAL',
|
||||
0,
|
||||
false,
|
||||
'DESTRUCTOR',
|
||||
),
|
||||
new Barco(
|
||||
6,
|
||||
5,
|
||||
0,
|
||||
BarcoTipo.DESTRUCTOR,
|
||||
'VERTICAL',
|
||||
0,
|
||||
false,
|
||||
'DESTRUCTOR',
|
||||
),
|
||||
new Barco(
|
||||
7,
|
||||
6,
|
||||
0,
|
||||
BarcoTipo.DESTRUCTOR,
|
||||
'VERTICAL',
|
||||
0,
|
||||
false,
|
||||
'DESTRUCTOR',
|
||||
),
|
||||
new Barco(8, 7, 0, BarcoTipo.FRAGATA, 'VERTICAL', 0, false, 'FRAGATA'),
|
||||
new Barco(9, 8, 0, BarcoTipo.FRAGATA, 'VERTICAL', 0, false, 'FRAGATA'),
|
||||
];
|
||||
|
||||
constructor(public nickname: string) {}
|
||||
constructor() {
|
||||
this.mapaFlota.setBarcos(this.barcos);
|
||||
}
|
||||
|
||||
prepararFlota(barcos: Barco[]) {
|
||||
this.barcos = barcos;
|
||||
this.mapaFlota.setBarcos(this.barcos);
|
||||
this.jugadorPreparado = true;
|
||||
}
|
||||
|
||||
setBarcos(barcos: Barco[]) {
|
||||
this.mapaFlota.setBarcos(barcos);
|
||||
}
|
||||
|
||||
realizarDisparo(x: number, y: number, rival: Jugador): boolean {
|
||||
const acierto = rival.mapaFlota.verificaDisparo(x, y);
|
||||
this.mapaDeAtaques.marcaDisparo(x,y,acierto ? EstadoCelda.Golpe : EstadoCelda.Agua);
|
||||
this.mapaDeAtaques.marcaDisparo(
|
||||
x,
|
||||
y,
|
||||
acierto ? EstadoCelda.Golpe : EstadoCelda.Agua,
|
||||
);
|
||||
return acierto;
|
||||
}
|
||||
|
||||
|
|
@ -46,4 +83,11 @@ export default class Jugador {
|
|||
return true;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
mapaFlota: this.mapaFlota,
|
||||
mapaDeAtaques: this.mapaDeAtaques,
|
||||
estado: this.estado,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,14 @@ export enum EstadoCelda {
|
|||
Agua = -1,
|
||||
Golpe = -2,
|
||||
}
|
||||
|
||||
export default class Mapa {
|
||||
celdas: number[][] = [];
|
||||
barcosMapa: Map<number, Barco> = new Map<number, Barco>();
|
||||
|
||||
get barcos() {
|
||||
return Array.from(this.barcosMapa.values());
|
||||
}
|
||||
|
||||
constructor() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
this.celdas[i] = [];
|
||||
|
|
@ -18,6 +22,10 @@ export default class Mapa {
|
|||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return { celdas: this.celdas, barcos: this.barcos };
|
||||
}
|
||||
|
||||
setBarcos(barcos: Barco | Barco[]) {
|
||||
const barcosArray = Array.isArray(barcos) ? barcos : [barcos];
|
||||
for (const barco of barcosArray) {
|
||||
|
|
@ -44,8 +52,8 @@ export default class Mapa {
|
|||
return null;
|
||||
}
|
||||
|
||||
marcaDisparo(x:number,y:number,valor:number){
|
||||
this.celdas[x][y]=valor;
|
||||
marcaDisparo(x: number, y: number, valor: number) {
|
||||
this.celdas[x][y] = valor;
|
||||
}
|
||||
|
||||
getInformacionBarcos(): Barco[] {
|
||||
|
|
@ -54,7 +62,7 @@ export default class Mapa {
|
|||
|
||||
verificaDisparo(x: number, y: number): boolean {
|
||||
if (this.celdas[x][y] > 0) {
|
||||
const barco = this.getBarcoEnCelda(x,y);
|
||||
const barco = this.getBarcoEnCelda(x, y);
|
||||
if (barco) {
|
||||
barco.recibirImpacto();
|
||||
this.celdas[x][y] = EstadoCelda.Golpe;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,29 @@
|
|||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { UsuariosService } from './usuarios.service';
|
||||
import BattleshipGame from 'src/battleship/battleship';
|
||||
|
||||
export class Partida {
|
||||
constructor(
|
||||
public uuid: string,
|
||||
public uuidJugadorA: string,
|
||||
public nickJugadorA: string = '',
|
||||
public nickJugadorA: string = null,
|
||||
public uuidJugadorB: string = null,
|
||||
public nickJugadorB: string = null,
|
||||
public abierta: boolean = true,
|
||||
public batalla: BattleshipGame = null,
|
||||
) {}
|
||||
|
||||
toJson() {
|
||||
return {
|
||||
uuid: this.uuid,
|
||||
uuidJugadorA: this.uuidJugadorA,
|
||||
nickJugadorA: this.nickJugadorA,
|
||||
uuidJugadorB: this.uuidJugadorB,
|
||||
nickJugadorB: this.nickJugadorB,
|
||||
abierta: this.abierta,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -18,19 +31,16 @@ export class PartidasService {
|
|||
private _partidas: Map<string, Partida> = new Map<string, Partida>();
|
||||
|
||||
constructor(private readonly usuariosService: UsuariosService) {}
|
||||
|
||||
get partidasAbiertas(): Partida[] {
|
||||
return Array.from(this._partidas.values()).filter(
|
||||
(partida) => partida.abierta,
|
||||
);
|
||||
}
|
||||
|
||||
get partidasCerradadas(): Partida[] {
|
||||
return Array.from(this._partidas.values()).filter(
|
||||
(partida) => !partida.abierta,
|
||||
);
|
||||
}
|
||||
|
||||
creaPartida(uuidJugadorA: string) {
|
||||
const uuid = uuidv4();
|
||||
const nickJugadorA =
|
||||
|
|
@ -39,16 +49,16 @@ export class PartidasService {
|
|||
this._partidas.set(uuid, partida);
|
||||
return partida;
|
||||
}
|
||||
|
||||
unirsePartida(uuidJugadorB: string, uuidPartida: string){
|
||||
unirsePartida(uuidJugadorB: string, uuidPartida: string) {
|
||||
const partida = this._partidas.get(uuidPartida);
|
||||
const nickJugadorB = this.usuariosService.usuarios.get(uuidJugadorB)?.nickname;
|
||||
const nickJugadorB =
|
||||
this.usuariosService.usuarios.get(uuidJugadorB)?.nickname;
|
||||
partida.uuidJugadorB = uuidJugadorB;
|
||||
partida.nickJugadorB = nickJugadorB;
|
||||
partida.abierta = false;
|
||||
partida.batalla = new BattleshipGame();
|
||||
return partida;
|
||||
}
|
||||
|
||||
eliminarPartida(uuidJugador: string, uuidPartida: string) {
|
||||
if (!this._partidas.has(uuidPartida)) {
|
||||
return null;
|
||||
|
|
@ -63,5 +73,22 @@ export class PartidasService {
|
|||
this._partidas.delete(uuidPartida);
|
||||
return uuidPartida;
|
||||
}
|
||||
|
||||
|
||||
|
||||
existePartida(uuidPartida: string, uuidJugador: string): boolean {
|
||||
if (!this._partidas.has(uuidPartida)) {
|
||||
return false;
|
||||
}
|
||||
const partida = this._partidas.get(uuidPartida);
|
||||
return (partida.uuidJugadorA === uuidJugador || partida.uuidJugadorB === uuidJugador)
|
||||
}
|
||||
|
||||
getSnapshotJugador(uuidPartida: string, uuidJugador: string){
|
||||
if (this.existePartida(uuidPartida,uuidJugador)){
|
||||
const partida=this._partidas.get(uuidPartida);
|
||||
return partida.uuidJugadorA === uuidJugador ? partida.batalla.jugadorA : partida.batalla.jugadorB;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user