No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Victoria: subiendo de nivel

14/24
Recursos

Aportes 27

Preguntas 5

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Lo he logrado, pero mi codigo es una verdadera ensalada, tengo que mejorar eso, voy a tratar de explicarlo.
Lo que se me ocurri贸 es crear un array bidimensional donde almacena las pocisiones de las bombas, pero de cada level, de esta forma, segun el level que estamos y con la misma logica detectamos las colisiones.

En este pedazo de codigo necesito sus consejos, como podria haber hecho esto mejor:

const bombsPosition =[];

let cantidadLevels = mapRowsCols.map(element => bombsPosition.push([]));
// de esta forma a bombsPosition le agrego los arrays internos y vacios segun cuantos niveles tengamos. Como har铆an esto de una mejor forma?

Ya teniendo mi array con arrays internos vacios, seguimos con la misma logica con el metodo push segun el map y level los agregamos(las posiciones)

// esto esta dentro de la funcion starGame() dentro del ciclo for
if(mapRowsCols[level][i][z-1] == 'X' && flag ){
                bombsPosition[level].push({x: elementSize*i, y: elementSize*z})
            }

Mi soluci贸n: Como desde el comienzo estaba creando un objeto de mi mapa.
Para pasar de nivel
Cree una funcion lvlUp(), la cual solo cambia la propiedad de mi objeto base, luego renderiza el siguiente lvl, llamando a la funcion startGame()

function lvlUp() {
    if (map.lvl < maps.length - 1) {
        map.lvl += 1;
        startGame()
    }

}

Para resetear todo
uso do funciones, una que detecta la colision, y la otra que le da los nuevos valores de posicion al player

}
function colision() {
    const enemyColition =map.bombPosition.find(a=>
        {
            const coincideX = map.playerPosition.x.toFixed(3) === a.x.toFixed(3);
            const coincideY = map.playerPosition.y.toFixed(3) === a.y.toFixed(3);
            return coincideY && coincideX
        })


        if (enemyColition) {
            console.log("perdiste")
        }
        return enemyColition
    
}
function resetGame(){
if (colision()){
    map.playerPosition.x=map.doorPosition.x
    map.playerPosition.y=map.doorPosition.y
    startGame()
}

Luego corro esa funci贸n cuando se mueve el jugador

 playerPosition: {
        x: undefined,
        y: undefined,
        render: function () {
            game.fillText(emojis["PLAYER"], this.y, this.x);
            const coincideX = Math.floor(this.x) === Math.floor(map.giftPosition.x);
            const coincideY = Math.floor(this.y) === Math.floor(map.giftPosition.y);

            if (coincideY && coincideX) {
                console.log("Subiste de nivel")
                lvlUp()
            }
            resetGame()
        }

    }

toooodo mi codigo

const canvas = document.getElementById('game');
const game = canvas.getContext("2d");
const btnUp = document.querySelector('#up');
const btnLeft = document.querySelector('#left');
const btnRight = document.querySelector('#right');
const btnDown = document.querySelector('#down')
let canvasSize;
let canvasElement;
const map = {
    lvl: 0,

    playerPosition: {
        x: undefined,
        y: undefined,
        render: function () {
            game.fillText(emojis["PLAYER"], this.y, this.x);
            const coincideX = Math.floor(this.x) === Math.floor(map.giftPosition.x);
            const coincideY = Math.floor(this.y) === Math.floor(map.giftPosition.y);

            if (coincideY && coincideX) {
                console.log("Subiste de nivel")
                lvlUp()
            }
            resetGame()
        }

    },
    giftPosition: {
        x: undefined,
        y: undefined,
    },
    doorPosition: {
        x: undefined,
        y: undefined,
    },
    bombPosition: [],
    render: function () {
        const Map = maps[this.lvl].match(/[IXO\-]+/g)
            .map(a => a.split("")) || console.log("No more maps")

        game.clearRect(0, 0, canvasSize, canvasSize)

        game.font = canvasElement + "px Verdana"
        game.textAlign = "end"
        Map.forEach((x, xi) => {
            x.forEach((y, yi) => {
                const posX = canvasElement * (xi + 1)
                const posY = canvasElement * (yi + 1)
                game.fillText(emojis[y], posY, posX)
               
                    if (y === "O") {
                        this.doorPosition.x = posX
                        this.doorPosition.y = posY
                        if (this.playerPosition.x === undefined && this.playerPosition.y === undefined) {
                        this.playerPosition.x = posX
                        this.playerPosition.y = posY
                        
                    }
                }
                if (y === "I") {
                    this.giftPosition.x = posX
                    this.giftPosition.y = posY
                }
                if (y === "X") {
                    this.bombPosition.push({ x: posX, y: posY })
                }
                

            })
        })
    }
}
// const playerPosition={

// }
window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize)


