CursosEmpresasBlogLiveConfPrecios

Sistema de tiempo y puntajes

Clase 17 de 24 • Taller Práctico de JavaScript: ¡Crea tu Primer Videojuego!

Clase anteriorSiguiente clase

Contenido del curso

Introducción
  • 1
    Programemos un juego con JavaScript

    Programemos un juego con JavaScript

    17:13
Canvas
  • 2
    ¿Qué es canvas en JavaScript?

    ¿Qué es canvas en JavaScript?

    18:37
  • 3
    Tamaño del canvas y sus elementos

    Tamaño del canvas y sus elementos

    17:37
  • 4
    Canvas responsive

    Canvas responsive

    12:37
Mapa del juego
  • 5
    ¿Qué es un array bidimensional?

    ¿Qué es un array bidimensional?

    05:48
  • 6
    Arreglos multidimensionales en JavaScript

    Arreglos multidimensionales en JavaScript

    23:38
  • 7
    Refactor del mapa de juego

    Refactor del mapa de juego

    20:48
Movimientos del jugador
  • 8
    Eventos y botones

    Eventos y botones

    14:14
  • 9
    Objeto playerPosition

    Objeto playerPosition

    11:34
  • 10
    Limpieza de movimientos

    Limpieza de movimientos

    09:53
  • 11
    No te salgas del mapa

    No te salgas del mapa

    11:15
Colisiones
  • 12
    Detectando colisiones fijas

    Detectando colisiones fijas

    13:29
  • 13
    Detectando colisiones con arrays

    Detectando colisiones con arrays

    14:11
  • 14
    Victoria: subiendo de nivel

    Victoria: subiendo de nivel

    07:50
  • 15
    Derrota: perdiendo vidas

    Derrota: perdiendo vidas

    11:45
Bonus: adictividad
  • 16
    Sistema de vidas y corazones

    Sistema de vidas y corazones

    13:02
  • 17
    Sistema de tiempo y puntajes

    Sistema de tiempo y puntajes

    19:30
  • 18
    ¿Qué es localStorage?

    ¿Qué es localStorage?

    07:33
  • 19
    Guardando records del jugador

    Guardando records del jugador

    18:35
Deploy
  • 20
    Depurando errores del juego

    Depurando errores del juego

    23:16
  • 21
    Desplegando el juego a GitHub Pages

    Desplegando el juego a GitHub Pages

    07:39
