Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am building a Javascript/canvas platformer game, and it's coming along nicely. The only problem I've really run into where I can think of any solution at all is the animation of my player sprite.

The game loop is running every 16ms, which equates to 60fps. On every game loop, I'm using a method of my player class (called draw) to draw the player sprite. The sprite looks like this: http://i.imgur.com/uM3Un.png

On every call of the draw method, I am advancing the "frame" of the player sprite, to give the illusion that the player is moving. As far as I know, this is common practice. However, due to my draw method being run every 16ms with the game loop, my player sprite is animating extremely quickly, and it doesn't look realistic at all.

Is there a way to slow this down to a pre-defined speed, or will I have to resort to adding loads of duplicate frames to my player sprite? Obviously that's not a great solution, as to make it look realistic at a game speed of 60fps I'd need to have a LOT of frames.

Here's my relevant code:

// Sets off the main game loop
setInterval("gameLoop()", gameSpeed);

function gameLoop() {
    // Updates
    player.update();

    // Draw
    c.clearRect(0, 0, canvas.width, canvas.height);
    player.draw();
}

// Then in my player class...

this.draw = function() {
        if(this.state == "idle") {
            c.drawImage(this.idleSprite, this.idleSprite.frameWidth * this.idleSprite.frameCount, 0, this.idleSprite.frameWidth, this.idleSprite.frameHeight, this.xpos, this.ypos, this.idleSprite.frameWidth, this.idleSprite.frameHeight);
            if(this.idleSprite.frameCount < this.idleSprite.frames - 1) { this.idleSprite.frameCount++; } else { this.idleSprite.frameCount = 0; }
        } else if(this.state == "running") {
            var height = 0;
            if(this.facing == "left") { height = 37; }
            c.drawImage(this.runningSprite, this.runningSprite.frameWidth * this.runningSprite.frameCount, height, this.runningSprite.frameWidth, this.runningSprite.frameHeight, this.xpos, this.ypos, this.runningSprite.frameWidth, this.runningSprite.frameHeight);
            if(this.runningSprite.frameCount < this.runningSprite.frames - 1) { this.runningSprite.frameCount++; } else { this.runningSprite.frameCount = 0; }
        }
    }
share|improve this question
add comment

2 Answers 2

up vote 8 down vote accepted

What I always do in this case is store a frameTime variable and store the last update time variable inside my animation class. Then I only update the frame if the currentTime - lastUpdateTime > frameTime, in which case I also set last update time to currentTime.

Huzzah for animation =]

share|improve this answer
    
Worked perfect, thank you! :) –  Andy Oct 28 '11 at 2:01
1  
@Andy, I do the same thing as ultifinitus, Except that do lastUpdateTime = lastUpdateTime + frametime so as to not lose time. If you simply set the lastUpdateTime = currentTime, your animation's speed will vary just a little bit. Probably not noticeable in most cases, but if you need to predict exactly when a long animation will end, you don't want to lose time. –  John McDonald Oct 28 '11 at 14:15
add comment

I'd try to use a new timer for the player, just a timeout for the next animation and in case of bad things the gameloop can clear this timer and reset the player.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.