function setCanvasSize() {
    window.innerHeight > window.innerWidth
        ? canvasSize = window.innerWidth * 0.9
        : canvasSize = window.innerHeight * 0.7;


    canvas.setAttribute("height", canvasSize)
    canvas.setAttribute("width", canvasSize)
    canvasElement = canvasSize / 10;
    startGame()
}


function startGame() {
    map.bombPosition = []
    map.render()
    map.playerPosition.render()
}
function lvlUp() {
    if (map.lvl < maps.length - 1) {
        map.lvl += 1;
        startGame()
    }

}
function colision() {
    const enemyColition =map.bombPosition.find(a=>
        {
            const coincideX = map.playerPosition.x.toFixed(3) === a.x.toFixed(3);
            const coincideY = map.playerPosition.y.toFixed(3) === a.y.toFixed(3);
            return coincideY && coincideX
        })


        if (enemyColition) {
            console.log("perdiste")
        }
        return enemyColition
    
}
function resetGame(){
if (colision()){
    map.playerPosition.x=map.doorPosition.x
    map.playerPosition.y=map.doorPosition.y
    startGame()
}

}
//moviemientos
window.addEventListener("keyup", moveByKey)
btnUp.addEventListener("click", moveUp)
btnLeft.addEventListener("click", moveLeft)
btnRight.addEventListener("click", moveRight)
btnDown.addEventListener("click", moveDown)

function moveUp() {
    map.playerPosition.x - canvasElement < canvasElement
        ? map.playerPosition.x = canvasElement
        : map.playerPosition.x -= canvasElement

    startGame()
}
function moveLeft() {
    map.playerPosition.y - canvasElement < canvasElement
        ? map.playerPosition.y = canvasElement
        : map.playerPosition.y -= canvasElement
    startGame()
}
function moveRight() {
    map.playerPosition.y + canvasElement > canvasSize
        ? map.playerPosition.y = canvasSize
        : map.playerPosition.y += canvasElement
    startGame()
}
function moveDown() {
    map.playerPosition.x + canvasElement > canvasSize
        ? map.playerPosition.x = canvasSize
        : map.playerPosition.x += canvasElement
    startGame()
}
function moveByKey(event) {

    if (event.key === "ArrowUp") moveUp();
    if (event.key === "ArrowLeft") moveLeft();
    if (event.key === "ArrowRight") moveRight();
    if (event.key === "ArrowDown") moveDown();

}

Lo logramos


Asi vamos

Creo que acabo de hacer algo muy chamb贸n jajaja.

En el IF de movePlayer que sirve para detectar la colisi贸n con las bombas ejecute una funcion llamada gameLose la cual consiste en recargar la pagina y asi reiniciar todos los niveles.

Funciona, pero鈥 a qu茅 costo.

Creo dos variables(initX, initY) que guarden la ubicaci贸n de la puerta cada renderizada en el mapa, no importa que nivel sea, y esa ubicaci贸n es la que se le dar谩 a la calavera si choca con algun elemento.

if(col=='O'){
                initX=positionX;
                initY=positionY
                if(!playerPosition.x && !playerPosition.y){
                    playerPosition.x=positionX;
                    playerPosition.y=positionY;
                   
                }

if (estallido){
            game.fillText(emojis['BOMB_COLLISION'],playerPosition.x,playerPosition.y)
            
            console.log(emojis['BOMB_COLLISION']);
            playerPosition.x=initX
            playerPosition.y=initY
           
        }
    });

Tenia el problema de que una vez mi jugador sal铆a de la primera fila, ya no podia volver a subir.

El condicional 鈥榠f鈥 de la funcion moveUp(), tenia ese cambio por decimales de diferencia entre (playerPositions.y - elementsSize) y el msmo elemensSize:

Lo solucion茅 redondeando hacia arriba los decimales de la resta para igualar al de elementsSize y poder moverme hasta la primera fila:

Este es mi c贸digo, al principio me creaba un bucle pero chat GPT me ayudo a solucionarlo, esta en Typescript

import './style.css'
import { maps, emojis } from './maps';

const canvas = document.querySelector('#game') as HTMLCanvasElement;
const game = canvas.getContext('2d')

window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize)
let canvasSize: string;
let elementSize: number;
let level = 0 as number
let winPosition = {
  x:0 as number,
  y:0 as number
}
let player = emojis['PLAYER']
let playerPosition = {
  x:0 as number,
  y:0 as number
}
let mapaActual: { elem: string; x: number; y: number }[] = [];
let element: { elem: string; x: number; y: number } = {
  elem: '-',
  x: 0,
  y: 0,
};
const btnUp = document.querySelector('#up') as HTMLElement
const btnLeft = document.querySelector('#left') as HTMLElement
const btnRight = document.querySelector('#right') as HTMLElement
const btnDown = document.querySelector('#down') as HTMLElement

