Неправильно воспроизводится анимация
Пишу небольшую 2д игру. Логика простая: персонаж перепрыгивает препятствия и собирает монетки. Но добавив в игру паузу, я столкнулся с проблемой, анимация появления дороги опаздывает, из-за чего всё выглядит некрасиво.
HTML:
<!DOCTYPE html>
<html lang="pt-br">
<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>My game</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="game-board">
<div class="pause">||</div>
<div class="score">Score: 0</div>
<div class="cointable">Coins: 0</div>
<img src="./images/clouds.png" class="clouds-1">
<img src="./images/clouds.png" class="clouds-2">
<img src="./images/clouds.png" class="clouds-3">
<img src="./images/character.png" class="character">
<img src="./images/car.png" class="pipe">
<img src="./images/coin.png" class="coin">
<img src="./images/coin.png" class="coin">
<div class="pausewindow">
<button class="continue-button">Continue</button>
</div>
<div class="floor">
<img src="./images/road1.png" class="floor-1">
<img src="./images/road1.png" class="floor-2">
<img src="./images/road1.png" class="floor-3">
</div>
</div>
<div class="under">
<p id="text-start">Click space to start game</p>
</div>
<script src="./script.js" defer></script>
</body>
</html>
CSS:
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@500&display=swap');
* {
margin: 0;
border: 0;
box-sizing: border-box;
}
body{
background-color: rgb(236, 236, 236);
}
.game-board {
width: 100%;
height: 530px;
border-top: 800px;
margin: 0 auto;
position: relative;
overflow: hidden;
background: linear-gradient(#87CEE8, #E0F6FF);
}
.score{
font-family:'Roboto Mono', monospace;
padding: 20px;
color: black;
font-size: 20pt;
}
.cointable{
font-family:'Roboto Mono', monospace;
padding: 20px;
color: black;
font-size: 20pt;
}
.pause{
font-family:'Roboto Mono', monospace;
padding: 20px;
color: black;
font-size: 20pt;
float: right;
cursor: pointer;
}
.pausewindow{
position: absolute;
left: 50vh;
background-color: white;
width: 1000px;
height: 400px;
text-align: center;
z-index: 999;
opacity: 0;
}
.pausewindow.active{
position: absolute;
left: 50vh;
background-color: white;
width: 1000px;
height: 400px;
text-align: center;
z-index: 999;
opacity: 1;
}
.character {
width: 150px;
position: absolute;
bottom: 0;
margin-left: 100px;
z-index: 200;
}
.jump{
animation: character-jump-animation 900ms ease-out;
}
@keyframes character-jump-animation {
0%{
bottom: 0px;
}
45%{
bottom: 180px
}
55%{
bottom: 180px;
}
100%{
bottom:0px;
}
}
.pipe {
position: absolute;
bottom: 0;
width: 200px;
right: -80px;
z-index: 100;
}
.pipe-animation{
animation: pipe-animation 3s infinite linear;
}
@keyframes pipe-animation {
from{
right: -80px;
}
to{
right: 100%;
}
}
.coin {
position: absolute;
bottom: 0;
width: 60px;
right: -160px;
padding-bottom: 34px;
z-index: 50;
}
.coin-animation{
animation: coin-animation 4s infinite linear;
}
@keyframes coin-animation {
from{
right: -80px;
}
to{
right: 130%;
}
}
.collected {
animation: coin-collected 3s ;
}
@keyframes coin-collected {
0%{
bottom: 0px;
opacity: 1;
}
50%{
bottom: 300px;
}
100%{
opacity: 0;
}
}
.floor {
width: 2000px;
position: absolute;
bottom: 0;
padding-bottom: 34px;
}
.floor-1{
position: absolute;
z-index: 10;
}
.floor-animation-1{
animation: floor-animation-1 3.1s infinite linear;
}
@keyframes floor-animation-1 {
0%{
right:0px;
}
100%{
right: 100%;
}
}
.floor-2{
position: absolute;
right: -2000px;
z-index: 10;
}
.floor-animation-2{
animation: floor-animation-2 6.2s infinite linear;
}
@keyframes floor-animation-2 {
0%{
right:-2000px;
}
100%{
right: 100%;
}
}
.floor-3{
position: absolute;
right: -2000px;
z-index: 10;
}
.floor-animation-3{
animation: floor-animation-3 6.2s infinite linear;
}
@keyframes floor-animation-3 {
0%{
right:-2000px;
}
100%{
right: 100%;
}
}
.clouds-1 {
position: absolute;
width: 550px;
padding-top: 50px;
z-index: 4;
animation: clouds-animation-1 40s infinite linear;
}
.clouds-2 {
position: absolute;
width: 270px;
padding-top: 150px;
z-index: 3;
animation: clouds-animation-2 50s infinite linear;
}
.clouds-3 {
position: absolute;
width: 150px;
padding-top: 300px;
z-index: 2;
animation: clouds-animation-3 75s infinite linear;
}
@keyframes clouds-animation-1 {
from{
right: -550px;
}
to{
right: 100%;
}
}
@keyframes clouds-animation-2 {
from{
right: -1300px;
}
to{
right: 100%;
}
}
@keyframes clouds-animation-3 {
from{
right: -250px;
}
to{
right: 100%;
}
}
p {
font-family:'Roboto Mono', monospace;
padding: 50px;
text-align: center;
color: white;
font-size: 20pt;
}
.under{
height: 445px;
width: 100%;
background-color: green;
}
JS:
character = document.querySelector('.character');
pipe = document.querySelector('.pipe');
coin = document.querySelector('.coin');
textStart = document.querySelector('text-start')
floor1 = document.querySelector('.floor-1')
floor2 = document.querySelector('.floor-2')
floor3 = document.querySelector('.floor-3')
scoretable = document.querySelector('.score')
cointable = document.querySelector('.cointable')
pause = document.querySelector('.pause')
pausewindow = document.querySelector('.pausewindow')
continuebutton = document.querySelector('.continue-button')
score = 0
coins = 0
let isPaused = true;
/*старт игры*/
const start = () => {
document.getElementById("text-start").style.color = "green";
pipe.classList.add('pipe-animation');
character.src = './images/character.png';
character.style.width = '150px';
character.style.marginLeft = '50px';
function coinAnimation(){
coin.classList.add('coin-animation');
}setInterval(coinAnimation, 8000);
function floorAnimation1(){
floor1.classList.add('floor-animation-1');
}setInterval(floorAnimation1, 0);
function floorAnimation2(){
floor2.classList.add('floor-animation-2');
}setInterval(floorAnimation2, 0);
function floorAnimation3(){
floor3.classList.add('floor-animation-3');
}setInterval(floorAnimation3, 3100);
isPaused = false;
}
document.addEventListener('keydown', start);
/*прыжок*/
const jump = () => {
character.classList.add('jump');
setTimeout(() => {
character.classList.remove('jump');
}, 900);
}
document.addEventListener('keydown', jump);
/*начисление очков*/
const addScore = setInterval(() => {
const pipePosition = pipe.offsetLeft;
const characterPosition = +window.getComputedStyle(character).bottom.replace('px', '');
if (isPaused == true) {
return;}
score++
scoretable.innerHTML = `Score: ${score}`;
}, 300)
/*подбор монетки*/
const checkCoinCollect = setInterval(() => {
const characterPosition = +window.getComputedStyle(character).bottom.replace('px', '');
const coinPosition = coin.offsetLeft;
if (coinPosition <= 180 && coinPosition > 0 && characterPosition < 10 ) {
coin.classList.add('collected');
coins++
cointable.innerHTML = `Coins: ${coins}`;
setTimeout(() => {
coin.classList.remove('collected');
}, 10);
}
})
/*пауза*/
const pausefunc = () =>{
const pipePosition = pipe.offsetLeft;
const characterPosition = +window.getComputedStyle(character).bottom.replace('px', '');
const coinPosition = coin.offsetLeft;
const floorPosition1 = floor1.offsetLeft;
const floorPosition2 = floor2.offsetLeft;
const floorPosition3 = floor3.offsetLeft;
console.log('game paused')
pipe.style.animation = 'none';
pipe.style.left = `${pipePosition}px`;
character.style.animation = 'none';
coin.style.animation = 'none';
floor1.style.animation = 'none';
floor2.style.animation = 'none';
floor3.style.animation = 'none';
isPaused = true;
pausewindow.classList.add('active');
}
pause.addEventListener('click', pausefunc)
const continuefunc = () =>{
const pipePosition = pipe.offsetLeft;
const characterPosition = +window.getComputedStyle(character).bottom.replace('px', '');
const coinPosition = coin.offsetLeft;
const floorPosition1 = floor1.offsetLeft;
const floorPosition2 = floor2.offsetLeft;
const floorPosition3 = floor3.offsetLeft;
pipe.style.animation = '';
pipe.style.left = ``
character.style.animation = '';
coin.style.animation = '';
floor1.style.animation = '';
floor2.style.animation = '';
floor3.style.animation = '';
isPaused = false;
pausewindow.classList.remove('active');
}
continuebutton.addEventListener('click', continuefunc)
/*Завершение игры*/
function reload(){
location.reload();
}
const checkGameOver = setInterval(() => {
const pipePosition = pipe.offsetLeft;
const characterPosition = +window.getComputedStyle(character).bottom.replace('px', '');
const coinPosition = coin.offsetLeft;
const floorPosition1 = floor1.offsetLeft;
const floorPosition2 = floor2.offsetLeft;
const floorPosition3 = floor3.offsetLeft;
if (pipePosition <= 120 && pipePosition > 0 && characterPosition < 80 ) {
pipe.style.animation = 'none';
pipe.style.left = `${pipePosition}px`;
character.style.animation = 'none';
character.style.bottom = `${characterPosition}px`;
character.style.width = '150px';
character.style.marginLeft = '50px';
coin.style.animation = 'none';
coin.style.left = `${coinPosition}px`;
floor1.style.animation = 'none';
floor1.style.left = `${floorPosition1}px`;
floor2.style.animation = 'none';
floor2.style.left = `${floorPosition2}px`;
floor3.style.animation = 'none';
floor3.style.left = `${floorPosition3}px`;
isPaused = true;
document.getElementById("text-start").style.color = "white";
document.getElementById("text-start").innerHTML="<strong>GAME OVER</strong>";
clearInterval(checkGameOver);
document.addEventListener('keydown', reload);
}
}, 10);