Yo utilice el metodo repeat() de los strings ya que cada emoji es un string
function showLives() {
spanLives.innerHTML = emojis["HEART"].repeat(lives)
}
Introducción
Programemos un juego con JavaScript
Canvas
¿Qué es canvas en JavaScript?
Tamaño del canvas y sus elementos
Canvas responsive
Mapa del juego
¿Qué es un array bidimensional?
Arreglos multidimensionales en JavaScript
Refactor del mapa de juego
Movimientos del jugador
Eventos y botones
Objeto playerPosition
Limpieza de movimientos
No te salgas del mapa
Colisiones
Detectando colisiones fijas
Detectando colisiones con arrays
Victoria: subiendo de nivel
Derrota: perdiendo vidas
Bonus: adictividad
Sistema de vidas y corazones
Sistema de tiempo y puntajes
¿Qué es localStorage?
Guardando records del jugador
Deploy
Depurando errores del juego
Desplegando el juego a GitHub Pages
Próximos pasos
Reto: reinicio del juego
Reto: timeouts de victoria o derrota
¿Quieres un simulador laboral?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 44
Preguntas 1
Yo utilice el metodo repeat() de los strings ya que cada emoji es un string
function showLives() {
spanLives.innerHTML = emojis["HEART"].repeat(lives)
}
Si se coloca solo heartsArray, te saldrá con comas. Lo que hice para solucionar eso fue utilizar join()
:
spanLives.innerHTML = hearts.join('');
Te dejo el Emoji HEART: “❤”,
o igual lo puedes obtener en Visual Studio Code presionando las teclas Window + .
Window + punto
Mi humilde forma de realizar el reto indicado fue utilizar la siguiente opción.
function showLives() {
const heartsArray = Array(lives).fill(emojis['HEART']);
spanLives.innerHTML = '';
for (heart of heartsArray) {
spanLives.innerHTML += heart;
}
}
Yo buscando el error por todos lados sin saber que era y despues de un rato me di cuenta que el archivo maps que yo habia copiado al inicio del curso no tenia el emoji del corazón >:V
Lo que hice fue imprimir lo que fuera que tuviera el array heartsArray en en innerHTML de spanLives (Siempre tendra el numero de corazones igual al numero de vidas que nos queden) concatenandolo con el metodo join("").
spanLives.innerHTML=heartsArray.join("")
Yo lo pensé así
function showLives() {
spanLives.innerHTML = Array(lives).fill(emojis['HEART']).join('');
}
Para el reto de poner los corazones lo realice con un reduce
const showLives=()=>{
const heartsArray= Array(lives).fill(emojis['HEART']);
spanLives.innerHTML=heartsArray.reduce((string, heart)=>string+=heart);
}
Yo la solución que pensé era un repeat de lives, así se ahorra más código y en lo personal es más fácil de entender
function showLives() {
spanLives.innerHTML = emojis["HEART"].repeat(lives)
}
En otros cursos dijeron que el usar innerHTML era mala practica debido a que si eso estaba al alcance de los usuarios se podía usar de mala forma.
Así que opté por hacerlo con .textContent, también use el .join("") para eliminar las comas:
function showLives (){
let heartsArray = Array(lives).fill(emojis["HEART"])
spanLives.textContent = heartsArray.join("")
}
De esta forma renderizo los valores de un array
yo le agregué esta pavadita para que se rompa el corazón cuando perdemos una vida
function showLives() {
livesCounter.innerText =
emojis['HEART'].repeat(lives) + emojis['EMPTY_HEART'].repeat(3 - lives);
}
function showLifes(){
//crear un array
const heartsArray=Array(lives).fill(emojis['HEART']);
spanLives.innerHTML = heartsArray.join('');
}
Yo solo imprimí tal cual la variable heartsLives, y le agregé el método join(’ ') (gracias a los aportes de otros compañeros), para separe cada corazón con nada, a la hora de mostrarlo en el HTML.
Funciona para mostrar la cantidad de vidas que reciba el Array con la variable ‘lives’, que se modifica dependiendo de las colisiones que tenga el jugador.
mi solucion
function showLives (){
const heartArray = Array(lives).fill(emojis['HEART']);
console.log(heartArray);
spanLives.innerHTML = '';
for (let i = 0; i < heartArray.length; i++) {
spanLives.innerHTML += heartArray[i]
}
}```
Mi solucion fue algo mas simple. aunque menos escala
<code>
//HTML
<p>Vidas = 💙💙💙</p>
// JS
function levelFail(){
if (lives <= 1) {
location.reload();
}
lives--;
if (lives == 2) {
parrafo.innerText = `Vidas = 💙💙`
}else if(lives == 1){
parrafo.innerText = `Vidas = 💙`
}
console.log(lives);
playerPosition.x = undefined;
playerPosition.y = undefined;
startGame();
}
Yo utilizé el meétodo repeat de String:
vidas.innerHTML = emojis['HEART'].repeat(lives)
Yo ser fan de forEach :3
heartsArray.forEach(heart => {
spanLives.append(heart);
})
heartArray.forEach(heart =>{
spanLives.innerHTML += heart;
})
Hola!
Para no tener que renderizar nuevamente los corazones lo resolví de esta manera:
function showLives() {
const heartsArray = Array(lives).fill(emojis['HEART'])
console.log(heartsArray)
countLives.innerHTML = `${heartsArray.join("")}`;
}
function showLives() {
const heartArray =
Array(lives).fill(emojis[‘HEART’]);
console.log(heartArray)
spanLives.innerHTML = heartArray;
}
a mi spanLives coloque para que fuera = a mi variable heartArray y funciono correctamente.
alguien puede decirme que esta mal en mi codigo ? se rompio y ya no sirve cuando esta en tamaño desktop
<!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">
<title>Platzriv - Jueguito online de carreras y calaveras</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="game-container">
<canvas id="game"></canvas>
<div class="btns">
<button id="up">Arriba</button>
<button id="left">Izquierda</button>
<button id="right">Derecha</button>
<button id="down">Abajo</button>
</div>
<div class="messages">
<p>Vidas: <span id="lives"></span></p>
</div>
</div>
<script src="./maps.js"></script>
<script src="./game.js"></script>
</body>
</html>
const canvas = document.querySelector("#game");
const game = canvas.getContext("2d");
const btnUp = document.querySelector("#up");
const btnLeft = document.querySelector("#left");
const btnRight = document.querySelector("#right");
const btnDown = document.querySelector("#down");
let canvasSize;
let elementsSize;
let level = 0;
let lives = 3;
const playerPosition = {
x: undefined ,
y: undefined ,
};
const giftPosition = {
x: undefined ,
y: undefined ,
};
let enemyPositions = [];
window.addEventListener("load", setCanvasSize);
window.addEventListener("resize", setCanvasSize);
function setCanvasSize(){
if(window.innerHeight > window.innerWidth){
canvasSize = window.innerWidth * 0.8;
} else{
canvasSize = window.innerHeight * 0.8;
}
canvas.setAttribute("width", canvasSize);
canvas.setAttribute("height", canvasSize);
elementsSize = canvasSize / 10;
startGame();
}
function startGame(){
console.log({canvasSize, elementsSize});
game.font = elementsSize + "px Verdana";
game.textAlign = "end";
const map = maps[level];
if(!map){
gameWin();
return;
}
const mapRows = map.trim().split("\n");
const mapsRowCols = mapRows.map(row => row.trim().split(""));
/* console.log({map, mapRows, mapsRowCols}); */
enemyPositions = [];
game.clearRect(0,0,canvasSize,canvasSize);
mapsRowCols.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(!playerPosition.x && !playerPosition.y){
playerPosition.x = posX;
playerPosition.y = posY;
console.log({playerPosition});
}
} else if(col == "I"){
giftPosition.x = posX;
giftPosition.y = posY;
} else if(col == "X"){
enemyPositions.push({
x: posX,
y: posY,
})
}
game.fillText(emoji, posX, posY);
/* */
});
});
movePlayer();
/* for (let row = 1; row <= 10; row++) {
for (let col = 1; col <= 10; col++) {
game.fillText(emojis[mapsRowCols[row - 1][col - 1]], elementsSize * col, elementsSize * row);
}
} */
// window.innerHeight
// window.inner
// game.fillRect(0,0,100,100);
// game.clearRect(50,50,50,50);
// game.clearRect();
// game.clearRect(0,0,50,50);
// game.font = "25px Verdana";
// game.fillStyle = "purple";
// game.textAlign = "center";
// game.fillText("Platzi", 25 , 25);
}
function movePlayer(){
const giftColisionX = playerPosition.x.toFixed(2) == giftPosition.x.toFixed(2);
const giftColisionY = playerPosition.y.toFixed(2) == giftPosition.y.toFixed(2);
const giftColision = giftColisionX && giftColisionY;
if(giftColision){
levelWin();
}
const enemyColision = enemyPositions.find(enemy => {
const enemyColisionX = enemy.x == playerPosition.x ;
const enemyColisionY = enemy.y == playerPosition.y ;
return enemyColisionX && enemyColisionY;
});
if(enemyColision){
levelFail();
}
game.fillText(emojis["PLAYER"] , playerPosition.x , playerPosition.y);
}
function levelWin(){
console.log("subiste de nivel");
level++;
startGame();
}
function levelFail(){
console.log("chocaste contra un enemigo");
lives--;
console.log(lives);
if(lives <= 0){
level = 0;
lives = 3;
}
playerPosition.x = undefined;
playerPosition.y = undefined;
startGame();
}
function gameWin(){
console.log("terminaste el juego!");
}
window.addEventListener("keydown", moveByKeys);
btnUp.addEventListener("click", moveUp);
btnLeft.addEventListener("click", moveLeft);
btnRight.addEventListener("click", moveRight);
btnDown.addEventListener("click", moveDown);
function moveByKeys(event){
if(event.key == "ArrowUp" || event.key == "w" || event.key == "W"){
moveUp();
} else if(event.key == "ArrowLeft" || event.key == "a" || event.key == "A"){
moveLeft();
} else if(event.key == "ArrowRight" || event.key == "d" || event.key == "D"){
moveRight();
} else if(event.key == "ArrowDown" || event.key == "s" || event.key == "S"){
moveDown();
}
}
function moveUp(){
console.log("me quiero mover hacia arriba");
if(playerPosition.y - elementsSize < elementsSize){
console.log("OUT");
} else{
playerPosition.y -= elementsSize;
startGame();
}
}
function moveLeft(){
console.log("me quiero mover hacia izquierda");
if(playerPosition.x - elementsSize < elementsSize){
console.log("OUT");
} else{
playerPosition.x -= elementsSize;
startGame();
}
}
function moveRight(){
console.log("me quiero mover hacia derecha");
if(playerPosition.x + elementsSize > canvasSize){
console.log("OUT");
} else{
playerPosition.x += elementsSize;
startGame();
}
}
function moveDown(){
console.log("me quiero mover hacia abajo");
if(playerPosition.y + elementsSize > canvasSize){
console.log("OUT");
} else{
playerPosition.y += elementsSize;
startGame();
}
}
Yo use un for y concatene los corazones en un String
function numberHearts(){
let hearts="";
for(let i=0; i< lives ; i++ ){
hearts = hearts + emojis["HEART"];
}
return hearts;
}
Bueno lo hice de otra forma, dentro de mi funcion starGame agregue
if (lives === 3){
livesHTML.innerText = 'Vidas: 💚💚💚';
}else if (lives === 2){
livesHTML.innerText = 'Vidas: 💚💚';
}else if (lives === 1){
livesHTML.innerText = 'Vidas: 💚';
}else {
livesHTML.innerText = 'GAME OVER';
level = 0;
lives = 3;
playerPosition.x = undefined;
playerPosition.y = undefined;
setTimeout(() => starGame(), 1000);
}
Como ven al final si ya no hay vidas, me saldra un mensaje diciendo Game Over, reinicia el level, me da las 3 vidas, reinicia posicion del jugador y un segundo despues comienza el juego de nuevo llamando la funcion starGame.
El método join() une todos los elementos de un array en una string y devuelve este string
Para mostrar el número de corazones, usé un ciclo for:
spanLives.innerHTML = "";
for(i=lives; i > 0; i--) {
spanLives.append(heartsArray[i-1]);
}
O un clico while:
spanLives.innerHTML = "";
var i = lives;
while(i>0) {
spanLives.append(heartsArray[i-1]);
i--;
}
Para tener todo más organizado, cree un objeto con los detalles del jugador, y también una función que lo renderiza
const playerDetails={
lives:3,
render: function(){
livesPlayers()
}
}
Y la función que creamos en la clase, la hice de esta manera, porque segun tengo entendido, innerHTML es una mala práctica, ya que puede literalmente ejecutar HTML, mientras innerText, solo mete texto.
También nos ahorramos el recorrido del arreglo de corazones, usando el join(""). Asi tenemos directo hecho texto, y no un arreglo
function livesPlayers() {
const lives = Array(playerDetails.lives).fill(emojis["heart"]).join("")
playerLives.innerText = lives
}
Y lo que más me gusta de mi código, es el cómo queda mi función de startGame()
function startGame() {
map.bombPosition = []
map.render()
playerDetails.render()
}
Comparto como va mi jueguito… 😃
Método .join( ) de los arrays
__
Método .fill( ) de los arrays
_
Mis sistema de vidas:
Resultado:
Pasos:
Siii… llegó el momento, me resolvió el conflicto…
.toFixed(3) jejejeje…
también funciona directo, solo que va con la coma (,)
Utilicé esta función, aunque los corazones están separados por comas.
function totalLives(){
const setLives = Array(lives).fill(emojis['HEART']);
spanLives.innerText = setLives;
};
Ps, así lo hice xd
function showstats(){
spanLives.innerText = (emojis["HEART"].repeat(lives)).toString();
spanLevel.innerText = (level + 1).toString();
}
Lo hice de la siguiente forma la función para mostrar los corazones:
function showLivesGame() {
const heartArr = Array(lives).fill(emojis['HEART']);
spanLives.innerHTML = heartArr.join('');
}
Yo use el método join para imprimir el total de vidas.
const totalVidas = Array(vidas).fill(emojis["HEARTH"]);
lives.innerHTML=totalVidas.join(" ");
Yo lo hice así. El método ‘join’ es para eliminar las comas que se imprimen para separar de cada corazón en nuestro html.
let lives = 3;
function showLive() {
const heartArray = Array(lives).fill(emojis['HEART']);
spanLive.innerHTML = heartArray.join('');
}
La forma de hacerlo con una sola linea que se me ocurrio seria esto al final de startGame()
document.getElementById('lives').innerHTML = (lives);
function print(){
livesContainer.innerHTML = '💖'.repeat(lives);
}
Yo lo hice de esta manera, la primera que se me ocurrió pero no es la mejor ya. que las comas entre los corazones aparecen y no es estético. 😢
function showLives () {
const hearthArray = Array(lives).fill(emojis['HEARTH'])
spanLives.innerHTML = hearthArray;
}
Ya en mi función de gameLose() le quitaba una vida a la variable lives. Al hacer heartsArray un elemento que sus valores cambian puedo insertarlo en el innerHTML del heartsSpan
const heartsArray = Array(lives).fill(emojis['HEART']);
heartsSpan.innerHTML = heartsArray;
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.