function setCanvasSize() {
  let height = window.innerHeight;
  let width = window.innerWidth;

  if (height > width) {
    canvasSize = `${width * 0.8}`;
  } else {
    canvasSize = `${height * 0.8}`;
  }

  elementSize = (parseFloat(canvasSize) / 10.5);

  canvas.setAttribute('width', canvasSize);
  canvas.setAttribute('height', canvasSize);
  startGame()
}

let mapa = maps[level]
  // El m茅todo trim elimina los espacios en blanco
let mapRows = mapa.trim().split('\n');
let mapRowCols = mapRows.map(row => row.trim().split(''))


function startGame() {
    console.log('Mapas:', mapa, mapRows, mapRowCols)
    mapa = maps[level]
    mapRows = mapa.trim().split('\n')
    mapRowCols = mapRows.map(row => row.trim().split(''))

  if (!game) {
    console.error('El contexto del lienzo no est谩 disponible');
    return;
  }
  game.font= elementSize + 'px Verdana'
    mapRowCols.forEach((row, i) => {
    row.forEach((col, j) => {
      const emoji = emojis[col]
      let posX =  j * elementSize
      let posY = (i+1) * elementSize
      element = {
        elem: col,
        x: posX,
        y: posY
      }
      mapaActual.push(element)
      if (col == 'O'){
        playerPosition = {
          x: posX,
          y: posY
        }
      // Se crea un array con el valor y las coordenadas  
      }
        game.fillText(emoji, posX, posY)
    })
  })
  movePlayer()
}
function renderGame() {
  if (!game) return;
  game.clearRect(0, 0, canvas.width, canvas.height);
  mapRowCols.forEach((row, i) => {
    row.forEach((col, j) => {
      const emoji = emojis[col];
      let posX = j * elementSize;
      let posY = (i + 1) * elementSize;
      if (col === 'I'){
        winPosition = {
          x: posX,
          y: posY
        }
      }
      game.fillText(emoji, posX, posY);
      
    });
  });
}

function movePlayer() {
  if (!game) return
  renderGame()
  game.fillText(player, playerPosition.x, playerPosition.y);

  mapaActual.map(item => {
    let actualPositionX = Math.floor(playerPosition.x) === Math.floor(item.x)
    let actualPositionY = Math.floor(playerPosition.y) === Math.floor(item.y)
    let actualPosition = actualPositionX && actualPositionY
    if (actualPosition){
      console.log(item.elem)
      if(item.elem === 'X') {
        console.log('Perdiste')
        startGame()
      } 
      if(item.elem === 'I') {
        console.log('Ganaste eeee')
        if(level > maps.length - 1){
          console.log('Fin del juego Ganaste!!')
        }
        else {
          level += 1
          mapaActual = []
          startGame()
        }
      
      }
    }
      
  })
 
  
}
  


function moveUp(){
  playerPosition.y -= elementSize
  if (playerPosition.y > (elementSize * 10)) {
    playerPosition.y = 10 * elementSize
  }
  movePlayer()
}
function moveLeft(){
  playerPosition.x -= elementSize
  if (playerPosition.x < 0) {
    playerPosition.x = 0
  }
  movePlayer()
}
function moveRight(){
  playerPosition.x += elementSize
  if (playerPosition.x > (elementSize * 9)) {
    playerPosition.x = 9 * elementSize
  }
  movePlayer()
}
function moveDown(){
  playerPosition.y += elementSize
  if (playerPosition.y < elementSize) {
    playerPosition.y = elementSize
  }
  movePlayer()
}

function moveByKeys(event: KeyboardEvent) {
  if(event.key == 'ArrowUp') moveUp()
  if(event.key == 'ArrowLeft') moveLeft()
  if(event.key == 'ArrowRight') moveRight()
  if(event.key == 'ArrowDown') moveDown()
}

window.addEventListener('keyup', moveByKeys)

btnUp?.addEventListener('click', moveUp)
btnLeft?.addEventListener('click', moveLeft)
btnRight?.addEventListener('click', moveRight)
btnDown?.addEventListener('click', moveDown)
<h5>Mi Solucion</h5>

En realidad he visto que la mayoria de compa帽eros lo han realizado casi parecido, esta fue como lo realice yo.

// Declare un objeto con valores de x y y, despues la inicialice con la posicion en el momento que se renderiza la puerta
const doorPosition = {
  x: undefined,
  y: undefined,
}

...

if (!playerPosition.x && !playerPosition.y && col == "O") {
    playerPosition.x = positionX;
    playerPosition.y = positionY;
        
    doorPosition.x = positionX;
    doorPosition.y = positionY;
}

