Jannes Braet
Jannes Braet

Reputation: 207

javascript settimeout keeps going faster and faster?

I am making a snake game in JavaScript, so if I press on an arrow key the 'snakehead' should keep moving in that direction.

The first time I press a key it's doing it nicely, but after that the head keeps moving faster and faster.

So what I want is something that moves the head once every 100 millisceconds. If you don't really get what i mean then have a look at this page: http://www.dbzweb.be/08/braetj08/snake.html

So, can someone tell me how to change my code so that it keeps running at same speed?

function init_game() {
    if ((event ? event.keyCode : down) == (event ? 40 : 1)) /*down*/
    {
        if ((snakehead + z) < z * z) {
            right = 0;
            left = 0;
            up = 0;
            down = 1;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gamebox";
            snakehead = snakehead + z;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gameboxsnake";
        } else {
            document.write("<h1>game over!</h1> press this button to try again.<br><input     type='button' value='retry'     onclick='window.open(\"http://www.dbzweb.be/08/braetj08/snake.html\",\"_self\")'>");
        }
    }
    if ((event ? event.keyCode : up) == (event ? 38 : 1)) /*up*/
    {
        if ((snakehead - z) > -1) {
            right = 0;
            left = 0;
            up = 1;
            down = 0;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gamebox";
            snakehead = snakehead - z;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gameboxsnake";
        } else {
            document.write("<h1>game over!</h1> press this button to try again.<br><input    type='button' value='retry'    onclick='window.open(\"http://www.dbzweb.be/08/braetj08/snake.html\",\"_self\")'>");
        }
    }
    if ((event ? event.keyCode : right) == (event ? 39 : 1)) /*right*/
    {
        if ((snakehead + 1) % z !== 0) {
            right = 1;
            left = 0;
            up = 0;
            down = 0;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gamebox";
            snakehead = snakehead + 1;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gameboxsnake";
        } else {
            document.write("<h1>game over!</h1> press this button to try again.<br><input     type='button' value='retry'   onclick='window.open(\"http://www.dbzweb.be/08/braetj08/snake.html\",\"_self\")'>");
        }
    }
    if ((event ? event.keyCode : left) == (event ? 37 : 1)) /*left*/
    {
        if (snakehead % z !== 0) {
            right = 0;
            left = 1;
            up = 0;
            down = 0;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gamebox";
            snakehead = snakehead - 1;
            document.getElementsByClassName(snakehead, "div", document)[0].id = "gameboxsnake";
        } else {
            document.write("<h1>game over!</h1> press this button to try again.<br><input   type='button' value='retry' onclick='window.open(\"http://www.dbzweb.be/08/braetj08/snake.html\",\"_self\")'>");
        }
    }
    t = 0;
    t = setTimeout("init_game()", 100);
}

Upvotes: 1

Views: 3141

Answers (1)

gen_Eric
gen_Eric

Reputation: 227190

t = 0;
t = setTimeout("init_game()", 100);

This doesn't do what you think it does. This sets the variable t to 0 (this doesn't clear the timeout), and then immediately sets it to the timeoutID returned from setTimeout.

The snake is speeding up, because each time a key is pressed init_game is ran again, thus increasing the amount of timeouts runnning all calling init_game again.

Try changing t = 0; to clearTimeout(t). You'll need to declare t before your code, though (add var t; to the top).

Also, don't pass strings to setTimeout, it uses eval. Pass functions.

clearTimeout(t);
t = setTimeout(init_game, 100);

Note: after you document.write("<h1>game over!</h1> you should add return; to stop init_game from looping (and printing infinite "game over!" messages).

DEMO: http://jsfiddle.net/T5kPg/1/

Upvotes: 3

Related Questions