Почему мой новый оператор if нарушает мою функцию?

#javascript

Вопрос:

Я новичок в javascript. Я только что сделал очень простую игру, в которой рыцарь перепрыгивает через скалу, однако скала была бесконечной анимацией. Я пытаюсь добавить различные скорости вращения, но по какой-то причине мой новый код нарушает мою игру. Вот мой полный код: https://codepen.io/flyingchicken22/pen/BadBLre Это код, который я добавил (с фрагментами моего другого кода: CSS:

 #rock {
    height: 50px;
    width: 50px;
    position: relative;
    top: 122px;
    left: 550px;
    background-image: url("http://pixelartmaker-data-78746291193.nyc3.digitaloceanspaces.com/image/da268f06e621b21.png");
    background-size: cover;
}

.rockAnimationFast {
    animation: rockAnimationFast 0.75s linear;
}

.rockAnimationMedium {
    animation: rockAnimationMedium 1s linear;
}

.rockAnimationSlow {
    animation: rockAnimationSlow 1.5s linear;
}

@keyframes rockAnimationFast {
    0%{left: 500px;}
    100%{left: -50px;}
}

@keyframes rockAnimationMedium {
    0%{left: 500px;}
    100%{left: -50px;}
}

@keyframes rockAnimationSlow {
    0%{left: 500px;}
    100%{left: -50px;}
}
 

язык JavaScript:

 function play() {
    let dead = false
    if (dead==false) {
        let falseVar = false
        while (falseVar == false) {
    
            console.log("working")
            function rockAnimationSlow() {
                document.getElementById("rock").classList.add('rockAnimationSlow')
                setTimeout(() => {
                    document.getElementById("rock").classList.remove('rockAnimationSlow')
                }, 1500);
            }
            
            function rockAnimationMedium() {
                let rock = document.getElementById("rock")
                rock.classList.add('rockAnimationMedium')
                setTimeout(() => {
                    rock.classList.remove('rockAnimationMedium')
                }, 1000);
            }
    
            function rockAnimationFast() {
                let rock = document.getElementById("rock")
                rock.classList.add('rockAnimationFast')
                setTimeout(() => {
                    rock.classList.remove('rockAnimationFast')
                    
                }, 750);
            }
            let randRockSpeed = Math.floor(Math.random() * 10)
            
            
            if (randRockSpeed <= 3) {
                rockAnimationFast()
            }
    
            if (randRockSpeed <= 7 amp;amp; randRockSpeed > 3) {
                rockAnimationMedium()
                
            }
    
            if (randRockSpeed <= 10 amp;amp; randRockSpeed > 7) {
                rockAnimationSlow()
            }
    }
    }
}
 

Большое вам спасибо!

Комментарии:

1. Пожалуйста, отредактируйте вопрос, чтобы ограничить его конкретной проблемой с достаточной детализацией для определения адекватного ответа.

Ответ №1:

Это не оператор if, который нарушает код, а скорее ваш бесконечный цикл while (который, я полагаю, вы используете для анимации своей игры). Однако анимацию необходимо обрабатывать по-другому, так как бесконечный цикл в основном блокирует основной поток на неопределенный срок, что приводит к сбою браузера. Обычно это делается с помощью requestAnimationFrame. Вот как это может выглядеть в действии в вашем случае :

 let dead = false


function update() {
  if (dead == false) {
    let falseVar = false


    console.log("working")

    function rockAnimationSlow() {
      document.getElementById("rock").classList.add('rockAnimationSlow')
      setTimeout(() => {
        document.getElementById("rock").classList.remove('rockAnimationSlow')
      }, 1500);
    }

    function rockAnimationMedium() {
      let rock = document.getElementById("rock")
      rock.classList.add('rockAnimationMedium')
      setTimeout(() => {
        rock.classList.remove('rockAnimationMedium')
      }, 1000);
    }

    function rockAnimationFast() {
      let rock = document.getElementById("rock")
      rock.classList.add('rockAnimationFast')
      setTimeout(() => {
        rock.classList.remove('rockAnimationFast')

      }, 750);
    }
    let randRockSpeed = Math.floor(Math.random() * 10)


    if (randRockSpeed <= 3) {
      rockAnimationFast()
    }

    if (randRockSpeed <= 7 amp;amp; randRockSpeed > 3) {
      rockAnimationMedium()

    }

    if (randRockSpeed <= 10 amp;amp; randRockSpeed > 7) {
      rockAnimationSlow()
    }

  }
}