...
// Y con una funcion que se llama cuando el jugador choca con las bombas
function gameOver() {
  console.log("Chocaste contra un enemigo!!");
  playerPosition.x = doorPosition.x;
  playerPosition.y = doorPosition.y;
  level = 0;
  startGame();
}

++mi soluci贸n ++

en la funcion movePlayer() remplace el mensaje del condicional que compara cuando hay una colisi贸n con las bombas, en dicho condicional introduje una nueva funci贸n

if (bombasCollision){
        repeatLevel()
    }

en la funci贸n repatLevel introduje el mensaje que hab铆a antes en el condicional, adem谩s, asigne las coordenadas de la puerta o el punto de inicio

function repeatLevel(){
    console.log('chocaste con una bomba');
    playerPosition.x = door.x ;
    playerPosition.y = door.y ;
}

驴 como extraje las coordenadas del punto inicial o la puerta?
cree un un nuevo objeto que contenga las coordenadas de la puerta, las coordenadas se insertan cuando se renderiza el mapa

const door = {
    x : undefined,
    y : undefined,
}
if (col =='O'){
                door.x = posX;
                door.y = posY;
               
                if(!playerPosition.x && !playerPosition.y){
                    playerPosition.x = posX;
                    playerPosition.y = posY;
                    console.log({playerPosition});
                }

La solucion para resetear la posicion del jugador hacia la puerta cada vez que colisione es simplemente crear una variable/contanre que haga una copia del objeto playerPosition con Object.create(playerposition) este copiara la estructura y valores mas no la referecia. Luego de esto en startGame cuando le pasamos la primera posicion a la calabera al principio del nivel pues tambien se la pasaremos a nuestro objeto de la puerta
y en cada levelUp le actualizaremos las coordenadas tomando como referencia la posicion del jugador al principio del nivel de esta manera:

function levelUp(){
  level++
  startGame()
  door.x = playerPosition.x
  door.y = playerPosition.y
 }

asi lo haria yo:

const canvas = document.querySelector("#game");
const context = canvas.getContext("2d");
const btnLeft = document.querySelector("#left");
const btnUp = document.querySelector("#up");
const btnRight = document.querySelector("#right");
const btnDown = document.querySelector("#down");

window.addEventListener("load", setCanvasSize);
window.addEventListener("resize", setCanvasSize);

let canvasSize;
let elementsSize;
let level = -1;

const playerPosition = {
	x: undefined,
	y: undefined,
};
const pricePosition = {
	x: undefined,
	y: undefined,
};
const bombPosition = {
	x: 0,
	y: 0,
};
const initialPosition = {
	x: 0,
	y: 0,
};

function startGame() {
	isPricePosition();
	delMap();

	context.textAlign = "end";
	context.font = elementsSize + "px Verdana";

	let map = maps[level];

	if (!map) {
		gameWin();
		return;
	}

	const cleanMap = map.trim().split("\n");
	const matrixMap = cleanMap.map((row) => row.trim().split(""));
	matrixMap.forEach((row, rowP) => {
		row.forEach((col, colP) => {
			let posX = Math.round(elementsSize * (colP + 1));
			let posY = Math.round(elementsSize * (rowP + 1));

			if (
				col == "O" &&
				playerPosition.x == undefined &&
				playerPosition.y == undefined
			) {
				playerPosition.x = posX;
				playerPosition.y = posY;
				initialPosition.x = posX;
				initialPosition.y = posY;
			}
			if (col == "I") {
				pricePosition.x = posX;
				pricePosition.y = posY;
			}
			if (col == "X") {
				bombPosition.x = posX;
				bombPosition.y = posY;
			}
			if (
				playerPosition.x == bombPosition.x &&
				playerPosition.y == bombPosition.y
			) {
				playerPosition.x = initialPosition.x;
				playerPosition.y = initialPosition.y;
			}
			context.fillText(emojis[col], posX, posY);
		});
	});
	console.log(
		playerPosition.x,
		playerPosition.y,
		pricePosition.x,
		pricePosition.y,
		initialPosition.x,
		initialPosition.y,
		level
	);
	movePlayer();
}

function movePlayer() {
	context.fillText(emojis["PLAYER"], playerPosition.x, playerPosition.y);
}
function delMap() {
	context.clearRect(0, 0, canvasSize, canvasSize);
}

function setCanvasSize() {
	canvasSize;
	if (window.innerWidth >= window.innerHeight) {
		canvasSize = Math.round(innerHeight * 0.8);
	} else {
		canvasSize = Math.round(innerWidth * 0.8);
	}

	canvas.setAttribute("width", canvasSize);
	canvas.setAttribute("height", canvasSize);
	elementsSize = Math.round(canvasSize * 0.1);

	startGame();
}

window.addEventListener("keydown", moveByKeys);
btnLeft.addEventListener("click", moveLeft);
btnUp.addEventListener("click", moveUp);
btnRight.addEventListener("click", moveRight);
btnDown.addEventListener("click", moveDown);

function moveByKeys(event) {
	const tecla = event.key;
	switch (tecla) {
		case "ArrowLeft":
			moveLeft();
			break;
		case "ArrowUp":
			moveUp();
			break;
		case "ArrowRight":
			moveRight();
			break;
		case "ArrowDown":
			moveDown();
			break;
		default:
			break;
	}
}

function moveLeft() {
	if (playerPosition.x > elementsSize) {
		playerPosition.x -= elementsSize;
	}
	startGame();
}
function moveUp() {
	if (playerPosition.y > elementsSize) {
		playerPosition.y -= elementsSize;
	}
	startGame();
}
function moveRight() {
	if (playerPosition.x < canvasSize) {
		playerPosition.x += elementsSize;
	}
	startGame();
}
function moveDown() {
	if (playerPosition.y < canvasSize) {
		playerPosition.y += elementsSize;
	}
	startGame();
}

function isPricePosition() {
	if (
		pricePosition.x == playerPosition.x &&
		pricePosition.y == playerPosition.y
	) {
		level++;
		playerPosition.x = undefined;
		playerPosition.y = undefined;
	}
}

function gameWin() {
	console.log("TERMINASTE EL JUEGO!");
}
// context.clearRect(50, 0, 100, 50);
// context.font = "30px Cabin";
// context.fillStyle = "green";
// context.textAlign = "center";
// context.fillText("Fabio", 100, 100);
// context.fillRect(100, 100, 1, 1);

Dentro de la funci贸n movePlayer(), en el condicional donde revisamos si enemyCollision es true, agregamos una funci贸n por ejemplo levelLost()

      if (enemyCollision) {
        console.log('Chocaste contra un enemigo :(');
        levelLost();
      }

Luego creamos dicha funci贸n levelLost() que primero le vuelve a dar los valores de undefined a las propiedades de playerPosition (si no se hace esto habr谩 un bucle infinito) y luego llamar谩 a la funci贸n startGame:

function levelLost() {
    playerPosition.x = undefined;
    playerPosition.y = undefined;
    startGame();
}

s

Me ha pasado el error de los decimales, en el ultimo decimal habia una variacion y eso hacia que mi calaverita al llegar al tercer nivel se pueda salir del mapa por la parte de arriba

Este es el codigo que causaba ese error:

if(key === "up" && (playerPosition.y > elementsSize)) {
                playerPosition.y -= elementsSize
}

y lo arregle asi:

if(key === "up" && (parseInt(playerPosition.y.toFixed(3)) > parseInt(elementsSize.toFixed(3)))) {
                playerPosition.y -= elementsSize

            }

Quer铆a aportar algo, aunque espero me confirmen si es acertado o no. Pienso que al final de la funci贸n movePlayer() deber铆a haber un return;

Ejemplo:
movePlayer(){
.
.
.
return;
}
De esta manera siempre que un movimiento sea exitoso, osea sin colisiones, todas las ejecuciones y llamados de funciones terminen y sean sacadas de la pila de ejecuciones; de esta manera no habr铆a que esperar a que terminar谩 el juego para por fin obtener un return y finalizar todas ejecuci贸n en la pila.

Aqu铆 mi soluci贸n:

  1. Lo que hice primero fue crear un objeto para obtener las posiciones de la puerta:
const doorPosition = new Map();
doorPosition.set('x', undefined);
doorPosition.set('y', undefined);
  1. Luego asignar los valores correspondientes de 鈥榵鈥 e 鈥榶鈥 en el condicional que ya ten铆amos:
if (col === 'O') {
    if (!playerPosition.get('x') && !playerPosition.get('y')) {
        playerPosition.set('x', posx);
        playerPosition.set('y', posy);
    }
    doorPosition.set('x', posx);
    doorPosition.set('y', posy);
}
  1. Por 煤ltimo constru铆 la funci贸n restartGame():
function restartGame() {
    log('Perdiste!');
    playerPosition.set('x', doorPosition.get('x'));
    playerPosition.set('y', doorPosition.get('y'));

}

en el condicional que vlidabamos la colision con las bombas agregue una funcion

    if (enemyCollision) {
        repeatLevel ()
    }

la funcion seria

function repeatLevel(){
    location.reload()
}

regresa el elemento al inicio pero si estamos en un nivel diferente nos regresa al primero

Lo que hize fue sobreescribir al nivel actual con el nivel que me interesa, en el caso de ganar ira aunmentando hasta el limite del mapa, y al perder lo multiplique por 0 para volver al primer nivel, asi va quedando mi codigo:

const canvas = document.querySelector('#game');
const game = canvas.getContext('2d');
let canvasSize;
let elementSize;

const playerRender = {
  level: 0,
  playerPosition: {
    x: undefined,
    y: undefined,
  },
  giftPosition: {
    x: undefined,
    y: undefined,
  },
  bombPosition: {
    x: [],
    y: [],
  },
  levelUp: function (){
    if (this.level < (maps.length - 1)) {
      this.level += 1;
    } else if ((this.level == (maps.length - 1)) ){
      this.levelWin();
    }
    startGame();
  },
  levelWin: function (){
    console.log('FELICIDADES!!, Ganaste el juego')
  },
  levelLost: function(){
    this.level *= 0;
    console.log('perdiste parce, a la siguiente')
  },
  movePlayer: function () {
    const x = this.getX('PLAYER', this.playerPosition.x)
    const y = this.getY('PLAYER', this.playerPosition.y)

    game.fillText(emojis['PLAYER'], x, y);
  },
  render: function () {
    if (this.level >= maps.length) {
      return console.log("Ese mapa no existe")
    }
    const map = maps[this.level].match(/[IXO\-]+/g)
      .map(a => a.split(""))
    game.font = `${elementSize}px Verdana`;
    game.textAlign = 'center';
    game.textBaseline = 'middle';

    this.bombPosition.x = [];
    this.bombPosition.y = [];

    game.clearRect(0, 0, canvasSize, canvasSize)
    map.forEach((row, rowIndex) => {
      row.forEach((col, colIndex) => {
        const emoji = emojis[col];
        const posX = this.getX(col, colIndex + 1);
        const posY = this.getY(col, rowIndex + 1);


        if (col == 'O') {
          if (!this.playerPosition.x && !this.playerPosition.y) {
            this.playerPosition.x = colIndex + 1;
            this.playerPosition.y = rowIndex + 1;
          }
        } else if (col == 'I') {
          this.giftPosition.x = colIndex + 1;
          this.giftPosition.y = rowIndex + 1;
        } else if (col == 'X') {
          this.bombPosition.x.push(colIndex + 1);
          this.bombPosition.y.push(rowIndex + 1);
        }
        


        game.fillText(emoji, posX, posY);
      });
    });

    this.movePlayer();
  },
  getX: function (icon, posicionNumber) {
    if (icon === 'X') {
      return elementSize * ((posicionNumber - 0.42));
    } else if (icon === 'I') {
      return elementSize * ((posicionNumber - 0.48));
    } else if (icon === 'O') {
      return elementSize * ((posicionNumber - 0.48));
    } else if (icon === 'PLAYER') {
      return elementSize * ((posicionNumber - 0.48));
    } else if (icon === 'BOMB_COLLISION') {
      return elementSize * ((posicionNumber - 0.42));
    }
  },
  getY: function (icon, posicionNumber) {
    if (icon === 'X') {
      return elementSize * ((posicionNumber - 0.32));
    } else if (icon === 'I') {
      return elementSize * ((posicionNumber - 0.28));
    } else if (icon === 'O') {
      return elementSize * ((posicionNumber - 0.32));
    } else if (icon === 'PLAYER') {
      return elementSize * ((posicionNumber - 0.20));
    } else if (icon === 'BOMB_COLLISION') {
      return elementSize * ((posicionNumber - 0.32));
    }
  }

}

window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize);

