CursosEmpresasBlogLiveConfPrecios

Contenido del curso

Introducción

  • 1
    Programemos un juego con JavaScript

    Programemos un juego con JavaScript

    17:13 min

Canvas

  • 2
    ¿Qué es canvas en JavaScript?

    ¿Qué es canvas en JavaScript?

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

    Tamaño del canvas y sus elementos

    17:37 min
  • 4
    Canvas responsive

    Canvas responsive

    12:37 min

Mapa del juego

  • 5
    ¿Qué es un array bidimensional?

    ¿Qué es un array bidimensional?

    05:48 min
  • 6
    Arreglos multidimensionales en JavaScript

    Arreglos multidimensionales en JavaScript

    23:38 min
  • 7
    Refactor del mapa de juego

    Refactor del mapa de juego

    20:48 min

Movimientos del jugador

  • 8
    Eventos y botones

    Eventos y botones

    14:14 min
  • 9
    Objeto playerPosition

    Objeto playerPosition

    11:34 min
  • 10
    Limpieza de movimientos

    Limpieza de movimientos

    09:53 min
  • 11
    No te salgas del mapa

    No te salgas del mapa

    11:15 min

Colisiones

  • 12
    Detectando colisiones fijas

    Detectando colisiones fijas

    13:29 min
  • 13
    Detectando colisiones con arrays

    Detectando colisiones con arrays

    14:11 min
  • 14
    Victoria: subiendo de nivel

    Victoria: subiendo de nivel

    07:50 min
  • 15
    Derrota: perdiendo vidas

    Derrota: perdiendo vidas

    11:45 min

Bonus: adictividad

  • 16
    Sistema de vidas y corazones

    Sistema de vidas y corazones

    13:02 min
  • 17
    Sistema de tiempo y puntajes

    Sistema de tiempo y puntajes

    19:30 min
  • 18
    ¿Qué es localStorage?

    ¿Qué es localStorage?

    07:33 min
  • 19
    Guardando records del jugador

    Guardando records del jugador

    18:35 min

Deploy

  • 20
    Depurando errores del juego

    Depurando errores del juego

    23:16 min
  • 21
    Desplegando el juego a GitHub Pages

    Desplegando el juego a GitHub Pages

    07:39 min

Próximos pasos

  • 22
    Reto: reinicio del juego

    Reto: reinicio del juego

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

    Reto: timeouts de victoria o derrota

    Viendo ahora
  • 24
    ¿Quieres un simulador laboral?

    ¿Quieres un simulador laboral?

    06:53 min
Tomar examen