Próximos pasos
  • 22
    Reto: reinicio del juego

    Reto: reinicio del juego

    03:36
  • 23
    Reto: timeouts de victoria o derrota

    Reto: timeouts de victoria o derrota

    04:14
  • 24
    ¿Quieres un simulador laboral?

    ¿Quieres un simulador laboral?

    06:53
    Rubén Ernesto Aragón Gil

    Rubén Ernesto Aragón Gil

    student•
    hace 3 años

    Minuto 3:48

      Juan Castro

      Juan Castro

      teacher•
      hace 3 años

      ALGUIEN ENTENDIÓ POR FIN

      Jesus Marquez Martini

      Jesus Marquez Martini

      student•
      hace 3 años

      la moskeramienta

    marco antonio

    marco antonio

    student•
    hace 3 años

    Le construí un format para que se lea mejor ;)

    timeformat.jpg


    también decidí agregarle un timer al contiue no mas para que vea mas bonito  
    //contect const canvas = document.querySelector('#game'); const btnArriba = document.querySelector('#arriba'); const btnAbajo = document.querySelector('#abajo'); const btnDer = document.querySelector('#derecha'); const btnIzq = document.querySelector('#izquierda'); const viewlive = document.querySelector('#lives'); const viewTime = document.querySelector('#time'); const juego = canvas.getContext('2d'); //signals: window.addEventListener('load', loadEvent); window.addEventListener('resize', resizeEvent); let posJugador = undefined; let mapa = Array(); let nivel = 0; let prePosJugador = undefined; let celda_t = 0; let nivel_actual = undefined; let puntoDePartida = Number(0); let canvas_t = 0; var actualizado = Boolean(false); let explociones = Array(); let vidas = 3; let timeStart = undefined; let timeInterval = undefined; let playerTime = 0; const re_iniciar = {'select': 'si', 'resetStart': 'indeciso','exec' : false}; function loadEvent(){ viewTime.innerHTML = '0:0:0'; timeEvent(); resizeEvent();} function resizeEvent(){ actualizado = false; canvas_t = (window.innerWidth < window.innerHeight ? window.innerWidth : window.innerHeight) *.75 ; canvas.setAttribute('width', canvas_t); canvas.setAttribute('height',canvas_t); celda_t = canvas_t / 10; juego.textAlign='end'; juego.font = font_t() +'px arial'; liveEvent(); update();} function font_t(){ return celda_t - celda_t / 10;} function liveEvent(){ const corazon = Array(vidas).fill(emojis['HEART']); viewlive.innerHTML = corazon.join('');} function timeFormat(time_msec){ const time = ~~(time_msec /1000); const min = (time / 60) | 0; const sec = time - (min * 60); const msec = ((time_msec / 10) | 0) - (time * 100); return min +':'+ ((sec < 10 ? '0' : 0) + sec) + ':' + ((msec < 10 ? '0' : 0) + msec);} function paintTimeEvent(){ playerTime = Date.now() - timeStart; viewTime.innerHTML = timeFormat(playerTime);} function timeEvent(var_function = paintTimeEvent){ if(!timeInterval){ timeStart = Date.now(); timeInterval = setInterval(var_function, 100);} else{ clearInterval(timeInterval); timeStart = undefined; timeInterval = undefined;}} function resetStartEvent(){ posJugador = prePosJugador = undefined; nivel = 0; nivel_actual = undefined; puntoDePartida = 0; vidas = 3; actualizado = false; explociones = Array(); re_iniciar['select'] = 'si'; re_iniciar['exec'] = false; re_iniciar['resetStart'] = 'indeciso'; timeEvent(); liveEvent(); playerTime = 0; update();} function update(){ if(re_iniciar['exec']){paintScreenFinal(); return;} cargarMapa(); clear(); paintEvent(); paintEventPlayer(); paintEventExplosion(); actualizado = true;} function cargarMapa(){ if(nivel_actual == nivel || Victoria()) return; nivel_actual = nivel; mapa = map[nivel].match(/[IOX-]/g);} function clear(){ if(!actualizado) { juego.clearRect(0,0, canvas_t, canvas_t); return;} if(posJugador == prePosJugador) return; clearRect(posJugador); clearRect(prePosJugador);} function clearRect(indice){ const x = posX(indice ) - celda_t / 10; const y = posY(indice ) + celda_t / 5; juego.clearRect(x - 1 ,y , - celda_t, - (celda_t + 1));} function posY(indice){ return (~~(indice/10) + 1) * celda_t - celda_t / 5; } function posX(indice){ return (indice - (~~(indice/10) * 10) + 1) * celda_t + celda_t / 10;} function paintEvent(){ if(!actualizado) mapa.forEach((char, idx) => { if(char == 'O' && posJugador == undefined) puntoDePartida = posJugador = idx; juego.fillText(emojis[char], posX(idx), posY(idx) );});} function paintEventPlayer(){ if(victoryEvent()) paintScreenEvent(); else { if(posJugador != undefined && prePosJugador != posJugador){ juego.fillText(emojis[mapa[prePosJugador]],posX(prePosJugador),posY(prePosJugador)); if(!gameOverEvent()) juego.fillText(emojis['PLAYER'], posX(posJugador),posY(posJugador)); else paintScreenEvent();}}} function gameOverEvent(){ if(vidas && mapa[posJugador] == 'X'){ explociones.push(posJugador); --vidas; liveEvent(); juego.fillText(emojis['BOMB_COLLISION'],posX(posJugador),posY(posJugador)); posJugador = puntoDePartida;} if(gameFinishEvent()) { explociones = Array(); return true;} /*juego terminado*/ return false; /*continuar con el juego*/} function paintEventExplosion(){ if(!explociones.length) return; explociones.forEach((pos) =>{ clearRect(pos); juego.fillText(emojis['BOMB_COLLISION'],posX(pos),posY(pos));});} function victoryEvent(){ if(mapa[posJugador] != 'I') return false; else if(nivel < map.length) ++nivel; explociones = Array(); if(gameFinishEvent()) return true;/*juego terminado*/ posJugador = prePosJugador = undefined; actualizado = false; update(); return false;/*continuar con el juego*/} function Victoria(){return nivel >= map.length;} function gameFinishEvent(){ if(!(nivel >= map.length) == (vidas <= 0) && !re_iniciar['exec']) { timeEvent(); re_iniciar['exec'] = true;} return !(nivel >= map.length) == (vidas <= 0);} function paintScreenEvent(){ if(!re_iniciar['exec']) return; paintScreen(Victoria() ? 'WIN': 'GAME_OVER'); paintScreenFinal();} function paintScreenFinal(){ if(!re_iniciar['exec']) return; if(!actualizado) paintScreen(Victoria() ? 'WIN': 'GAME_OVER'); if(!timeInterval && !Victoria() && re_iniciar['select'] != 'exit') { timeEvent(paintScreenFinal);} const media = canvas_t / 2; const media_alta = media - font_t() + 1; const media_baja = media + font_t() - 1; let color, backgroundColor, text = 'continuar', y = media_alta; if(Victoria()){ color = '#ffd700'; backgroundColor = '#01433A';} else { color = '#FF2F22'; backgroundColor = '#211A27';} if(re_iniciar['resetStart'] == 'no' || re_iniciar['select'] == 'exit'){ if(actualizado)paintScreen(Victoria() ? 'WIN': 'GAME_OVER'); if(timeStart) timeEvent(); text = Victoria() ? 'Has Ganado' : 'Game Over'; y = media + (font_t() / 2); re_iniciar['select'] = 'exit';} else if(re_iniciar['resetStart'] == 'si') { timeEvent(); resetStartEvent(); return;} else{ if(timeStart){ const contador = 10 - (((Date.now() - timeStart) / 1000) | 0); text = text + ' ' + contador; if(contador < 0){ timeEvent(); re_iniciar['resetStart'] = 'no'; update(); return;}} paintScreen(Victoria() ? 'WIN': 'GAME_OVER'); paintRectText('', '' , backgroundColor,'center',media, media); paintRectText('', '' , backgroundColor,'center',media, media_baja); let siCa = color, siCb = backgroundColor; let noCa = color, noCb = backgroundColor; if(re_iniciar['select'] == 'no'){ noCa = backgroundColor; noCb = color;} else { siCa = backgroundColor; siCb = color;} paintRectText('no', noCa, noCb,'center',media + font_t(), media + (font_t() / 2)); paintRectText('si', siCa, siCb,'center',media - font_t(), media + (font_t() / 2));} paintRectText('', '' , backgroundColor,'center',media, y); paintRectText(text, color , '','center',media, y);} function paintScreen(emoji){ juego.clearRect(0,0, canvas_t, canvas_t); mapa.forEach((char, idx) =>{ if(char == 'X') char = emoji; juego.fillText(emojis[char],posX(idx),posY(idx));});} function paintRectText(txt, color = '', backgroundColor = '', aling = 'center', x = 0,y = 0){ if(aling) juego.textAlign = aling; if(backgroundColor){ const rect = rectBgText(txt, x, y, aling); juego.fillStyle = backgroundColor; juego.fillRect(rect['x'], rect['y'], rect['width'], rect['height']);} if(color) juego.fillStyle = color; if(txt) juego.fillText(txt, x, y); juego.textAlign = 'end';} function rectBgText(txt, x = 0, y = 0, align=''){ const height = font_t(); const width = txt == ''|| txt == ' ' ? canvas_t : (font_t()*.75)* txt.length; let px = x; let py = y - (height - (height / 6)); if(align == 'center'){px = x - (width / 2);} else if(align != 'left')px = x - width; return {'width': width, 'height':height, 'x': px, 'y' : py};} //signals: window.addEventListener('keydown',keyMov); btnArriba.addEventListener('click', movArriba); btnAbajo.addEventListener('click', movAbajo); btnDer.addEventListener('click', movDer); btnIzq.addEventListener('click', movIzq); //slots: function keyMov(event){ switch(event.keyCode){ //enter S N Y case 13: case 83: case 78: case 89: selectOptionEvent(event.keyCode); break;//selecionar opciones case 37: movIzq(); break;//izquierda case 38: movArriba(); break;//arriba case 39: movDer(); break; //derecha case 40: movAbajo(); break;//abajo default: break;}} function selectOptionEvent(key){ if(key == 83 || key == 89) re_iniciar['resetStart'] = 'si'; else if(key == 78) re_iniciar['resetStart'] = 'no'; else re_iniciar['resetStart'] = re_iniciar['select']; update();} function movArriba(){ prePosJugador = posJugador; posJugador -= 10; if(posJugador < 0) posJugador = prePosJugador; update();} function movAbajo(){ prePosJugador = posJugador; posJugador += 10; if(posJugador >= 100) posJugador = prePosJugador; update();} function movDer(){ if(re_iniciar['exec']) re_iniciar['select'] = 'no'; else{ prePosJugador = posJugador; const pered = (~~(posJugador / 10)) *10 + 10; ++posJugador; if(posJugador >= pered) posJugador = prePosJugador;} update();} function movIzq(){ if(re_iniciar['exec']) re_iniciar['select'] = 'si'; else{ prePosJugador = posJugador; const pered = ~~(posJugador /10) * 10; --posJugador; if(posJugador < pered) posJugador = prePosJugador;} update();}
      Juan Castro

      Juan Castro

      teacher•
      hace 3 años

      Me encanta la idea del counter hacia atrás para reanudar el juego. :clap:

    Juan Jose Sepulveda Calderon

    Juan Jose Sepulveda Calderon

    student•
    hace 3 años

    Date.now()

    El método estático Date.now() devuelve el número de milisegundos transcurridos desde el 1 de enero de 1970 a las 00:00:00 UTC. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now

    Eliezer Hernandez

    Eliezer Hernandez

    student•
    hace 3 años
    Desarrolle una función que de al tiempo en milisegundos, un formato en el que se puede apreciar las horas, minutos, segundos y centisegundos a partir de los milisegundos; tal cual como lo haría un cronómetro.
    carbon (1).png
      Diego Hanssel Perez

      Diego Hanssel Perez

      student•
      hace 3 años

      Hola Eliezer, que fue lo que guardaste en ms? me gusto mucho tu solución y me gustaría implementarla.

      Eliezer Hernandez

      Eliezer Hernandez

      student•
      hace 3 años

      Hola @diego-hanssel-perez, disculpa la demora de mi respuesta. “ms” son los milisegundos, por lo que le puedes pasar a la funcion el tiempo en milisegundos como argumento y la function se encargara de llevar el tiempo representado en esa unidad(ms) al formato que todos solemos utilizar para representar el tiempo de forma mas legible, mostrando las horas, minutos, segundos y centisegundos como se ve arriba en el gif de la misma manera que lo hace un relog digital.

      Ejemplo: -1000 milisegundos equivalen a 1 segundo por lo que deberia verse de la siguiente manera 00:00:01:00. -250000 milisegundos equivalen a 4 minutos con 10 segundos exactos por lo que deberia verse 00:04:10:00. . Si gustas puedes mejorar la función yo realmente no lo hice en su momento porque me encontraba realmente corto de tiempo, por ejemplo la función tiene muchos “magics numbers” que estoy seguro de que más de uno no tendrá claro el contexto de estos números, también podrías sustituir el uso del metodo slice por algún otro metodo lo que podría dar una idea más clara de porque lo estoy usando por ejemplo por el metodo padStart:

      function formatTime(ms){ const cs = parseInt(ms/10) % 100 const seg = parseInt(ms/1000) % 60 const min = parseInt(ms/60000) % 60 const hr = parseInt(ms/3600000) % 24 const csStr = `${cs}`.padStart(2,"0") const segStr = `${seg}`.padStart(2,"0") const minStr = `${min}`.padStart(2,"0") const hrStr = `${hr}`.padStart(2,"0") return`${hrStr}:${minStr}:${segStr}:${csStr}` }

      Gracias por comentar y espero haber resultado de ayuda compañero, nos vemos mas adelante en proximos cursos o en este mismo aporte si tienes alguna pregunta mas no dudes escribirla. Un saludo.

    César Augusto Cortés Labrada

    César Augusto Cortés Labrada

    student•
    hace 3 años

    Utilicé una conversión para que se vea mejor el tiempo.

    function showTime(){ textTime.innerText = +((Date.now()-timeStart)/1000); }

    Además especifiqué en la etiqueta <p> que el tiempo es en segundos. Este curso está super.

    Cristian Zapata

    Cristian Zapata

    student•
    hace 3 años

    Con formato fácil:

    Se crea una función:

    function formatTime(ms){ const cs = parseInt(ms/10) % 100 const seg = parseInt(ms/1000) % 60 const min = parseInt(ms/60000) % 60 const csStr = `${cs}`.padStart(2,"0") const segStr = `${seg}`.padStart(2,"0") const minStr = `${min}`.padStart(2,"0") return`${minStr}:${segStr}:${csStr}` }

    Se modifica el string de showTime():

    function showTime(){ spanTime.innerHTML = formatTime(Date.now()-timeStart); }

    Time: mm:ss:ms

    Nestor Luis Álvarez Rojas

    Nestor Luis Álvarez Rojas

    student•
    hace 3 años

    ¡Que maravilloso profesor eres, Juan!

    Jorge Alejandro Suárez Rivera

    Jorge Alejandro Suárez Rivera

    student•
    hace 2 años

    Yo lo que hice fué cambiar el formato de tiempo a como se conoce normalmente ya que como aparece sin dos puntos ni nada de eso no me parece legible, entonces mi solución es que el tiempo tenga esto

    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}`; }

    eso es lo que cambiaria en la función de showTime, el código completo es este obviamente sin contar lo de las próximas clases

    const canvas = document.getElementById('game'); const game = canvas.getContext('2d'); const btnUp = document.getElementById('up'); const btnLeft = document.getElementById('left'); const btnRight = document.getElementById('right'); const btnDown = document.getElementById('down'); const spanLives = document.getElementById('lives'); const spanTime = document.getElementById('time'); let canvasSize; let elementsSize; let level = 0; let lives = 3; let timeStart; let timePlayer; let timeInterval; const playerPos = { x: undefined, y: undefined, }; const finishPos = { x: undefined, y: undefined, } let enemiesPos = []; 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() { game.font = (elementsSize - 12) + 'px Verdana'; game.textAlign = 'end'; game.textBaseline = 'bottom'; const map = maps[level]; if (!map) { gameWin(); return; } if(!timeStart) { timeStart=Date.now();timeInterval=setInterval(showTime,100); } const mapRows = map.trim().split('\n'); const mapRowCols = mapRows.map(row => row.trim().split('')); showLives(); enemiesPos = []; 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(col == "O"){ if (!playerPos.x && !playerPos.y) { playerPos.x = posX; playerPos.y = posY; } } else if(col == "I"){ finishPos.x = posX; finishPos.y = posY; } else if (col == 'X') { enemiesPos.push({ x: posX, y: posY, }); } game.fillText(emoji, posX, posY); }); }); movePlayer(); } function movePlayer(){ const giftColX = playerPos.x.toFixed(2) == finishPos.x.toFixed(2); const giftColY = playerPos.y.toFixed(2) == finishPos.y.toFixed(2); const giftCol = giftColX && giftColY; if (giftCol) { levelWin(); } const enemiesCol = enemiesPos.find( enemy => { const enemyColX = enemy.x.toFixed(2) == playerPos.x.toFixed(2); const enemyColY = enemy.y.toFixed(2) == playerPos.y.toFixed(2); return enemyColX && enemyColY; }); if (enemiesCol) { levelFail(); } game.fillText(emojis['PLAYER'], playerPos.x, playerPos.y); } function levelWin() { console.log('Subiste de nivel'); level++; startGame(); } function levelFail() { console.log('Chocaste'); lives--; timeStart=undefined; console.log(lives); if (lives <= 0) { level = 0; lives = 3; } playerPos.x = undefined; playerPos.y = undefined; startGame(); } function gameWin() { console.log('¡Terminaste el juego!'); clearInterval(timeInterval); } function showLives() { spanLives.innerHTML = emojis["HEART"].repeat(lives) } 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}`; } window.addEventListener('keydown', moveKeysDir); btnUp.addEventListener('click', moveUp); btnLeft.addEventListener('click', moveLeft); btnRight.addEventListener('click', moveRight); btnDown.addEventListener('click', moveDown); function moveKeysDir(event){ if (event.code == "KeyW" || event.code == "ArrowUp") { moveUp(); } else if (event.code == "KeyA" || event.code == "ArrowLeft") { moveLeft(); } else if (event.code == "KeyD" || event.code == "ArrowRight") { moveRight(); } else if (event.code == "KeyS" || event.code == "ArrowDown") { moveDown(); } } function moveUp(){ if ((playerPos.y - elementsSize) < elementsSize ) { } else { playerPos.y -= elementsSize; startGame(); } } function moveLeft(){ if ((playerPos.x - elementsSize) < elementsSize ) { } else { playerPos.x -= elementsSize; startGame(); } } function moveRight(){ if ((playerPos.x + elementsSize) > canvasSize ) { } else { playerPos.x += elementsSize; startGame(); } } function moveDown(){ if ((playerPos.y + elementsSize) > canvasSize ) { } else { playerPos.y += elementsSize; startGame(); } }
    Raúl Adolfo Sánchez Rodríguez

    Raúl Adolfo Sánchez Rodríguez

    student•
    hace 2 años

    Solución a contador de tiempo de juego a partir de minuto 11:40 de la clase

    1. Solución

    2. Paso a paso

      Slide1.png
      Slide2.png
      Slide3.png
      Slide4.png
      Slide5.png
      Slide6.png
      Slide7.png
      Slide8.png
      Slide9.png
      Slide10.png
      Slide11.png
      Slide12.png
      Slide13.png
      Slide14.png
      Slide15.png
      Slide16.png
      Slide17.png
      Slide18.png
      Slide19.png
      Slide20.png
      Slide21.png
      Slide22.png
      Slide23.png

    Miguel Angel Hernandez Colombo

    Miguel Angel Hernandez Colombo

    student•
    hace 3 años

    hice los tres niveles en 10 segundos ajajajajaj

    Hector Maluy Fernandez

    Hector Maluy Fernandez

    student•
    hace 3 años

    ¿Sería lo mismo si a timeStart lo seteas a null o a false en lugar de undefined?

      Juan Castro

      Juan Castro

      teacher•
      hace 3 años

      Yep

      Oscar Gutiérrez

      Oscar Gutiérrez

      student•
      hace 2 años

      Si ya que tanto undefined como null o 0 (entre otros) son valores falsy lo que significa que representa un valor falso en un contexto booleano

    Raúl Adolfo Sánchez Rodríguez

    Raúl Adolfo Sánchez Rodríguez

    student•
    hace 2 años

    Función global: clearInterval( )

    _

    clearInterval-function.png
    Adhemar Duran Gahuincha

    Adhemar Duran Gahuincha

    student•
    hace 3 años

    En la función levelFail se debería aumentar:

    if (lives <= 0) { level = 0; lives = 3; clearInterval(timeInterval); timeStart = undefined; }

    Para evitar una memory leak.

      Oscar Israel Román Quispe

      Oscar Israel Román Quispe

      student•
      hace 2 años

      Muy bien. Tu aporte sirve para evitar que el contador siga contando cuando el jugador gane los 3 mapas luego de reiniciado los mapas (muerto 3 veces).

    Mauricio Combariza

    Mauricio Combariza

    student•
    hace 2 años

    La variable fecha incluye el tiempo en milisegundos por lo que una diferencia entre la fecha en que inicio y en la que termino, puede ser la medida de tiempo.

    // Al iniciar el juego, se guarda el tiempo actual startTime = new Date();

    Esta se coloca en movePlayer cuando sale de O, y esta sería la función de winLevel:

    function winLevel() { const endTime = new Date(); const elapsedSeconds = Math.floor((endTime.getTime() - (startTime as Date).getTime()) / 1000); console.log('Ganaste eeee'); console.log('Tiempo transcurrido:', elapsedSeconds, 'segundos'); if (level >= 0 && level < maps.length -1) { level += 1 mapaActual = [] startGame() } else { console.error('Fin del juego Ganaste!!'); } }
    David Alvarez

    David Alvarez

    student•
    hace 3 años

    Para insertar emojies usar tecla de Windows y .

    Jonathan Meixueiro

    Jonathan Meixueiro

    student•
    hace 3 años

    Reinventando la rueda para formatear el timer 😅

    function showTime() { const msToSec = (Date.now() - timeStart) / 1000; const milliseconds = (String(msToSec - Math.floor(msToSec)).split('.')[1]).substring(0,2); const milliInterval = Date.now() - timeStart; let seconds = Math.floor(milliInterval / 1000); let minutes = Math.floor(seconds / 60); seconds = (seconds % 60) < 10 ? `0${seconds % 60}` : seconds % 60; minutes = (minutes % 60) < 10 ? `0${minutes % 60}` : minutes % 60; spanTime.innerHTML = `${minutes}:${seconds}:${milliseconds}`; }
    Miguel Enrique Velásquez Millán

    Miguel Enrique Velásquez Millán

    student•
    hace 3 años

    ¿Hay alguna razón especial por la que usamos Date.now()? 🤔. · Lo pregunto porque pienso que quizás sería mucho más sencillo contabilizar el tiempo de los jugadores directamente con el setInterval en vez de estar usando el Date.now(), je je.

      Juan Castro

      Juan Castro

      teacher•
      hace 3 años

      ¿Cómo lo harías con setInterval? :o

      Miguel Enrique Velásquez Millán

      Miguel Enrique Velásquez Millán

      student•
      hace 3 años

      Así~

      let totalGameTime = 0; let currentTimer = null; const timeShown = document.querySelector("#time"); function startTimer() { currentTimer = setInterval( () => { totalGameTime++; timeShown.innerText = totalGameTime; }, 1000 ); }

      Pienso que de esta forma tendríamos un contador que muestra en pantalla el tiempo que ha transcurrido de la partida actual solo usando el setInterval, je je. · ¿El Date.now() tiene alguna cosita especial que lo haga más eficiente o algo así? Yo en mi código usé este forma ya que me parece más sencillita, je je. Incluso luego le di un formato al totalGameTime con otra función para que se viera más bonito~

    Alejandro Ramos

    Alejandro Ramos

    student•
    hace 3 años

    Y como le damo formato al tiempo ;_;

      Oscar Gutiérrez

      Oscar Gutiérrez

      student•
      hace 2 años

      Depende del tipo de formato que quieras darle. Por ejemplo si quieres que se muestre los segundos solamente, podrías utilizar la siguiente sintaxis:

      spanTime.innerHTML = ((Date.now() - timeStart) / 1000).toFixed(0);
    Antonio Mateos Mariscal

    Antonio Mateos Mariscal

    student•
    hace 2 años

    Para añadir mayor dificultad al juego, en lugar de crear un cronómetro, he decidido poner un temporizador en el que el tiempo vaya hacia atrás y cuando llegue a 0 el jugador pierda la partida.

    Para ello, he creado las variables:

    let totalTime; let timeInterval;

    He añadido el siguiente condicional dentro de la función startGame:

    if (!timeInterval) { timeInterval = setInterval(showTime, 100); }

    Y he creado la siguiente función, en la que establezco el tiempo inicial multiplicando el número total de mapas por 5 segundos cada uno, y posteriormente se van restando 10 al tiempo total cada 10 milisegundos hasta llegar a 0, momento en el que limpio el canvas con clearRect y reinicio los valores de la posición del jugador, del tiempo total, el nivel y el número de vidas:

    function showTime() { if (!totalTime) { totalTime = maps.length * 500; } else { if (totalTime > 10) { totalTime -= 10; } else { game.clearRect(0, 0, canvasSize, canvasSize); playerPosition.col = undefined; playerPosition.row = undefined; totalTime = null; level = 0; lives = 3; startGame(); } } spanTime.innerText = totalTime; }
    Raúl Adolfo Sánchez Rodríguez

    Raúl Adolfo Sánchez Rodríguez

    student•
    hace 2 años

    Contador de tiempo utilizando ++setInterval++ y ++clearInterval++

    1. Resultado
      _
    2. Paso a paso
      Mejora-1.png
      Mejora-2.png
      Mejora-3.png
      Mejora-4.png
      Mejora-5.png
      Mejora-6.png
      Mejora-7.png
      Mejora-8.png
      Mejora-9.png
      Mejora-10.png
      Mejora-11.png
      Mejora-12.png
      Mejora-13.png
      Mejora-14.png
      Mejora-15.png
      Mejora-16.png
      Mejora-17.png
      Mejora-18.png

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads