BattleShip/Mapa.js
2024-03-27 13:42:31 +01:00

204 lines
6.8 KiB
JavaScript

import Oceano from "./oceano.js";
class Mapa {
celdas = [];
barcos = [];
barcoSeleccionado;
constructor(canvas, size, scale, oceanoImg) {
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.oceano = new Oceano(this.width, this.height, 32, oceanoImg);
this.casillaSize = 64;
this.numFilas = 10;
this.numColumnas = 10;
this.inicializarCeldas();
canvas.addEventListener("click", this.getPosClick);
canvas.addEventListener("contextmenu", this.giraBarcoSeleccionado);
canvas.addEventListener("mousemove", this.mueveBarcoSeleccionado);
document.addEventListener("keydown", this.handleKeyDown);
}
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) {
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(...barcosArray);
}
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() {
this.setBarcos(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;
}
draw() {
this.ctx.clearRect(0, 0, this.width, this.height);
this.oceano.draw(this.ctx);
this.barcos.forEach((barco) => {
barco.draw(this.ctx);
});
if (this.barcoSeleccionado) this.barcoSeleccionado.draw(this.ctx);
// this.ctx.beginPath();
// for (let i = 0; i <= this.numFilas; i++) {
// const y = i * this.casillaSize;
// this.ctx.moveTo(0, y);
// this.ctx.lineTo(this.casillaSize * this.numColumnas, y);
// }
// for (let i = 0; i <= this.numColumnas; i++) {
// const x = i * this.casillaSize;
// this.ctx.moveTo(x, 0);
// this.ctx.lineTo(x, this.casillaSize * this.numFilas);
// }
// this.ctx.strokeStyle = "rgba(0, 255, 0, 0.2)";
// 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);
// }
// }
}
}
export default Mapa;