Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Jumping Mario: Bug no Score

Oi gente! Eu gostaria de uma ajudinha em um bug que estou enfrentando no código de um joguinho simples que eu fiz baseado no seguinte vídeo (o exercício foi proposto pela faculdade): https://www.youtube.com/watch?v=r9buAwVBDhA&ab_channel=ManualdoDev

Eu estou tentando criar um sistema de pontuação. O problema é que quando o Mario consegue desviar do cano, a pontuação, que deveria ser atualizada para +1, é atualizada para valores vareados, mas maiores do que 1, como eu especifiquei no código.

Link do repositório: https://github.com/kellysondias/mario-jump

Este é o script.js:

const mario = document.querySelector(".mario");
const pipe = document.querySelector(".pipe");
const score = document.querySelector(".score");

console.log(score);

const jump = () => {
  const add = () => mario.classList.add("mario-jump");
  const remove = () => mario.classList.remove("mario-jump");
  const timeOut = 500;

  add();
  setTimeout(() => remove(), timeOut);
};

const interval = 10;

let points = 0;

const updateScore = () => (score.innerText = `Score: ${points}`);

updateScore();

const gameLoop = () => {
  const pipePosition = pipe.offsetLeft;
  const marioPosition = Number(
    window.getComputedStyle(mario).bottom.replace("px", "")
  );

  const pipeCrash = 120;
  const marioCrash = 80;

  const scored = pipePosition <= pipeCrash && marioPosition > marioCrash;
  const gameOver =
    pipePosition <= pipeCrash && pipePosition > 0 && marioPosition < marioCrash;

  if (gameOver) {
    pipe.style.animation = "none";
    pipe.style.left = `${pipePosition}px`;

    mario.style.animation = "none";
    mario.style.bottom = `${marioPosition}px`;

    mario.src = "./img/game-over.png";
    mario.style.width = "75px";
    mario.style.marginLeft = "50px";

    clearInterval(loop);
  } else if (scored) {
    points++;
  }

  updateScore();
};

const loop = setInterval(gameLoop, interval);

document.addEventListener("keydown", jump);

Este é o index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="shortcut icon" href="./img/favicon.png" type="image/x-icon" />
    <link rel="stylesheet" href="./css/style.css" />
    <title>Mario Jump</title>
  </head>
  <body>
    <div class="game-board">
      <p class="score"></p>
      <img src="./img/clouds.png" alt="Clouds" class="clouds" />
      <img src="./img/mario.gif" alt="Mario" class="mario" />
      <img src="./img/pipe.png" alt="Pipe" class="pipe" />
    </div>
    <script src="js/script.js" type="text/javascript"></script>
  </body>
</html>

Este é o index.css:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.game-board {
  width: 100%;
  height: 500px;
  border-bottom: 15px solid rgb(35, 160, 35);
  margin: 0 auto;
  position: relative;
  overflow: hidden;
  background: linear-gradient(#87ceeb, #e0f6ff);
}

.clouds {
  position: absolute;
  width: 350px;
  top: 15px;
  animation: clouds-animation 20s infinite linear;
}

.mario {
  width: 150px;
  position: absolute;
  bottom: 0;
}

.mario-jump {
  animation: jump 500ms ease-out;
}

.pipe {
  position: absolute;
  bottom: 0;
  width: 80px;
  animation: pipe-animation 2s infinite linear;
}

@keyframes clouds-animation {
  from {
    right: -350px;
  }

  to {
    right: 100%;
  }
}

@keyframes pipe-animation {
  from {
    right: -80px;
  }

  to {
    right: 100%;
  }
}

@keyframes jump {
  from {
    bottom: 0;
  }

  40% {
    bottom: 180px;
  }

  50% {
    bottom: 180px;
  }

  60% {
    bottom: 180px;
  }

  70% {
    bottom: 180px;
  }

  to {
    bottom: 0;
  }
}
1 resposta
solução!

Oi Kellyson!

O problema está na forma como você está verificando se o Mario marcou pontos. A condição pipePosition <= pipeCrash && marioPosition > marioCrash pode ser verdadeira por vários loops do jogo enquanto o Mario estiver acima do cano. Isso faz com que a pontuação seja atualizada várias vezes ao pular, sugerindo esses valores.

Desenvolvi o código que aparentemente resolve essa questão, em resumo adicionei uma variável chamada "MarcaPontos" do tipo booleana e inicializamos com true. Em seguida, verificamos se scored é verdadeiro e se MarcaPontos também é verdadeiro. Se ambas as condições forem atendidas, incrementamos a pontuação e definimos MarcaPontos como false para evitar que a pontuação seja atualizada repetidamente enquanto o Mario estiver acima do cano.

Seu código completo fica assim:

const mario = document.querySelector(".mario");
const pipe = document.querySelector(".pipe");
const score = document.querySelector(".score");

console.log(score);

const jump = () => {
  const add = () => mario.classList.add("mario-jump");
  const remove = () => mario.classList.remove("mario-jump");
  const timeOut = 500;

  add();
  setTimeout(() => remove(), timeOut);
};

const interval = 10;

let points = 0;
let MarcaPontos = true;

const updateScore = () => (score.innerText = `Score: ${points}`);

updateScore();

const gameLoop = () => {
  const pipePosition = pipe.offsetLeft;
  const marioPosition = Number(
    window.getComputedStyle(mario).bottom.replace("px", "")
  );

  const pipeCrash = 120;
  const marioCrash = 80;

  const scored = pipePosition <= pipeCrash && marioPosition > marioCrash;
  const gameOver =
    pipePosition <= pipeCrash && pipePosition > 0 && marioPosition < marioCrash;

  if (gameOver) {
    pipe.style.animation = "none";
    pipe.style.left = `${pipePosition}px`;

    mario.style.animation = "none";
    mario.style.bottom = `${marioPosition}px`;

    mario.src = "./img/game-over.png";
    mario.style.width = "75px";
    mario.style.marginLeft = "50px";

    clearInterval(loop);
  } else if (scored && MarcaPontos) {
    points++;
    MarcaPontos = false;
  }

  if (!scored) {
    MarcaPontos = true;
  }

  updateScore();
};

const loop = setInterval(gameLoop, interval);

document.addEventListener("keydown", jump);

Jogo do Mario em Javascript

Espero ter ajudado, qualquer dúvida, me coloco à disposição! Bons estudos!

Sucesso

Um grande abraço e até mais!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!