function setCanvasSize() {
  canvasSize = Math.min(window.innerWidth, window.innerHeight) * 0.7;

  canvas.setAttribute('width', canvasSize);
  canvas.setAttribute('height', canvasSize);

  elementSize = canvasSize / 10.20;

  startGame();
}


function startGame() {
  playerRender.render()
}

// Mapeo entre teclas y direcciones
const keyToDirection = {
  ArrowUp: 'up',
  ArrowLeft: 'left',
  ArrowDown: 'down',
  ArrowRight: 'right',
  w: 'up',
  a: 'left',
  s: 'down',
  d: 'right'
};

const directionToButton = {
  up: document.querySelector('#up'),
  left: document.querySelector('#left'),
  down: document.querySelector('#down'),
  right: document.querySelector('#rigth'),
};

Object.keys(directionToButton).forEach(direction => {
  directionToButton[direction].addEventListener('click', () => {
    move(direction);
  });
});

window.addEventListener('keydown', moveByKey);

function moveByKey(event) {
  const direction = keyToDirection[event.key];
  if (direction) {
    move(direction);
  }
}

function move(direction) {
  if (direction == 'up') {
    if ((playerRender.playerPosition.y) >= 2) playerRender.playerPosition.y -= 1
  } else if (direction == 'left') {
    if ((playerRender.playerPosition.x) >= 2) playerRender.playerPosition.x -= 1
  } else if (direction == 'right') {
    if (playerRender.playerPosition.x <= 9) playerRender.playerPosition.x += 1
  } else if (direction == 'down') {
    if (playerRender.playerPosition.y <= 9) playerRender.playerPosition.y += 1
  }
  
  if (playerRender.playerPosition.x == playerRender.giftPosition.x && playerRender.playerPosition.y == playerRender.giftPosition.y) {
    console.log('colision jugador con regalo')
    playerRender.levelUp();
  }

  playerRender.bombPosition.x.forEach((xBombs, indexBomb) =>{
    let yBombs = playerRender.bombPosition.y[indexBomb]
    if (playerRender.playerPosition.x == xBombs && playerRender.playerPosition.y == yBombs) {
      console.log('Colision Jugador con bombas')
      playerRender.levelLost();
    }

  })
  
  console.log('Posicion jugador', playerRender.playerPosition, 'Posicion bomba', playerRender.bombPosition)

  playerRender.movePlayer();
  startGame();
}