function play() {
  dead = false
  update()
  //transfers jump animation to script

  function jump() {
    knight.classList.add('jump-animation')
    setTimeout(() => {
      knight.classList.remove('jump-animation')
    }, 500)
  }
  //When any key is pressed, run jump animation
  document.addEventListener('keypress', () => {
    if (!knight.classList.contains('jump-animation') amp;amp; dead == false) {
      jump();
    }
  })
  //game loop


  var gameLoop = setInterval(() => {
    score.innerText  
  }, 50)
}
let score = document.getElementById('score')




var gameLoop1 = setInterval(() => {



  const knight = document.getElementById('knight')
  const rock = document.getElementById('rock')


  const knightTop = parseInt(window.getComputedStyle(knight).getPropertyValue('top'))
  const rockLeft = parseInt(window.getComputedStyle(rock).getPropertyValue('left'))


  if (rockLeft < 0) {
    rock.style.display = 'none'
  } else {
    rock.style.display = ''
  }

  if (rockLeft < 90 amp;amp; rockLeft > 50 amp;amp; knightTop > 79) {
    dead = true
  }

  const deathAnimation = document.getElementById("deathAnimation")
  const game = document.getElementById("game")
  if (dead == true) {
    clearInterval(gameLoop)
    clearInterval(gameLoop1)
    game.classList.add(deathAnimation)
    document.getElementById("reload").style.animationPlayState = "running"
    document.getElementById("game").style.animationPlayState = "running"
    document.getElementById("rock").style.animationPlayState = "paused"
    document.getElementById("gameOver").style.animationPlayState = "running"
  }

  let scoreNum = document.getElementById("score")

  if (scoreNum == 1000) {
    //ENTER NEXT STAGE
    console.log("1000")
  }
}, 50)

function reload() {
  location.reload()
} 
 html {
  background-color: black;
}

#score {
  font-family: 'Press Start 2P', cursive;
  text-align: center;
  color: rgba(102, 255, 0, 0.993);
}

#game {
  width: 600px;
  height: 300px;
  border: 2px solid black;
  margin: auto;
  background-image: url("https://t3.ftcdn.net/jpg/01/73/79/26/360_F_173792623_516juhwjkCCZJ9OyesyH7hf7r9zsyH5u.jpg");
  background-size: cover;
  animation: deathAnimation 2s;
  animation-play-state: paused;
  animation-fill-mode: forwards;
}

@keyframes deathAnimation {
  0% {
    filter: none;
  }
  100% {
    filter: grayscale(100%);
  }
}

#knight {
  height: 100px;
  width: 75px;
  position: relative;
  top: 171px;
  left: 50px;
  background-image: url("https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/f57b5304-de59-49e3-b0f9-cc29a2458425/dcgy8i3-e6dac283-04a7-40e5-a333-cc645e172df7.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcL2Y1N2I1MzA0LWRlNTktNDllMy1iMGY5LWNjMjlhMjQ1ODQyNVwvZGNneThpMy1lNmRhYzI4My0wNGE3LTQwZTUtYTMzMy1jYzY0NWUxNzJkZjcucG5nIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.0LapCzRi5sQjkqzwB5lwWQT_XH1BM4rSMZt7jrflMLk");
  background-size: cover;
}

#h3 {
  font-family: 'Press Start 2P', cursive;
  color: rgba(102, 255, 0, 0.993);
  text-align: center;
}

#rock {
  height: 50px;
  width: 50px;
  position: relative;
  top: 122px;
  left: 550px;
  background-image: url("http://pixelartmaker-data-78746291193.nyc3.digitaloceanspaces.com/image/da268f06e621b21.png");
  background-size: cover;
}

