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;