En un principio utilice la funci贸n setCanvas, pero despu茅s mejor hice un objeto doorPosition para guardar el valor de x e y cuando col fuera igual a 鈥極鈥 que da el emoji de la puerta. Ambas propuestas hacen lo mismo, pero mejor solo regresar el elemento a su posici贸n inicial que empezar con todo el canvas de nuevo

if(giftCollisionXY){
        levelUp();
    }else if(bombaCollisionXY){
        console.log('Tocaste una bomba');
        setCanvas();
    }
function initialPosition(){
    console.log('Regresaste a la posicion inicial');
    playerPosition.x = doorPosition.x;
    playerPosition.y = doorPosition.y;
}

C贸mo evitar el ERROR al terminar todos los niveles


Mi soluci贸n

  • Demostraci贸n:

  • Paso a paso:

















Comparto un peque帽o c贸digo para finalizar el juego, espero que les guste.

        if(maps.length > level){
            startGame();
        }else{
            console.log('Felicitaciones, has finalizado el juego.');
            finish = true;
        }

Hab铆a entendido la l贸gica detr谩s, quisiera ver como se hace el reinicio, pq a mi me sale mal xd

Interesante como el profe propone retos para desarrollar la l贸gica de programador en cada clase鈥qu铆 lo que hice es crear dos funciones para subir de nivel y reiniciar nivel si revienta una bomba.

