Contenido del curso
Contenido del curso
marco antonio
Andriw Jose Rollo Castro
Antonio Mora
Wilkins Bernardo Brito Serrano
Eliezer Hernandez
Wilkins Bernardo Brito Serrano
Eliezer Hernandez
Tommy Toala Cox
Wilkins Bernardo Brito Serrano
Tommy Toala Cox
Matias Martel
Oscar Israel Román Quispe
Julian Avila
Angel David Velasco Bonifaz
Agustin Orcha Mata
Manuel Araujo
Laura Roa
David Fernando Estacio Quiroz
Ricardo Alfonso Chavez Vilcapoma
Miguel Angel Suarez Forero
Paula Inés Cudicio
Juan Castro
Paula Inés Cudicio
Eduard Barrios
Juan Castro
Angel David Velasco Bonifaz
César Augusto Cortés Labrada
Federico Ivan Llano
Abigail Nahomi Chávez Lozano
Andre Huaman Yovera
Libian María Hernández Gil
Ivan de jesus Romero leal
si esta complicado mover la pantalla mientras juegas XD
no mas por que mi compu no me aguanta el obs si no grabaría como queda con las animaciones mientras juego XD en fin.
si quieren evitar un dolor de cabeza con las posiciones y las colisiones, animaciones ...o si le puse animaciones a esto cuando explotan las bombas y cuando mueres y mas cosas locas como sea esta es la solución para hacerles la vida mas sencilla
Perfecto. Lo hice de esta forma: en cada uno de los objetos (playerPosition, giftPosition, etc) guardo únicamente el índice. De esta forma siempre tengo una matriz de índices 10x10. La variable element size me sirve únicamente cuando voy a renderizar los emojis. Así también nos ahorramos el problema de los decimales, pues las posiciones que se comparan son número enteros del 1 al 10 (en realidad del 0 al 9 por como contamos en programación).
Yo lo solucioné creando otra objeto para la posición del jugador
playerPostion para guardar el índice de la 🚪 y mi funciónmoverPlayer quedo así: playerPostion
Les comparto mi código para que lo puedan verificar.
Antonio quise aplicar tu solución en mi código pero te cuento que al cambiar las constantes de la forma que tu lo hiciste mi calavera se escondió no me paraece por ningun lado o bueno debe estar en otro extremo del canvas que no lo puedo ver en la pantalla
Reposicionar al player al cambiar el tamaño de la viewport
Excelente, ¿podrías pasarme tu repositorio?
@wilkinsbrito Hola, como estas? Gracias por comentar aca tienes el link del repositorio: https://github.com/eliezersam93/Taller-practico-javascript-videogames No es muy detallado en los commits, ya que este taller lo realice solo por curiosidad, porque había realizado los cursos en sus versiones anteriores, pero aun así espero que te sea de ayuda. No dudes en escribir si requieres algo mas.
La verdad fui resolviendo todos esos bugs mientras seguía el curso, y de hecho ahí faltan mencionar; Que el tiempo que agarra para ponerlo en el record, está un poco desfasado, por unos segundo, por lo que hay que hacer unos pequeños ajuste. Así quedo mi repo https://estrelladlm.github.io/game-with-js/
Súper!!! ¿me podrías pasar tu repositorio para checar tu código porque a mi no me funciona ni siquiera el código que me descargué de esta clase que se supone que es la solución me funciona es como si lo hubiesen subido con el mismo error del video. Qué frustante!!
Hola @wilkinsbrito, qué tal? Lo lograste?, coméntamelo! Aquí te dejo mi repo
https://github.com/EstrellaDLM/game-with-js Espero te sea de ayuda, y estoy al pendiente xD.
Cualquier cosa, ese repo lo abandoné hace un tiempo
Bueno vamos con los errores que no he visto aun solucionados o que puedo ofrecer una solucion alternativa.
Bug # 1 decimales incorrectos al reajustar el canvasSize:
function resizeCanvas () { windowHeight = window.innerHeight * 0.8; windowWidth = window.innerWidth * 0.8; //Dependiendo del tamaño de la pantalla, va a colocar el tamaño cuadrado del canvas //Al dividir entre 10 y luego aproximar el valor a un entero garantiza que el canvas será un entero múltiplo de 10. Finalmente se multiplica la expresión por 10 para obtener el dato real del canvas //Con Math.ceil nos ahorramos el problema de los decimales if (window.innerHeight > window.innerWidth) { if ((windowWidth % 10) !== 0) { canvasSize = Math.ceil(windowWidth / 10) * 10; } else { canvasSize = windowWidth; }} else { if ((windowHeight % 10) !== 0) { canvasSize = Math.ceil(windowHeight / 10) * 10; } else { canvasSize = windowHeight; } } canvas.setAttribute('width', canvasSize); canvas.setAttribute('height', canvasSize); elementsSize = (canvasSize / 10); startGame(lvl); }
En vez de ponerme a retocar el valor elementalSize recortando decimales me decidi por ir a la raiz del error, el canvasSize, aplicando lo mostrado arriba en los casos de resoluciones extrañas que probe el valor de elementsSize en todo momento es un entero por lo que no genera ningun tipo de problema en las coordenadas.
/////////////
Bug #2 Al perder todas las vidas y volver a comenzar sin refrescar la pagina el juego no termina el timer al llegar a la meta del ultimo mapa:
function bombsDetection () { //Buscamos una coincidencia en el array contenido en la propiedad lvl(ej. 0) y en caso de que la posicion del jugador coincida con alguna de las bombas reseteamos su posicion al inicio del mapa bombsDetected = bombsPosition[lvl].find(bomb => bomb[0] == playerPosition.x && bomb[1] == playerPosition.y); if (bombsDetected) { console.log("collision detected") lives--; if (lives <= 0) { lvl = 0; lives = 3; timeStart = undefined; clearInterval(timeInterval) } playerPosition.x = undefined; playerPosition.y = undefined; startGame(lvl); } }
Este fue muy sencillo de resolver pero raro de encontrar. Debemos buscar en nuestro codigo donde reseteamos el juego si perdemos todas las vidas y observar que cuando sucede eso nosotros establecemos como undefined a la variable timeStart, pero ademas debemos agregarle un clearInterval para volver a comenzar desde cero el tiempo del juego ya que sino el juego abre otra instancia de timeInterval y esa no podemos detenerla al llegar a la meta, lo cual seria el comportamiento normal de nuesto juego.
/////////////
Bug #3 Desfasaje entre el tiempo en que completamos el juego y el record que seteamos en localStorage.
Si analizamos nuestro codigo, durante la clase definimos una variable llamada: timePlayer, la cual no manipulamos en todo el ciclo de ejecucion:
let lvl = 0; let lives = 3; let timeStart; let timePlayer; let timeInterval;
Bueno esa variable utilizaremos para alojar el contenido que insertaremos en el local storage de la siguiente manera:
En la parte visual:
function timeSystem() { timePlayer = formatTime(Date.now() - timeStart); spanTime.innerHTML = timePlayer; } function showRecord(){ spanRecord.innerHTML= localStorage.getItem('record_time'); }
Y dentro de la logica:
function gameWin() { console.log('¡Terminaste el juego!'); clearInterval(timeInterval) const recordTime = localStorage.getItem('record_time'); const playerTime = timePlayer; if (recordTime) { if (recordTime >= playerTime) { localStorage.setItem('record_time', playerTime); pResult.innerHTML = 'Superaste el record'; } else { pResult.innerHTML = 'No superaste el record'; } } else { localStorage.setItem('record_time', playerTime); pResult.innerHTML = 'Nuevo record, ahora trata de superarlo'; } showRecord() }
Si bien de la manera que vimos en clase trabajamos con el mismo valor, asumo que lo consulta con un pequeño desfasaje al momento de setear el visual y setar el localStorage, haciendolo de esta forma nos aseguramos que tanto uno como otro consulten el mismo valor (timePlayer).
¡Muchas gracias! Sí funcionaron =D
Gracias matias.
Para solucionar un poco los errores de los decimales, se le puede poner un toFixed(0) al ancho y alto del canvas.
Me salvaste la vida, porque me estaba volviendo loco :)
Creo 2 variables:
let ultima_x; let ultima_y;
Dentro de la función movePlayer, le asigno a la variable ultima_x el valor de playerPosition.x, y a la variable ultima_y le asigno el valor de playerPosition.y.
ultima_x = playerPosition.x; ultima_y = playerPosition.y;
Entonces dentro de la funcion setCanvasSize le asigno a playerPosition.x y playerPosition.y los últimos valores que tuvieron y que capturé en movePlayer:
playerPosition.x = ultima_x; playerPosition.y = ultima_y;
Esto funciona si se hace resize de una sola dimensión a la vez, ya que en este caso las dimensiones internas del canvas se mantienen constantes. Pero si se hace resize en ambas dimensiones de la pantalla al mismo tiempo, la dimensión interna del canvas cambia constantemente y el player se desplaza. Para resolver esto último, creo una tercera variable
let canvasSize1;
A la cual le asigno un valor con el mismo condicional del canvasSize original pero dentro de la función movePlayer
if(window.innerHeight > window.innerWidth) { canvasSize1 = window.innerWidth * 0.7; } else { canvasSize1 = window.innerHeight * 0.7; }
Ahora dentro de la función setCanvasSize, modifico lo que había escrito, colocando la asignación de valores que había hecho dentro de la condición de que ambos valores de dimension del canvas sean iguales, pero que si la dimension interna del canvas cambió, entonces se utilce un factor de ajuste
if(canvasSize == canvasSize1) { playerPosition.x = ultima_x; playerPosition.y = ultima_y; } else { playerPosition.x = ultima_x*(canvasSize/canvasSize1); playerPosition.y = ultima_y*(canvasSize/canvasSize1); }
cambie unos textos y variables a ingles! y asi fue como con la funcion fixNumber() arregle el codigo que el profe menciono :)
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="./styles.css"> <title>VideoGame Project</title> </head> <body> <div class="game-container"> <canvas id="game"></canvas> <div class="btns"> <button id="up">Up</button> <button id="left">Left</button> <button id="right">Right</button> <button id="down">Down</button> </div> <div class="messages"> <p>lives: <span id="lives"></span></p> <p>Time: ⏰: <span id="time"></span></p> <p>Record: 🏁<span id="record"></span></p> <p id="result"></p> </div> </div> <script src="./maps.js"></script> <script src="./game.js"></script> </body> </html>
game.js
const canvas = document.querySelector('#game'); const game = canvas.getContext('2d'); const upButton = document.querySelector ('#up'); const rightButton = document.querySelector ('#right'); const leftButton = document.querySelector ('#left'); const downButton = document.querySelector ('#down'); const spanLives = document.querySelector('#lives') const spanTime = document.querySelector('#time'); const spanRecord = document.querySelector('#record'); const pResult = document.querySelector('#result'); let canvasSize; let elementsSize; let level = 0; let lives = 3; let timeStart; let timePlayer; let timeInterval; const playerPosition = { x: undefined, y: undefined, }; const giftPosition = { x: undefined, y: undefined, }; let enemyPositions = []; window.addEventListener('load', setCanvasSize); window.addEventListener('resize', setCanvasSize); function fixNumber(n) { return Number(n.toFixed(0)); } function setCanvasSize() { if (window.innerHeight > window.innerWidth) { canvasSize = window.innerWidth * 0.7; } else { canvasSize = window.innerHeight * 0.7; } canvasSize = Number(canvasSize.toFixed(0)); canvas.setAttribute('width', canvasSize); canvas.setAttribute('height', canvasSize); elementsSize = fixNumber(canvasSize / 10); playerPosition.x = undefined; playerPosition.y = undefined; startGame(); } function startGame() { console.log({ canvasSize, elementsSize }); console.log(window.innerWidth, window.innerHeight); game.font = elementsSize + 'px Verdana'; game.textAlign = 'end'; const map = maps[level]; if (!map) { gameWin(); return; } if (!timeStart) { timeStart = Date.now(); timeInterval = setInterval(showTime, 100); showRecord(); } const mapRows = map.trim().split('\n'); const mapRowCols = mapRows.map(row => row.trim().split('')); console.log({map, mapRows, mapRowCols}); showLives(); enemyPositions = []; game.clearRect(0, 0, canvasSize, canvasSize); mapRowCols.forEach((row, rowI) => { row.forEach((col, colI) => { const emoji = emojis[col]; const posX = fixNumber(elementsSize * (colI + 1)); const posY = fixNumber(elementsSize * (rowI + 1)); if (col == 'O') { if (!playerPosition.x && !playerPosition.y) { playerPosition.x = fixNumber(posX); playerPosition.y = fixNumber(posY); console.log({playerPosition}); } } else if (col == 'I') { giftPosition.x = fixNumber(posX); giftPosition.y = fixNumber(posY); } else if(col == 'X') { enemyPositions.push ({ x: fixNumber(posX), y: fixNumber(posY), }); } game.fillText(emoji, posX, posY); }); }); movePlayer(); } function movePlayer() { const giftCollisionX = playerPosition.x.toFixed(3) == giftPosition.x.toFixed(3); const giftCollisionY = playerPosition.y.toFixed(3) == giftPosition.y.toFixed(3); const giftCollision = giftCollisionX && giftCollisionY; if(giftCollision) { winningLevel(); } const enemyCollision = enemyPositions.find(enemy => { const enemyCollisionX = enemy.x.toFixed(3) == playerPosition.x.toFixed(3); const enemyCollisionY = enemy.y.toFixed(3) == playerPosition.y.toFixed(3); return enemyCollisionX && enemyCollisionY; }); if(enemyCollision) { levelFail(); } game.fillText(emojis['PLAYER'], playerPosition.x, playerPosition.y); } function winningLevel() { console.log('Level up'); level ++; startGame(); } function levelFail() { console.log("ENEMY!") lives--; console.log(lives) if(lives <= 0) { level = 0; lives = 3; timeStart= undefined; } playerPosition.x = undefined; playerPosition.y = undefined; startGame(); } function gameWin() { console.log('¡Terminaste el juego!'); clearInterval(timeInterval); const recordTime = localStorage.getItem('record_time'); const playerTime = Date.now() - timeStart; if (recordTime) { if (recordTime >= playerTime) { localStorage.setItem('record_time', playerTime) pResult.innerHTML ='you made a new record! Congratulations!'; } else { pResult.innerHTML ='Sorry, this is not a record'; } } else { localStorage.setItem('record_time', playerTime) pResult.innerHTML = 'first time playing? Try to get a new record'; } console.log({recordTime, playerTime}); } function showLives() { const heartsArray = Array(lives).fill(emojis['HEART']); console.log(heartsArray); spanLives.innerHTML = ""; heartsArray.forEach(heart => spanLives.append(heart)) } function showTime() { spanTime.innerHTML = Date.now() - timeStart; } function showRecord() { spanRecord.innerHTML = localStorage.getItem('record_time'); } //rowI and colI are the index // 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); // } // } 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(); } //console.log(event) function moveUp() { console.log('Moving up'); if ((playerPosition.y - elementsSize) < elementsSize) { console.log('OUT'); } else { playerPosition.y -= elementsSize; startGame(); } } function moveLeft() { console.log('moving left'); if ((playerPosition.x - elementsSize) < 20) { console.log('OUT'); } else { playerPosition.x -= elementsSize; startGame(); } } function moveRight() { console.log('moving right'); if ((playerPosition.x + elementsSize) > canvasSize) { console.log(elementsSize) console.log('OUT'); } else { playerPosition.x += elementsSize; startGame(); } } function moveDown() { console.log('moving down'); if ((playerPosition.y + elementsSize) > canvasSize) { console.log('OUT'); } else { playerPosition.y += elementsSize; startGame(); } }
Yo... desde el principio me di cuenta que tendríamos problemas con los decimales y los pixeles. Mi solución fue guardar los indices de los ciclos cuando recorremos el mapa para manejar el canvas como una matriz 10*10
rows.forEach((row, j) => { columns[j].forEach((key, i) => { emoji = emojis[key]; // Position on pixels posX = Math.floor(elementSize * (i + 1)); posY = Math.floor(elementSize * (j + 1)); game.fillText(emoji, posX, posY); // Set origin position to render the player in the very first position if (!playerPosition.X && key == 'O') { playerPosition.X = i + 1; playerPosition.Y = j + 1; } }); });
Y ya luego es más sencillo todo la verdad, simplemente renderizar al jugador:
function renderPlayer() { //console.log(playerPosition) game.fillText( emojis['PLAYER'], // To draw the player we need to calculate the position on pixels Math.floor(elementSize * playerPosition.X + 1), Math.floor(elementSize * playerPosition.Y + 1) ); }
Y en la función de movimiento usamos un switch para comparar el emoji basados en las filas y columnas de nuestro array bidimendional
switch (columns[newRow-1][newColumn-1]) { case 'O': //console.log('Returned to the start'); (level-1 < 0) ? level=level : level-=1; break; case 'X': //console.log('Collided'); lostLive(); // reduce lives return true; case 'I': levelPassed(); break; }
Agregué esto 😅
Para actualizar la ubicación del jugador al cambiar el tamaño de la pantalla plantee la siguiente solución:
const playerPosition = { x: undefined, y: undefined, col: undefined, row: undefined, };
if (elementSize) { oldElementSize = elementSize; } else { oldElementSize = (canvasSize / 10); } elementSize = (canvasSize / 10) ;
if (oldElementPos !== elementPos) { playerPosition.x = (elementPos * playerPosition.col) - (elementPos/2) + fixPos; playerPosition.y = (elementPos * playerPosition.row) - fixPos; playerPosition.x = fixNumber(playerPosition.x); playerPosition.y = fixNumber(playerPosition.y); oldElementPos = elementPos; }
Dejo mi jueguito, le cambié un poquito la temática para mandárselo a mi sobrino que tiene 4 añitos a que lo juegue, asique cambié las calaveras y explosiones por un paseo por el bosque. Agregué algunos mapitas, y cambié la estructura del css. De a poquito le iré agregando mas mapas y mejorándolo. Espero les guste!!!
Ufff. Me encantó la temática y los nuevos niveles. :D
🥰🤩
este fue mi juego al final. https://eduardbarrios.github.io/taller_practico_JS_videogame/
Me encanta :clap:
Solucione lo de la calavera de la siguiente forma. Hay que tomar la formula de la posicion en x y en y Yo la tengo en +5 y --10 para acomodar las bombas y que no se salgan.del canvas-
const posX = elementsSize * (col + 1) + 5; const posY = elementsSize * (rowIndex + 1) - 10;
Bueno vamos a despejar la ubicación de la columna y de la fila donde se encuentra nuestra calavera.
despejando col y row, me quedaron estas formulas. ahora ya se en que columna y fila se encuentra mi player
const colPlayer=((playerPosition.x-5)/elementsSize)-1; const rowPlayer=((playerPosition.y+10)/elementsSize)-1;
y lo que hago es volver a realizar la misma formula de un principio con el nuevo elementSize y lo dibujamos.
playerPosition.x=elementsSize*(colPlayer+1)+5; playerPosition.y=elementsSize*(rowPlayer+1)-10; game.fillText(emojis["PLAYER"], playerPosition.x, playerPosition.y);
y ya nos quedara nuestra calavera en la posición que esta.
Comparto mi solución para corregir el desfase del objeto jugador(calavera) al hacer resize.
Tengo dos variables globales llamadas:
let canvasSize; //Esta fue creada desde las primeras clases let reCanvas; //Se guardará el primer canvasSize al cargar la página luego de un resize // También agregué dos propiedades más a al objeto player; lastX y lastY const player = { x: null, y: null, lastX : null, lastY : null, }
Al principio de la función resizeCanvas(){} agregué el siguiente condicional
function resizeCanvas(){ if(canvasSize){ reCanvas = canvasSize; //Aquí se guarda el primer tamaño del canvas anterior como expliqué arriba } . . . starGame(); }
Luego al llamarse starGame() justo dentro del ciclo forEach doble tengo el siguiente condicional:
starGame(){ . . . map.forEach((row, rowIndex) => { row.forEach((col, colIndex) => { if(player.x || player.y){ if(player.x.toFixed(2) == (elementSize*(colIndex+1.14)).toFixed(2)){ player.lastX = colIndex; } if(player.y.toFixed(2) == (elementSize*(rowIndex+0.88)).toFixed(2)){ player.lastY = rowIndex; } } . . . } }
Como se puede ver; este condicional entra sólo si player.x o player.y tienen algún valor. Luego va a verificar si el valor de la posición de mi jugador en cada coordenada de la matriz es igual al valor de la coordenada actual dentro del ciclo y de esta manera guardará la posición del jugador dentro de la matriz, en que fila o columna está, y las guarda en player.lastX y player.lastY, ósea, estoy guardando los índices que tenía mi jugador dentro de la matriz.
Finalmente en la función movePlayer(){} ejecuto el siguiente condicional:
if(canvasSize > reCanvas || canvasSize < reCanvas){ console.log('entro en 2'); player.y = elementSize*(player.lastY+0.88); player.x = elementSize*(player.lastX+1.14); game.fillText(emojis['PLAYER'], player.x+4, player.y); } else{ //Renderizado de auto game.fillText(emojis['PLAYER'], player.x+4, player.y); }
Cuando halla un resize el va a comparar si el nuevo tamaño del canvas es mayor o menor al anterior, de ser así, va a guardar la posición en X y Y del jugador haciendo uso de los índices que tenía antes de que se haga resize, luego lo renderiza. Pero no no existe un resize pasará al else{} donde pondrá las coordenadas que normales cuando el usuario mueva al jugador.
Se que puede no entenderse sin ver el código completo. Lo estaré compartiendo la próxima clase. De todos modos es muy parecido a todo o que se ha hecho hasta ahora.
Antes de la clase hice algunos cambios y fui arreglando algunas partes visuales dividiendo por 1000 y con toFixed(2) para mostrar el tiempo y el record.
let diferencia = Date.now() - timeStart; segundos = diferencia /1000; spanTime.innerHTML = segundos.toFixed(2);
Ademas agregando que un event keydown para que en el momento en que el player presiona una tecla inicie el tiempo.
let onKeyDown = false; document.body.onkeydown = () => onKeyDown = true; document.body.onmousedown = () => onKeyDown = true; //...... if(!timeStart){ if(onKeyDown){ timeStart = Date.now(); timeInterval = setInterval(showTime, 10) spanResult.innerHTML = ' '; } showRecord() }
Un titulo que muestra el level en el que estas.
function showLevel(){ if(!level >0){ spanLevel.innerHTML = level + 1; } else { spanLevel.innerHTML = ` Game Over` } }
Mi solución a ese problema fue solo redondear la resta en el condicional pero solo en la función de mover hacia arriba (porque solo ahi tenia el problema la inicio). No me valia para las démas direcciones. Está mejor solucionar el problema desde su raiz..👍👍
[Link a mi juego :]](https://tathatahy.github.io/taller-practico-javascript-videogames/)
Hola...les comparto.. Mi repositorio: https://github.com/libian19/videogame Mi deploy: https://libian19.github.io/videogame/
Ok reubicar el player me tomo dos días, tuve que pensar super profundo porque no me funciono las soluciones de los compañeros, así que no voy a pasar el código ya que es mas confuso, esto es para ayudar a los que como yo no les funciono lo que publicaron los demás.
La manera en que lo hice fue haciendo la regla de tres antes de empezar el start game justo en el resize, sigiendo esta formula:
(NuevoCanvasSize * playerPosition.x ) / anteriorCanvasSize
Hacemos esto mismo con el playerPosition.y
Entonces que fue lo que hice, sobre escribi la playerPosition X y Y y lo mande a imprimir cada ves que se hace un resize
Ahora que ya lo detalle como lo hice, aca esta mi codigo
const canvas = document.querySelector("#game") const game = canvas.getContext('2d') let canvasSize //Cree una variable que un if le dara un valor, esta variable es para el tamaño del canvas let elementsSize let level = 0 let lives = 3 let timeStart let timePlayer let timeInterval const playerPosition = {x: undefined, y: undefined} const giftPosition = {x: undefined, y: undefined} let enemiesPosition = [] let resizeElementXandY let arrayUltimoCanvasSize =[] window.addEventListener('load', setCanvasSize) window.addEventListener('resize', resize) function resize(){ if(window.innerHeight > window.innerWidth){ canvasSize = window.innerWidth * 0.7 //si el alto de la pagina es mas grande que el ancho, el canvas solo va a tomar el 80% del ancho }else if (window.innerHeight < window.innerWidth){ canvasSize = window.innerHeight * 0.7 //si el ancho de la pagina es mas grande que el alto, el canvas solo va a tomar el 80% del alto } playerPosition.x = (canvasSize * playerPosition.x) / arrayUltimoCanvasSize[arrayUltimoCanvasSize.length - 1] playerPosition.y = (canvasSize * playerPosition.y) / arrayUltimoCanvasSize[arrayUltimoCanvasSize.length - 1] console.log(playerPosition.x, playerPosition.y) setCanvasSize() } function setCanvasSize(){ if(window.innerHeight > window.innerWidth){ canvasSize = window.innerWidth * 0.7 //si el alto de la pagina es mas grande que el ancho, el canvas solo va a tomar el 80% del ancho }else if (window.innerHeight < window.innerWidth){ canvasSize = window.innerHeight * 0.7 //si el ancho de la pagina es mas grande que el alto, el canvas solo va a tomar el 80% del alto } canvas.setAttribute('width', canvasSize) canvas.setAttribute('height', canvasSize) elementsSize = canvasSize / 10 // playerPosition.x = undefined // playerPosition.y = undefined arrayUltimoCanvasSize.push(canvasSize) // resizeElementPosition.push(elementsSize) // if (resizeElementPosition){ // let ultimoElementSize = resizeElementPosition[resizeElementPosition.length - 2] // console.log(ultimoElementSize) // } startGame() } function startGame(){ game.font = (elementsSize - 15) + "px Verdana" game.fillStyle ="orange" game.textAlign = "end" const map = maps[level] if(!map){ gameWinAndSetRecord() return } if(!timeStart){ timeStart = Date.now() timeInterval = setInterval(showTime, 100 ) showRecord() } // console.log(timeStart) const mapRows = map.trim().split("\n") const mapRowsSinEspacios = mapRows.map((row) => row.trim().split('')) // console.log(mapRows, mapRowsSinEspacios ) //si con un ForEach recibe un segundo parametro. este regresa la ubicacion en el index de ese elemento enemiesPosition = [] game.clearRect(0, 0, canvasSize, canvasSize) showLives() mapRowsSinEspacios.forEach((row, rowI) => { row.forEach((col, colI) => { let emoji = emojis[col] let posX = elementsSize * (colI + 1) let posY = (elementsSize * (rowI + 1)) // console.log({col, colI, row, rowI, emoji}) if(col == 'O' && playerPosition.x == undefined && playerPosition.y == undefined){ playerPosition.x = posX playerPosition.y = posY console.log({"Aqui debe estar el jugador": 0, posX, posY, playerPosition}) } else if (col === 'I'){ giftPosition.x = posX giftPosition.y = posY // console.log({giftPosition}) } else if (col === 'X'){ enemiesPosition.push({col, positionX: posX, positionY: posY}) // console.log(enemiesPosition) } game.fillText(emoji, posX, posY) game.fillText(emojis["PLAYER"], playerPosition.x, playerPosition.y) }) }); // console.log(enemiesPosition) let tempUltimaPosiciones = [playerPosition.x, playerPosition.y] resizeElementXandY = tempUltimaPosiciones movePlayer() } window.addEventListener('keydown', moveByKeys) const btnUp = document.getElementById('up') const btnRight = document.getElementById('right') const btnLeft = document.getElementById('left') const btnDown = document.getElementById('down') const spanLives = document.getElementById('lives') const spanTime = document.getElementById('tiempo') const spanRecord = document.getElementById('record') const pResult = document.getElementById('result') btnUp.addEventListener('click', moveUp) btnRight.addEventListener('click', moveRight) btnLeft.addEventListener('click', moveLeft) btnDown.addEventListener('click', moveDown) 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() } // game.fillText(emojis["PLAYER"], playerPosition.x, playerPosition.y) // console.log(playerPosition.x, playerPosition.y) ///colicion bombas// const enemyCollision = enemiesPosition.find(enemy => { const enemyCollisionX = (enemy.positionX).toFixed(2) == (playerPosition.x).toFixed(2); const enemyCollisionY = (enemy.positionY).toFixed(2) == (playerPosition.y).toFixed(2); return(enemyCollisionX && enemyCollisionY) }) if(enemyCollision){ levelFail() } } function levelWin(){ console.log("subiste de nivel") level++ return startGame() } function levelFail(){ console.log('Chocaste con un enemigo :(') playerPosition.x = undefined playerPosition.y = undefined lives-- if(lives <= 0){ level = 0 lives = 3 timeStart = undefined } startGame() } function gameWinAndSetRecord(){ console.log("Superaste el juego") level = 0 playerPosition.x = undefined playerPosition.y = undefined clearInterval(timeInterval) const recordTime = localStorage.getItem('record_time') //Variable que nos trae una iformacion del local storaage const playerTime = Date.now() - timeStart //Variable que nos trae el ultimo tiempo cuando ya se acabaron los niveles del juego, osea tu marca en la partida //Revisa si ya existia un record y empieza a comparar if(recordTime){ //Si el record en el localStorage es mayor, este lo sobre escribe if(recordTime >= playerTime ){ localStorage.setItem('record_time', playerTime) pResult.innerHTML = 'Haz superado el record ✨✨' } //Y si el tiempo en esta partida no es mayor al record ya impuesto en otras partidas, te avisa que no lo has roto else{ pResult.innerHTML = 'lo siento, no has roto el record 💀' } } //Si no habia un record en el localStorage, lo va a creear else{ localStorage.setItem('record_time', playerTime) pResult.innerHTML = 'Primer ingreso de tiempo ✍' } //Y aca te enseña en la consola el record anterior (si no existe es null), y el record de esta partida console.log({recordTime, playerTime}) // startGame() } function moveUp(){ // console.log('Arriba') if((playerPosition.y - elementsSize) < elementsSize){ console.log("limite") } else{ playerPosition.y = playerPosition.y - elementsSize startGame() } } function moveRight(){ // console.log('Derecha') if((playerPosition.x + elementsSize) > canvasSize){ console.log("limite") } else{ playerPosition.x = playerPosition.x + elementsSize startGame() } } function moveLeft(){ // console.log('Izquierda') if((playerPosition.x - elementsSize) < elementsSize){ console.log("limite") } else{ playerPosition.x = playerPosition.x - elementsSize startGame() } } function moveDown(){ // console.log('Abajo') if((playerPosition.y + elementsSize) > canvasSize ){ console.log("limite") } else{ playerPosition.y = playerPosition.y + elementsSize startGame() } } function moveByKeys(event){ // console.log(event.key) let teclaPulsada = event.key switch(teclaPulsada){ case "ArrowUp": moveUp() break; case "ArrowRight": moveRight() break; case "ArrowLeft": moveLeft() break; case "ArrowDown": moveDown() break; } } /////////////Utilidades visuales (vidas, tiempo, etc ) function showLives(){ //Esto es interesante, el metodo "Array" con a mayuscula te permite crear un array que le puedes decir cuantas posiciones quieres y despues con el metodo fill, la llenas de lo que le pediste let corazonesArray = Array(lives).fill(emojis['h']) // console.log(corazones) // let corazones = "" spanLives.innerHTML = "" corazonesArray.forEach(corazon => { spanLives.append(corazon) // corazones = corazones + corazon // console.log(corazones) } ) } function showTime(){ spanTime.innerHTML = Date.now() - timeStart } function showRecord(){ spanRecord.innerHTML = localStorage.getItem('record_time') } //Esta ves usaremos una herramiendo de navegadores que se llama el localStorage, que nos sirve para guardar informacion en el navegador y lo podamos usar de nuevo con su informacion guardada asi hallamos cerrado la pagina, usa 3 metodos (que conozco) como ".getItem" es para leer la informacio que este guardada , ".setItem" para guardar la informacion, variable etc, ".removeItem" saca la variable que se guardo