setinterval time speed in click

Viewed 58

I have created a simple game, have problem in the game start, i use setinterval to make time and the score but increase very quick thes code just example:

const main = document.querySelector("main"),
    model = document.querySelector(".model"),
    time = document.querySelector(".time");

function jump() {
    modelAnimation();
    setInterval(timeInt, 1000)
}

main.addEventListener("click", jump);

function modelAnimation() {
    model.classList.add("model-act")

    model.addEventListener("animationend", () => {
        model.classList.remove("model-act");
    });

}

let seconds = 0;

function timeInt(m = "00", s = "00") {
    m = Math.floor(seconds / 60);
    s = Math.floor(seconds % 60);

    m = m < 10 ? `0${m}` : m
    s = s < 10 ? `0${s}` : s

    time.textContent = `${m}:${s}`

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

body {
    font-family: sans-serif;
    display: grid;
    place-items: center;
    min-height: 100vh;
    background-color: #121212;
}

main {
    width: 700px;
    height: 400px;
    background-color: white;
    position: relative;
}

.model {
    position: absolute;
    left: 1em;
    bottom: 0;
    width: 100px;
    height: 100px;
    background-color: red;
}

.model.model-act {
    animation: modelJump 500ms forwards;
    -webkit-animation: modelJump 500ms forwards;
}

@keyframes modelJump {
    0% {
        top: 100px;
    }

    30%,
    70% {
        top: 50px;
    }

    100% {
        bottom: 0;
    }
}
<!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>Document</title>
        <link rel="stylesheet" href="style.css">
        <script defer src="amin.js"></script>
    </head>

    <body>
        <main>
            <div class="time">00:00</div>
            <div class="model"></div>
        </main>
    </body>

</html>

Also this is my first game project and first javascript project. So any other input or mistakes in code is appreciated. Note: Please ignore some comments in the js file. Those were my mistakes. For my reference.

1 Answers

You call jump every time it is clicked. So if you click many times, there will be multiple intervals, all trying to do seconds++

*[see edit history for older comments]

One way around it is to save a variable let activeInterval somewhere, and only create the interval when it's not yet defined.

Also, since the function is only called 1000ms after the click, it should show 00:01 the first time it runs. One way to get this behavior is to add one second immediately at the top of the function.

const main = document.querySelector("main"),
    model = document.querySelector(".model"),
    time = document.querySelector(".time");
let activeInterval; 
function jump() {
    modelAnimation();
    if(activeInterval === undefined) activeInterval = setInterval(timeInt, 1000)
}

main.addEventListener("click", jump);

function modelAnimation() {
    model.classList.add("model-act")

    model.addEventListener("animationend", () => {
        model.classList.remove("model-act");
    });

}

let seconds = 0;

function timeInt(m = "00", s = "00") {

    seconds++;
    m = Math.floor(seconds / 60);
    s = Math.floor(seconds % 60);

    m = m < 10 ? `0${m}` : m
    s = s < 10 ? `0${s}` : s

    time.textContent = `${m}:${s}`

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

body {
    font-family: sans-serif;
    display: grid;
    place-items: center;
    min-height: 100vh;
    background-color: #121212;
}

main {
    width: 700px;
    height: 400px;
    background-color: white;
    position: relative;
}

.model {
    position: absolute;
    left: 1em;
    bottom: 0;
    width: 100px;
    height: 100px;
    background-color: red;
}

.model.model-act {
    animation: modelJump 500ms forwards;
    -webkit-animation: modelJump 500ms forwards;
}

@keyframes modelJump {
    0% {
        top: 100px;
    }

    30%,
    70% {
        top: 50px;
    }

    100% {
        bottom: 0;
    }
}
<!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>Document</title>
        <link rel="stylesheet" href="style.css">
        <script defer src="amin.js"></script>
    </head>

    <body>
        <main>
            <div class="time">00:00</div>
            <div class="model"></div>
        </main>
    </body>

</html>

Related