Complete el reto y sinceramente no se como, si alguien me puede explicar viendo mi codigo estaria agradecido.
Basicamente hice que cuando tocabas una bomba puse que playerPosition = doorPosition. Pero nunca defini la posicion de la puerta, queda undefined. asi que con mas razon no entiendo como saber donde esta la puerta. Si alguien lo encuentra agradecido

const canvas = document.querySelector('#game');
const game = canvas.getContext('2d');
const upButton = document.getElementById('up');
const leftButton = document.getElementById('left');
const rightButton = document.getElementById('right');
const downButton = document.getElementById('down');

let canvasSize;
let elementsSize;
let level = 0;

const playerPosition = {
    x: undefined,
    y: undefined,
};

const giftPosition = {
    x: undefined,
    y: undefined,
}

const doorPosition = {
    x: undefined,
    y: undefined,
}

let bombs = [];


window.addEventListener('load', setCanvasSize);
window.addEventListener('resize', setCanvasSize);

function setCanvasSize() {
    if (window.innerHeight > window.innerWidth) {
        canvasSize = window.innerWidth * 0.8;
    } else {
        canvasSize = window.innerHeight * 0.8;
    };

    canvas.setAttribute('width', canvasSize);
    canvas.setAttribute('height', canvasSize);

    elementsSize = canvasSize / 10;

    startGame()
}

function startGame() {
    // console.log({ canvasSize, elementsSize });
    
    game.font = elementsSize + 'px Verdana';
    game.textAlign = 'end';
    
    const map = maps[level];
    
    if (!map) {
        gameWin();
        return;
    }
    
    const mapRows = map.trim().split('\n');
    const mapRowCols = mapRows.map(row => row.trim().split(''));
    
    bombs = [];
    game.clearRect(0, 0, canvasSize, canvasSize);
    mapRowCols.forEach((row, rowI) => {
        row.forEach((col, colI) => {
            const emoji = emojis[col]
            const posX = elementsSize * (colI + 1);
            const posY = elementsSize * (rowI + 1);
            
            // if (level = 1) {
            //     doorPosition.x = posX;
            //     doorPosition.y = posY;
            //     console.log('Posicion de puerta cambiada')
            // }

            if (col == 'O') {
                if (!playerPosition.x && !playerPosition.y) {
                    playerPosition.x = posX;
                    playerPosition.y = posY;
                    console.log({ playerPosition })
                }
            } else if (col == 'I') {
                    giftPosition.x = posX;
                    giftPosition.y = posY;                
            } else if (col == 'X') {
                bombs.push({
                    x: posX,
                    y: posY,
                });
            }

            game.fillText(emoji, posX, posY);
        });
    });

    movePlayer()
    //Another way to do it =>
    // if (playerPosition.x <= 5 || playerPosition.x - 1 > canvasSize) {
    //     console.log('Te FUISTE');
    // } if (playerPosition.y >=402 || playerPosition.y < 40) {
    //     console.log('Te FUISTE')
    // }

    // for (let row = 1; row <= 10; row++) {
    //     for (let col = 1; col <= 10; col++) {
    //         game.fillText(emojis[mapRowCols[row - 1][col - 1]], elementsSize * col, elementsSize * row);
    //     }
    // }
};

