Contenido del curso
Canvas
Mapa del juego
Movimientos del jugador
Colisiones
Bonus: adictividad
Deploy
Próximos pasos
Guardando records del jugador
Contenido del curso
Guardando records del jugador
Guadalupe Monge Barale
studentRubén Ernesto Aragón Gil
studentMiguel Angel Hernandez Colombo
studentNestor Rios Garcia
studentAndres Annicchiarico
studentRaúl Adolfo Sánchez Rodríguez
studentRubén Jaimes
studentNestor Rios Garcia
studentNestor Rios Garcia
studentRicardo Alfonso Chavez Vilcapoma
studentAaron Santiago Loyo Zabala
studentLaura Roa
studentJuan Castro
teacherOrlando Rodriguez
studentRaúl Adolfo Sánchez Rodríguez
studentRaúl Adolfo Sánchez Rodríguez
studentJorge Alejandro Suárez Rivera
studentAlejandro Ramos
studentAndre Huaman Yovera
studentSteven García
studentFabio Escobar
studentRed Robles
studentBeder Danilo Casa Condori
studentRaúl Adolfo Sánchez Rodríguez
studentLuis Alberto Alberto Posada
studentRaúl Adolfo Sánchez Rodríguez
studentManuel Andres García Vera
studentHice esto cuando el usuario gana
Utilizo clases con display:none para que no se vea de comienzo este HTML Lo aprendí del curso de consumo de API, del mismo profe (es crack)
<section class="win-container inactive"> <h3> ¡Felicidades! Terminaste el juego</h3> <span>🏆</span> <p class="newrecord"></p> <a href="/index.html"><input type="button" value="Volver a Jugar"></a> </section>
Luego en js este es mi código
function gameWin() { let newRecord; clearInterval(timeInterval); const newTime = Math.floor((Date.now() - timeStart)/1000); const record = localStorage.getItem('record_time'); // si no tiene record o su tiempo es mejor que el anterior if (!record || record > newTime ) { localStorage.setItem('record_time', newTime); newRecord = true; } game.fillText(m.emojis['WIN'], playerPosition.x, playerPosition.y); setTimeout(()=> { n.win.classList.remove('inactive'); n.gameContainer.classList.add('inactive'); newRecord ? n.recordStatus.textContent = 'Conseguiste un nuevo record' : n.recordStatus.textContent = `No superaste el record de ${record} seg.`; }, 1000); return; }
En la función startGame le agregué esta línea
n.recordSeg.textContent = localStorage.getItem('record_time') || 'Todavía no tienes record de';
Si ya hay algo en localStorage lo muestra, si no le dice al usuario que todavía no tiene nada. Esto es visible en la vista principal
Yo usé Git Bash:
1.- Accede a tu proyecto con cd + nombre de la carpeta 2.- git status (miras rojo los archivos modificados) 3.- git add . (agregas todos los archivos con modificación) 4.- git commit -m "escribe el nombre de tu commit" 5.- git push -u origin main 6.- Ve a tu repo en Github y confirma que esté todo allí.
el mejor comentario que he leido !!! un heroe!!! odin esta orgulloso de ti
UFF, yo me quedé con ese hábito desde el curso de Freddy
Amigos les dejo una funcion para pasarle como parametro los milisegundos y transformarlos en minutos y segundos antes de mandarlo al span del html:
function millisToMinutesAndSeconds(millis) { var minutes = Math.floor(millis / 60000); var seconds = ((millis % 60000) / 1000).toFixed(0); return minutes + ":" + (seconds < 10 ? '0' : '') + seconds; }
DESPLIEGUE DEL JUEGO EN GITHUB PAGES:
🎮Taller: Crea tu primer videojuego 🎮
El videojuego ha sido elaborado durante las sesiones del taller de Platzi con HTML🧡, CSS 💙y JavaScript💛 y adicionalmente se han añadido algunas funcionalidades, como:
| Funcionalidad | Tutorial |
|---|---|
| Incorporación de fuego 🔥 en las colisiones contra las bombas | Entra aquí |
| Contador de tiempo ⏱ en segundos + 2 decimales | Entra aquí |
| Tarjetas interactivas al perder, ganar sin récord y ganar con nuevo récord | Entra aquí |
| Pantalla de inicio del juego 🤠 | Entra aquí |
📌Prueba la demo del juego 🎮 ⭐⭐⭐⭐⭐
📌Échale un vistazo al repositorio de GitHub
📌Échale un vistazo al Taller de Platzi
Excelente UwU
Esta super, de momento no entendi nada jeje, tiene unos pequeños bugs, pero esta super.
Asi vamos
!Clase_19
Juega aquí
Ve mi código aquí
Antes de subir mi proyecto a github, le agregué una portada 😅
Que bonito
Hola! Alguno sabe como se borra el record del navegador para empezar de nuevo?
Para borrar algo en localStorage puedes user removeItem. O mejor aún, puedes simplemente crear un botón de reiniciar el record que le asigne el tiempo por defecto con setItem. :D
Les dejo mi juego. v0.29 alpha Faltan detalles por pulir, por eso es una version alpha.
🎮OPORTUNIDAD DE MEJORA: Tarjetas de mensajes al ganar y perder el juego ⭐⭐
Resultado
Paso a paso
🎮Almacena tus mejores tiempos y establece tu propio record, utilizando localStorage 🏆🏆🏆
Resultado
Paso a paso
para que el tiempo y el record se muestre en el formato de tiempo que nosotros usamos el código es así
function showTime() { const time = Date.now() - timeStart; const minutes = Math.floor(time / 60000); const seconds = Math.floor((time % 60000) / 1000); const milliseconds = time % 1000; spanTime.innerHTML = `${minutes}:${seconds}.${milliseconds}`; } function showRecord() { const record_time = localStorage.getItem('record_time'); if (record_time) { const minutes = Math.floor(record_time / 60000); const seconds = Math.floor((record_time % 60000) / 1000); const milliseconds = record_time % 1000; spanRecord.innerHTML = `${minutes}:${seconds}.${milliseconds}`; } else { spanRecord.innerHTML = 'Sin registro aún.'; } }```
Ahora intentaré hacer una página de inicio y una página de cierre xd
game.js
const canvas = document.querySelector("#game"); const game = canvas.getContext("2d"); window.addEventListener("DOMContentLoaded", startGame); window.addEventListener("resize", setCanvasSize); // Obtener referencias a los botones const upButton = document.getElementById("up"); const leftButton = document.getElementById("left"); const rightButton = document.getElementById("right"); const downButton = document.getElementById("down"); const spanLives = document.getElementById("lives"); const spanTime = document.getElementById("time"); const recordTime = document.getElementById("record"); // Agregar manejadores de eventos a los botones upButton.addEventListener("click", () => movePlayer("up")); leftButton.addEventListener("click", () => movePlayer("left")); rightButton.addEventListener("click", () => movePlayer("right")); downButton.addEventListener("click", () => movePlayer("down")); document.addEventListener("keydown", handleKeyDown); let playerPosition = { x: undefined, y: undefined, }; let giftPosition = { x: undefined, y: undefined, }; let bombPosition = []; let lives = 3; let startMap = 0; let timeStart; let timePlayer; let timeInterval; function handleKeyDown(event) { const key = event.key.toLowerCase(); let direction; switch (key) { case "arrowup": case "w": direction = "up"; break; case "arrowleft": case "a": direction = "left"; break; case "arrowright": case "d": direction = "right"; break; case "arrowdown": case "s": direction = "down"; break; default: return; } // Realizar alguna acción basada en la dirección detectada // Por ejemplo, llamar a una función para mover al jugador en esa dirección movePlayer(direction); } let elementsSize; let map; function startGame() { parseMap(); setCanvasSize(); } async function movePlayer(direction) { // Realizar acciones según la dirección recibida switch (direction) { case "up": if (!(playerPosition.y > 0)) { return; // No se cumple la condición, se sale de la función sin hacer nada } playerPosition.y -= 1; // Lógica para mover al jugador hacia arriba break; case "left": if (!(playerPosition.x > 0)) { return; // No se cumple la condición, se sale de la función sin hacer nada } playerPosition.x -= 1; // Lógica para mover al jugador hacia la izquierda break; case "right": if (!(playerPosition.x < 9)) { return; // No se cumple la condición, se sale de la función sin hacer nada } playerPosition.x += 1; // Lógica para mover al jugador hacia la derecha break; case "down": if (!(playerPosition.y < 9)) { return; // No se cumple la condición, se sale de la función sin hacer nada } playerPosition.y += 1; // Lógica para mover al jugador hacia abajo break; default: return; } showTime(); if ( giftPosition.x === playerPosition.x && giftPosition.y === playerPosition.y ) { lvlUp(); return; } else if ( bombPosition.some( (bombItem) => bombItem.x === playerPosition.x && bombItem.y === playerPosition.y ) ) { lvlFail(); return; } // Actualizar el juego, dibujar el mapa actualizado, etc. drawMap(); } function lvlUp() { if (isGameWin(startMap)) { clearInterval(timeInterval); var elapsedTime = Date.now() - timeStart; let record = localStorage.getItem("record"); if (elapsedTime < record) { localStorage.setItem("record", elapsedTime); } if (record == null) { localStorage.setItem("record", elapsedTime); } resetGame(); return; } startMap++; startGame(); } function isGameWin(startMap) { return maps.length == startMap + 1; } function resetGame() { startMap = 0; lives = 3; playerPosition = { x: undefined, y: undefined, }; timeStart = undefined; startGame(); } function lvlFail() { game.fillText( emojis.BOMB_COLLISION, playerPosition.x * elementsSize, (playerPosition.y + 1) * elementsSize ); lives -= 1; if (lives === 0) { setTimeout(function () { resetGame(); }, 600); return; } playerPosition = { x: undefined, y: undefined, }; setTimeout(function () { startGame(); }, 600); } function setCanvasSize() { const canvasSize = Math.min(window.innerHeight, window.innerWidth) * 0.75; canvas.width = canvasSize; canvas.height = canvasSize; elementsSize = Math.floor(canvasSize / 10 - 1); game.font = `${elementsSize}px Verdana`; drawMap(); } function drawMap() { game.clearRect(0, 0, canvas.width, canvas.height); bombPosition = []; showLives(); showRecord(); map.forEach((row, y) => { row.forEach((emoji, x) => { game.fillText(emoji, x * elementsSize, (y + 1) * elementsSize); if (emoji === "🚪") { if (playerPosition.x === undefined && playerPosition.y === undefined) { playerPosition = { x, y }; } // Utiliza object destructuring para simplificar la asignación de coordenadas } if (emoji === "🎁") { giftPosition = { x, y }; } if (emoji === "💣") { bombPosition.push({ x, y }); } }); }); game.fillText( emojis.PLAYER, playerPosition.x * elementsSize, (playerPosition.y + 1) * elementsSize ); // Utiliza la notación de puntos para acceder a las propiedades del objeto emojis } function showLives() { spanLives.innerHTML = emojis.HEART.repeat(lives); } function showTime() { if (!timeStart) { timeStart = Date.now(); timeInterval = setInterval(function () { var elapsedTime = Date.now() - timeStart; var formattedTime = formatTime(elapsedTime); spanTime.innerHTML = formattedTime; }, 100); } } function showRecord() { let record = localStorage.getItem("record"); var formattedTime = formatTime(record); recordTime.innerHTML = formattedTime; } function formatTime(milliseconds) { var minutes = Math.floor(milliseconds / 60000); milliseconds %= 60000; var seconds = Math.floor(milliseconds / 1000); var millisecondsRemaining = milliseconds % 1000; var formattedTime = `${minutes.toString().padStart(2, "0")}:${seconds .toString() .padStart(2, "0")}:${millisecondsRemaining.toString().padStart(3, "0")}`; return formattedTime; } function parseMap() { try { const mapString = maps[startMap].trim(); const lines = mapString.split("\n").map((line) => line.trim()); map = lines.map((line) => line.split("").map((symbol) => emojis[symbol])); } catch (error) { setTimeout(function () { resetGame(); }, 300); } }
yo lo hice de esta manera y el inner lo coloque en la funcion startGame
function showRecord(){ if(timePlayer < localStorage.getItem('record')){ localStorage.setItem('record', timePlayer); }else{ alert('No superaste el tiempo :(') } }
Mi solución:
function showRecord() { if (!localStorage.puntaje) { localStorage.setItem("puntaje", 9999); } recordSpan.innerHTML = localStorage.puntaje + " seg"; }
Mi código terminó siendo un poco diferente al del profe!
la idea es que funcione
🎮OPORTUNIDAD DE MEJORA 2: Pantalla de inicio del juego ⭐⭐
Resultado
Paso a paso
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
Prueba la demo: Hasta aquí llega la elaboración del videojuego. Te invito a testear la demo y a dejarme tu feedback: 📌Prueba la demo del juego 🎮 ⭐⭐⭐⭐⭐ 📌Échale un vistazo al repositorio de GitHub
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
Hola, Esta muy bien tu proyecto, también estoy desarrollando el taller aunque aun no lo termino, he implementado cosas diferentes que compartiré en su momento...
pero hay un detalle que creo,muy respetuosamente, importante dentro de la forma de jugar y que podrías ajustar y es que cuando se cargue la pantalla de juego el reloj se active con el primer movimiento y no en automático.
saludos y en hora buena por tu desarrollo..
Muy importante observación Luis, créeme que también lo pensé y espero poder implementarlo.
Gracias por comentar!
aqui esta el link del despliegue en github pages
https://manuel15939.github.io/taller-practico-javascript-videogame/
faltan muchas cosas por mejorar, pero en lo posible se haran mas adelante