.rockAnimationFast {
  animation: rockAnimationFast 0.75s linear;
}

.rockAnimationMedium {
  animation: rockAnimationMedium 1s linear;
}

.rockAnimationSlow {
  animation: rockAnimationSlow 1.5s linear;
}

@keyframes rockAnimationFast {
  0% {
    left: 500px;
  }
  100% {
    left: -50px;
  }
}

@keyframes rockAnimationMedium {
  0% {
    left: 500px;
  }
  100% {
    left: -50px;
  }
}

@keyframes rockAnimationSlow {
  0% {
    left: 500px;
  }
  100% {
    left: -50px;
  }
}

.jump-animation {
  animation: jump 0.5s;
}

@keyframes jump {
  0% {
    top: 171px;
  }
  50% {
    top: 70px;
  }
  75% {
    top: 70px;
  }
  100% {
    top: 171px;
  }
}

#gameName {
  font-family: 'Press Start 2P', cursive;
  text-align: center;
  color: rgba(102, 255, 0, 0.993);
  font-size: 300%;
}

#gameOver {
  font-family: 'Press Start 2P', cursive;
  text-align: center;
  color: black;
  animation: gameOver 2s infinite;
  animation-play-state: paused;
}

@keyframes gameOver {
  0% {
    color: black;
  }
  50% {
    color: rgba(102, 255, 0, 0.993);
  }
  100% {
    color: black
  }
}

#reload {
  background: url("https://static.thenounproject.com/png/191594-200.png");
  margin: 200;
  margin-left: auto;
  margin-right: auto;
  width: 300px;
  height: 300px;
  background-size: cover;
  animation: reload 5s, move 0.5s infinite;
  animation-fill-mode: forwards;
  animation-play-state: paused;
}

@keyframes reload {
  0% {
    filter: none
  }
  100% {
    filter: invert(100%)
  }
}

@keyframes move {
  0% {
    transform: rotate(0deg)
  }
  50% {
    transform: rotate(10deg)
  }
  90% {
    transform: rotate(0deg)
  }
  93% {
    transform: rotate(0deg)
  }
  95% {
    transform: rotate(0deg)
  }
  100% {
    transform: rotate(0deg)
  }
}

#play {
  margin-left: 1150px;
  margin-right: auto;
  width: 300px;
  height: 300px;
  background-image: url("https://art.pixilart.com/a9b70c683c2aed9.png");
  background-size: cover;
}

#companyName {
  width: 10px;
  height: 5px;
  color: #7bafd4;
  font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
  margin-right: 500px;
  margin-bottom: 0px;
} 
 <!DOCTYPE html>
<html lang="en">

<head>

  <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=Press Start 2Pamp;display=swap" rel="stylesheet">
  <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>Document</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div id="game">
    <div id="knight"></div>
    <div id="rock"></div>

  </div>

  <h1 id="score">0</h1>
  <h3 id="highScore"></h3>
  <h1 id="gameName">KNIGHT HOPPER</h1>
  <h1 id="gameOver">Game Over</h1>
  <div id="play" onclick="play()"></div>
  <div id="reload" onclick="reload()"></div>
  <div id="companyName">flyingchicken</div>
  <script src="script.js"></script>
</body>

</html> 

Хотя некоторые ошибки все еще присутствуют здесь и там в вашем коде (например, переменную gameLoop нужно обрабатывать по-другому), я считаю, что вы на правильном пути для своего потрясающего проекта.

Если вы все еще боретесь с другими ошибками, пожалуйста, дайте мне знать, я с радостью помогу вам.

Комментарии:

1. Большое вам спасибо за ответ на мой вопрос. Кажется, я не могу понять window.requestAnimationFrame (), и мне было интересно, не могли бы вы объяснить, как я могу его использовать? Я бы хотел, чтобы камень бежал по бесконечному циклу, но в данный момент он просто бежит один раз и останавливается. Спасибо!