function movePlayer() {
    const giftCollisionX = playerPosition.x.toFixed(1) == giftPosition.x.toFixed(1);
    const giftCollisionY = playerPosition.y.toFixed(1) == giftPosition.y.toFixed(1);
    const giftCollision = giftCollisionX && giftCollisionY;

    if (giftCollision) {
        levelWin();
    }


    const bombCollision = bombs.find(enemy => {
        const bombCollisionX = enemy.x.toFixed(1) == playerPosition.x.toFixed(1);
        const bombCollisionY = enemy.y.toFixed(1) == playerPosition.y.toFixed(1);
        return bombCollisionX && bombCollisionY;
    });

    if (bombCollision) {
        youDied();
    }

    game.fillText(emojis['PLAYER'], playerPosition.x, playerPosition.y);
};

function levelWin() {
    console.log('LVLUP!');
    level++;
    startGame()
    //Another way to do it =>
    //     if (level < maps.length - 1) {
    //         level += 1;
    //         playerPosition.x = undefined;
    //         playerPosition.y = undefined;
    //         startGame()
    // }
}

function gameWin() {
    console.log('Terminaste el Juego!')
}

function youDied() {
    console.log('BOOM!');
    playerPosition.x = doorPosition.x;
    playerPosition.y = doorPosition.y;
    startGame()
}

//movimientos
window.addEventListener('keydown', moveByKeys);
upButton.addEventListener('click', moveUp);
rightButton.addEventListener('click', moveRight);
leftButton.addEventListener('click', moveLeft);
downButton.addEventListener('click', moveDown);

function moveByKeys(event) {
    if (event.key == 'ArrowUp') moveUp();
    else if (event.key == 'ArrowRight') moveRight();
    else if (event.key == 'ArrowLeft') moveLeft();
    else if (event.key == 'ArrowDown') moveDown();
};

function moveUp() {
    console.log('UP');

    if ((playerPosition.y - elementsSize) < elementsSize - 1) {
        console.log('OUTSIDE');
    } else {
        playerPosition.y -= elementsSize;
        startGame()
    }

};
function moveLeft() {
    console.log('LEFT');
    if ((playerPosition.x - elementsSize) < elementsSize) {
        console.log('OUTSIDE');
    } else {
        playerPosition.x -= elementsSize;
        startGame()
    }
};
function moveRight() {
    console.log('RIGHT');
    if ((playerPosition.x + elementsSize) > canvasSize + 2) {
        console.log('OUTSIDE')
    } else {
        playerPosition.x += elementsSize;
        startGame()
    }
};
function moveDown() {
    console.log('DOWN');
    if ((playerPosition.y + elementsSize) > canvasSize) {
        console.log('OUTSIDE')
    } else {
        playerPosition.y += elementsSize;
        startGame()
    }
};

Por estos milagros hay que encomendarse con los dioses del internet, gracias juan

Esta fue mi soluci贸n al reto

function levelWin(){
   if(level == 3){
      level = 0;
      playerPosition.x = elementsSize;
      playerPosition.y = canvasSize;
      startGame();
   }else {
      level++;
      startGame();
   }
}

Les comparto mi soluci贸n, cree una funci贸n que verifica la colisi贸n con alguna bomba, si la colisi贸n sucede la posici贸n del jugador vuelve a ser undefined para que la funci贸n startGame le asigne la posici贸n de la puerta.

La funci贸n defeat cada vez que se mueve el jugador, es decir con cada ejecuci贸n de movePlayer

Lo que hice fue crear una variable que guardara el valor inicial de cada level.

Global
const initialPosition = {
  x: undefined,
  y: undefined,
};

en moveplayer()
      if (col == "O" && !playerPosition.x) {
        initialPosition.x = posX;
        initialPosition.y = posY;
        playerPosition.x = posX;
        playerPosition.y = posY;
      }

y cree una funcion que ese ejecuta cuando hay una colision con las bombas

const gameLose=()=>{
  playerPosition.x=initialPosition.x;
  playerPosition.y=initialPosition.y;
  game.clearRect(0, 0, canvasSize, canvasSize);
  drawMap();     //Esta es la funcion startGame
  game.fillText(emojis["PLAYER"], playerPosition.x, playerPosition.y);
}