268 lines
8.3 KiB
JavaScript
268 lines
8.3 KiB
JavaScript
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.id,
|
|
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.id;
|
|
}
|
|
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 };
|