Reto: timeouts de victoria o derrota

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

      Comentarios

      Axel Enrique Galeed Gutierrez

      Axel Enrique Galeed Gutierrez

      student
      hace 4 años
        Juan Castro

        Juan Castro

        teacher
        hace 4 años
      Manuel Araujo

      Manuel Araujo

      student
      hace 4 años
      Sergio Javier Lopez Olivera

      Sergio Javier Lopez Olivera

      student
      hace 4 años
        Jose Carlos Espinosa Espinosa

        Jose Carlos Espinosa Espinosa

        student
        hace 4 años
        Sergio Javier Lopez Olivera

        Sergio Javier Lopez Olivera

        student
        hace 3 años
      José Fernando Fuentes Roa

      José Fernando Fuentes Roa

      student
      hace 3 años
      Elío Diez

      Elío Diez

      student
      hace 3 años
      Eder Raúl Abarca Raviela

      Eder Raúl Abarca Raviela

      student
      hace 4 años
      Cristian Paiva

      Cristian Paiva

      student
      hace 3 años
      Matias Ezequiel Rivero

      Matias Ezequiel Rivero

      student
      hace 3 años
      Orlando Rodriguez

      Orlando Rodriguez

      student
      hace 4 años
      Leonardo Garrido

      Leonardo Garrido

      student
      hace 3 años
      Laura Roa

      Laura Roa

      student
      hace 4 años
        Juan Castro

        Juan Castro

        teacher
        hace 4 años
        Laura Roa

        Laura Roa

        student
        hace 4 años
      Yhoshua Bernal

      Yhoshua Bernal

      student
      hace 2 años
      Harold Zurita Simon

      Harold Zurita Simon

      student
      hace 3 años
      Raúl Adolfo Sánchez Rodríguez

      Raúl Adolfo Sánchez Rodríguez

      student
      hace 3 años
      Jose Angel Esquivel Cisneros

      Jose Angel Esquivel Cisneros

      student
      hace 3 años
      Raúl Adolfo Sánchez Rodríguez

      Raúl Adolfo Sánchez Rodríguez

      student
      hace 3 años
      Manuel Andres García Vera

      Manuel Andres García Vera

      student
      hace 3 años
        Stivenson David Mejia Palacios

        Stivenson David Mejia Palacios

        student
        hace 3 años
      Kevin Cantú Gómez

      Kevin Cantú Gómez

      student
      hace 3 años
      Alejandro Ramos

      Alejandro Ramos

      student
      hace 3 años
        Alejandro Ramos

        Alejandro Ramos

        student
        hace 3 años
      Alejandro Ramos

      Alejandro Ramos

      student
      hace 3 años

      Les comparto, el resultado final de mi juego. 😄 Todo feedback es bienvenido. Repositorio de GitHub. Link del juego.

      Dude, qué buen proyecto. Te quedó muy, muy genial tu personalización. Las instrucciones al principio :ok_hand:.

      Creo una función showCollision que limpie todo el canvas y muestre un mensaje, cuyo contenido depende de si el jugador aún tiene vidas o no.

      function showCollision() { game.clearRect(0, 0, canvasSize, canvasSize); game.font = '10px Verdana'; game.textAlign = 'center'; if(lives > 1) { game.fillText('PERDISTE UNA VIDA, VUELVE A INTENTARLO', canvasSize/2, canvasSize/2); } else { game.fillText('PERDISTE TODAS LAS VIDAS, VUELVE AL INICIO', canvasSize/2, canvasSize/2); } }

      Luego, dentor de la fiunción movePlayer, en el condicional donde se verifica si hubo colisión, agrego la función showCollision y establezco un setTimeout para que espere un tiempo antes de llamar a la función leverlLost (levelFail para el profesor)

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

      Después de muchos intentos y ver a otros compañeros así pude resolver el reto de las colisiones y que se mostrase donde había chocado:

      else if (bombCollision) { showCollision(); setTimeout(gameLose, 1000); }

      Dentro de la función de movePlayer en el condicional pude introducir esta función con el setTimeout .

      function showCollision(){ firePos.x = playerPos.x; firePos.y = playerPos.y; console.log(firePos.x, firePos.y); fireExp(); } function fireExp(){ game.fillText(emojis['BOMB_COLLISION'], firePos.x, firePos.y) }

      Arriba está la función que se llama en movePlayer y esta a su vez llama a otra que ubica en las posiciones del jugador el emoji del fuego, con ello mostrando donde se chocó el jugador.

      Una pregunta lo intente hacer como tu lo hiciste, pero hace la animación de la explosión pero encima de la bomba y debajo del jugador, te pasa lo mismo o te paso, sabes como resolverlo.

      @jose-carlos-espinosa-espinosa saludos, si me ocurría, aunque en este momento no recuerdo como lo resolví, eso creo es debido a que al momento de la colisión se ejecuta la función de showCollision() y luego la de setTimeOut con game lose:

      function movePlayer() { game.fillText(emojis['PLAYER'], playerPos.x, playerPos.y); const bombCollision = bombsPos.find( bomb => { const bombPosX = bomb.x.toFixed(0) == playerPos.x.toFixed(0); const bombPosY = bomb.y.toFixed(0) == playerPos.y.toFixed(0); //this two values return booleans return bombPosX && bombPosY; //using return at the end with "&&" operator will help us to have as a value the coincidential positions }) if (playerPos.x == giftPos.x && playerPos.y == giftPos.y){ gameWin(); } else if (bombCollision) { showCollision(); setTimeout(gameLose, 1000); } }//esto asociado al movimiento del jugador function showCollision(){ firePos.x = playerPos.x; firePos.y = playerPos.y; console.log(firePos.x, firePos.y); fireExp(); } function fireExp(){ game.fillText(emojis['BOMB_COLLISION'], firePos.x, firePos.y) } function gameLose() { lives--; playerPos.x = undefined; playerPos.y = undefined; indicator = true; if (lives <= 0) { level = 0; lives = 3; timeStart = undefined; startGame(); } else { // game.fillText(emojis['BOMB_COLLISION'], playerPos.x, playerPos.y); startGame(); } }

      Hola a todos

      Acá les comparto algunas de las mejoras que le realicé al juego.

      FireShot Capture 069 - Platzriv - Jueguito online de carreras y calaveras - joffur.github.io.png
      FireShot Capture 068 - Platzriv - Jueguito online de carreras y calaveras - joffur.github.io.png
      FireShot Capture 067 - Platzriv - Jueguito online de carreras y calaveras - joffur.github.io.png
      FireShot Capture 066 - Platzriv - Jueguito online de carreras y calaveras - joffur.github.io.png

      Space Odisey.png

      Aquí mi versión del juego. Todavía no he podido resolver el último reto sin que se rompa todo pero el mapa tiene algunos atajos y los encuentros con alienígenas se premian con vidas ;-).

      Aquí mi repositorio: https://github.com/ElioDiez/Curso-Videojuego-en-JavaScript

      Y aquí el juego: https://eliodiez.github.io/Curso-Videojuego-en-JavaScript/

      ¡Seguiré intentándolo!

      Implemente mensajes en el canvas cada vez que chocas, pierdes o ganas:

      Captura de pantalla de 2022-11-06 18-31-02.png
      Captura de pantalla de 2022-11-06 18-31-29.png
      Captura de pantalla de 2022-11-06 18-30-16.png

      GitHub: https://github.com/RedCode-123/Videojuego_JavaScript_2022

      Acá dejo mi aporte. Le agregue un par de pantallas extras como por ejemplo el conteo hacia atrás antes de comenzar el game, como también una ventana de Game over y cuando ganas el game. Repo: Juego:

      Hola comparto el proyecto. De los retos, el que más me costo es el de posicionar el jugador en el lugar correcto al hacer resize del HTML. mhgame web del proyecto repo en GitHub

      Muchas gracias. Excelente curso.

      Se me ocurrio usar una clase que nombro "inactive" en CSS le agrego display:none. En mi js luego, en el codigo de las colisiones agrego.

      const boom = setInterval(() => {canvas.classList.toggle('inactive'); game.fillText(emojis['BOMB_COLLISION'], collision.x, collision.y)}, 70); console.warn('BOOOM'); setTimeout(() => {clearInterval(boom); startGame() }, 700);

      El canvas desaparece y aparece . Pruébalo has una colision. https://orlando0x.github.io/videojuego-con-javascript/

      Esta fue mi resolución en base a ver como usar el set interval en los comentarios.

      if (enemyCollision) { showColision(); //espera 1 segundo para empezar la funciona level fail// setTimeout (levelFail,1000); }

      para que el fuego aparezca y no se vea la calavera hice lo siguiente.

      function showColision() { game.fillText (emojis['BOMB_COLLISION'], playerPosition.x, playerPosition.y); playerPosition.x = undefined; playerPosition.y = undefined; console.log ('choque'); }

      Hola! estaba todo bien, puse el toFixed() y me funciono bien con los mapas que ya teniamos hechos, pero cuando intente agregar un mapa por mi parte, fallo y tengo otra vez ese error. Ya he mirado mucho y no se que pueda estar fallando. Agradeceria si tienen alguna sugerencia. Este es mi repositorio https://github.com/laulexa/video-game-project--learningJS

      https://laulexa.github.io/video-game-project--learningJS/https://laulexa.github.io/video-game-project--learningJS/

      si.JPG

      Veo que hiciste un nuevo commit después de agregar los nuevos mapas y que el jugo ya funciona otra vez: https://laulexa.github.io/video-game-project--learningJS/

      ¿Te late si nos cuentas cuál era eel error y cómo lo solucionaste? :D

      Hola profe! No de hecho no lo habia solucionado :( , vi tu comentario y en mi computador aun habian errores. Trate de solucionarlo y di con una solucion que no estoy segura si sea tan buena pero hice todo tipo de pruebas y no salio ese error. Lo que hice fue restarle 1 a element size y multiplicar window.innerheight y window.innerWidth por 0.6:

      function setCanvasSize() { if (window.innerHeight > window.innerWidth) { canvasSize = fixNumber(window.innerWidth * 0.6); } else { canvasSize = fixNumber(window.innerHeight * 0.6) } canvasSize = Number(canvasSize.toFixed(0)); canvas.setAttribute('width', fixNumber(canvasSize)); canvas.setAttribute('height', fixNumber(canvasSize)); elementsSize = fixNumber(canvasSize / 10) -1; playerPosition.x = undefined; playerPosition.y = undefined; restartGame(); }

      Y finalmente en la funcion startGame(), cambie la siguiente linea y en vez de 1 le agregue un 1.2

      const posX = fixNumber(elementsSize * (colI + 1.2)); const posY = fixNumber(elementsSize * (rowI + 1));

      Seguie trabajando en ello porque antes de publicar este post vi que una pantalla fallo :( Hice la ultima prueba en un mac y en pantalla completa se rompio el ultimo mapa en las cajas de la parte derecha. este es mi repositorio seguire trabajando en el proyecto y no se si otras cosas cambien despues. https://github.com/laulexa/video-game-project--learningJS

      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 restartButton = document.querySelector ('#restart'); const deleteRecord = document.querySelector('#delete-record'); const spanLives = document.querySelector('#lives'); const spanTime = document.querySelector('#time'); const spanRecord = document.querySelector('#record'); const pResult = document.querySelector('#result'); const countdownText = document.querySelector('.countdown'); let canvasSize; let elementsSize; let level = 0; let lives = 3; let timeStart; let playerTime; 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 = fixNumber(window.innerWidth * 0.6); } else { canvasSize = fixNumber(window.innerHeight * 0.6) } canvasSize = Number(canvasSize.toFixed(0)); canvas.setAttribute('width', fixNumber(canvasSize)); canvas.setAttribute('height', fixNumber(canvasSize)); elementsSize = fixNumber(canvasSize / 10) -1; playerPosition.x = undefined; playerPosition.y = undefined; //countdown() restartGame(); } function startGame() { console.log({ canvasSize, elementsSize }); console.log(window.innerWidth, window.innerHeight); game.font = fixNumber(elementsSize) + 'px Verdana'; game.textAlign = 'end'; const map = maps[level]; // console.log(map) 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.2)); 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'], fixNumber(playerPosition.x), fixNumber(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('¡Game Finished!'); 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() { if(timeStart == undefined) { spanTime.innerHTML = 0; } else { //spanTime.innerHTML = Date.now() - timeStart; spanTime.innerHTML = ((Date.now() - timeStart)/1000).toFixed(2) + " S"; } } function showRecord() { spanRecord.innerHTML = localStorage.getItem('record_time') + ' S'; } //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); deleteRecord.addEventListener('click', deleteRecords); upButton.addEventListener('click', moveUp); rightButton.addEventListener('click', moveRight); leftButton.addEventListener('click', moveLeft); downButton.addEventListener('click', moveDown); restartButton.addEventListener('click', restartGame); 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 deleteRecords() { console.log('record deleted') localStorage.removeItem('record_time'); spanRecord.innerText = '0' } 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(); } } function countdown() { console.log("counting down"); let numberCount = 3 function count () { if (numberCount > 0) { countdownText.innerHTML = numberCount; numberCount--; setTimeout(count, 700); } else { countdownText.innerHTML ='Go!'; } } count () startGame() } function restartGame() { console.log('restart game'); level = 0; lives = 3; pResult.innerHTML = ''; playerPosition.x = undefined; playerPosition.y = undefined; setTimeout(startGame, 3000); countdown() timeStart= undefined; } function victory() { } function collision() { // setTimeout() }

      maps.js

      /* * Reglas: * El final de cada nivel debe ser el inicio del siguiente */ // const img1 = document.createElement("img"); // img1.src = "./myDog.png"; const emojis = { '-': ' ', 'O': '🚪', 'X': '📦', 'I': '🧀', 'PLAYER':'🐹', 'BOMB_COLLISION': '🔥', 'GAME_OVER': '👎', 'W': '🏆', 'HEART': '❤️', 'S': '🌟' }; const maps = []; maps.push(` IXXXXXXXXX -XXXXXXXXX -XXXXXXXXX -XXXXXXXXX -XXXXXXXXX -XXXXXXXXX -XXXXXXXXX -XXXXXXXXX -XXXXXXXXX OXXXXXXXXX `); maps.push(` O--XXXXXXX X--XXXXXXX XX----XXXX X--XX-XXXX X-XXX--XXX X-XXXX-XXX XX--XX--XX XX--XXX-XX XXXX---IXX XXXXXXXXXX `); maps.push(` I-----XXXX XXXXX-XXXX XX----XXXX XX-XXXXXXX XX-----XXX XXXXXX-XXX XX-----XXX XX-XXXXXXX XX-----OXX XXXXXXXXXX `); maps.push(` O--------X XXXXXXXX-X XXXX---X-X XXXX-X---X XXXX-XXXXX XXXX-----X XXXXXXXX-X XXX---XX-X ----X-XX-X IXXXX----X `); maps.push(` WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW SWWWWWWWWW `);

      styles.css

      /* font-family: 'RocknRoll One', sans-serif; */ body { background-color: indigo; color: #fff; font-family: 'RocknRoll One', sans-serif;; margin: 0; padding: 0; } .game-container { display: flex; align-items: center; flex-direction: column; justify-content: space-between; height: 100vh; width: 100vw; } canvas { border: 4px solid #ff6600; border-radius: 8px; background-color: #feff9d; } .winner-message { align-items: center; background-color: #82B700; color: rgb(255, 255, 255); display: flex; font-size: 20px; font-weight: bold; justify-content: center; margin-top: 10px; height: 200px; width: 300px; } .loser-message { align-items: center; background-color: #b72500; color: rgb(255, 255, 255); display: flex; font-size: 20px; font-weight: bold; justify-content: center; margin-top: 10px; height: 200px; width: 300px; } .final-message { place-items: center; } .btns { display: flex; justify-content: center; flex-wrap: wrap; margin: 0 auto; width: 100%; } button { background-color: #fdef05; border-radius: 8px; border-color: #ff6600; font-family: inherit; margin: 0; padding: 5px 20px; width: 100px; } button:not(:last-child) { margin-right: 10px; } .restart-delete-btn { background-color: #82B700; border-color: #ff6600; font-weight: bold; font-size: 10px; padding: 5px 0 5px; height: 50px; } .messages { display: flex; flex-wrap: wrap; margin: 10px auto; width: 80%; max-width: 460px; } .stats { display: block; margin: 0; width: 100%; } .countdown { text-align: center; font-size: 30px; } .inactive { display: none; } @media (max-width: 440px) { button { margin: 5px 0 5px; padding: 10px 20px; } #up, #down { margin-left: 100%; margin-right: 100%; } #restart-delete-btn { margin: 15px 0 15px;} .messages {text-align: center;} }

      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="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=RocknRoll+One&display=swap" rel="stylesheet"> <link rel="stylesheet" href="./styles.css"> <title>VideoGame Project</title> </head> <body> <div class="game-container"> <canvas id="game"></canvas> <div class="winner-message inactive"> <p class="final-message">You Win!</p> </div> <div class="loser-message inactive"> <p class="final-message">Game Over</p> </div> <p class="countdown"></p> <div class="btns"> <button id="up">Up</button> <button id="left">Left</button> <button id="right">Right</button> <button id="down">Down</button> <button id="restart" class="restart-delete-btn">Restart</button> <button id="delete-record" class="restart-delete-btn">Delete Record</button> </div> <div class="messages"> <p class="stats">Lives: <span id="lives"></span></p> <p class="stats">Time ⏰: <span id="time"></span></p> <p class="stats">Record 🏁: <span id="record"></span></p> <p class="stats" id="result"></p> </div> </div> <script src="./maps.js"></script> <script src="./game.js"></script> </body> </html>

      HIce algunos cambios interesantes que si me retaron un poco link al juego:

      github:

      Hola 🙋‍♂️, les comparto mi proyecto: Dungeon Magician

      Beta1.PNG
      Inspirado en el juego del Buscaminas y un rpg 2d tradicional, Dungeon Magician trata de un mago en busca de gemas encantadas.
      Beta2.PNG
      Distintas trampas mágicas se encuentran escondidas en el mapa, tienes la habilidad de prever el peligro en un radio de 1 cuadro a tu alrededor si la situación así lo requiera. . Esquiva las minas con tu intuición, perspicacia y cumple con tu destino 🧙‍♂️🌟.

      Primera versión

      🎮Taller: Crea tu primer videojuego -Mi proyecto🎮

      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:

      • Incorporación de fuego 🔥 en las colisiones contra las bombas

      • Contador de tiempo ⏱ en segundos + 2 decimales

      • Tarjetas interactivas al perder, ganar sin récord y ganar con nuevo récord

      • Pantalla de inicio del juego 🤠con enlaces a redes sociales

      • Animación al ganar un nivel y perder vidas 🟠🟡🟢🔵🔴

      • Pantalla para registrar tus mejores récords.🎖🎖

        GAME1.png
        GAME2.png
        GAME3.png
        GAME4.png
        GAME5.png
        GAME6.png
        GAME7.png
        GAME8.png


      ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐


      📌Prueba la demo del juego 🎮

      📌Échale un vistazo al repositorio de GitHub

      🎮Deploy de 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:

      FuncionalidadTutorial
      Incorporación de fuego 🔥 en las colisiones contra las bombasVer
      Contador de tiempo ⏱ en segundos + 2 decimalesVer
      Tarjetas interactivas al perder, ganar sin récord y ganar con nuevo récordVer
      Pantalla de inicio del juego 🤠Ver
      Animación al ganar un nivel 🟠🟡🟢🔵🔴Ver

      📌Prueba la demo del juego 🎮 ⭐⭐⭐⭐⭐

      📌Échale un vistazo al repositorio de GitHub

      📌Échale un vistazo al Taller de Platzi

      Dejo mi jueguito después de tomar características como modelos de algunos compañeros logre terminar los retos

      Captura de pantalla (1277).png

      ++Dejo mi juego desplegado++ https://manuel15939.github.io/taller-practico-javascript-videogame/ ++Mi repositorio++ https://github.com/manuel15939/taller-practico-javascript-videogame

      creo que tienes bugs Manuel, en la resolución actual que tengo en el navegador no puedo acceder al regalo e intente ir a la derecha pero la bomba no explotó no me devolvió al inicio.

      Captura de pantalla (253).png

      Cuando haya una colisión entre la calaverita y una bomba lo cambio por una explosión y uso el setTimeout para después retomar el punto de partida inicial del mapa en el que nos encontremos

      if(giftCollisionXY){ levelUp(); }else if(bombaCollisionXY){ console.log('Tocaste una bomba'); game.fillText(emojis['EXPLOTION'],playerPosition.x,playerPosition.y); setTimeout(gameFailed,1000); }else{ game.fillText(emojis['PLAYER'],playerPosition.x,playerPosition.y); }
      Captura de pantalla 2023-04-19 151758.png
      Captura de pantalla 2023-04-19 151848.png
      Captura de pantalla 2023-04-19 151918.png
        Después de muchos dolores de cabeza, logré hacer:
      1. Botón de reiniciar el juego sin reiniciar la página
      2. Botón para borrar el record máximo
      3. Presentar el intervalo en formato de tiempo
      4. Una pantalla de inicio y de cierre
      5. El canvas ahora se ajusta al tamaño que se le dará por CSS (arrastrando consigo a ElementSize)
      6. Transiciones entre las distintas páginas (3 en total xd)
      7. Algunas correcciones de errores
      8. Ajustes en CSS para el tamaño de los botones, del canvas y demás, incluso dependiendo de la orientación del dispositivo (y esta en responsive :D).
      9. El reloj solo empezará cuando se presione uno de los botones.

        Si bien hay bastantes cosas para mejorar o añadir a mi código, por ahora mi problema es hacer que las interfaces de los navegadores en los móviles no interfieran con el contenido de la página tapándolo xd

      Creo firmemente que hay mucho por mejorar en el aspecto de diseño :p

      EN fin, link del juego :D ↓ juego

      Hay muchas ideas interesantes en la sección de comentarios, haré mi idea, pero aprenderá de las demás!