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 been working in the animation of a 2D platformer game in C++/SDL/OpenGL, and my team and I reach the point where we need to establish that every animation of the player (Walking, Running, etc..) needs a different framerate for our concept, but I use as a guideline the Game Programming All In One as a example for the smooth animation, and in the book recommend have variables that limits the movement and the changes of frames.

To clarify what I mean I have in my Sprite class these parameters:

std::vector< Vector2f > delayMovementSprite;
std::vector< int > frameDelayPerAnimation;
GLfloat countX, countY;

Where the vector delayMovementSprite contains all the values for the differents animations and countX increment in every frame until it's equal or greater than the value that correspond in the vector delayMovementSprite.

Something like this:

void Sprite::movePosXWithSpeed()
{
  playerMoveInX = false || playerMoveInX;

  countX++;
  if ( countX > delayMovementSprite.at(getCurrentState()).x )
  {
    countX = 0;
    if ( handlerAnimation->getAnimationDirection() == SpriteData::RIGHT )
    {
      if ( position.x + getSpeedX() + width < 6368.f )
      {
        position.x += getSpeedX();
        playerMoveInX = true;
        return;
      }
    }

    else if ( position.x + getSpeedX() + width  > 0 )
    {
      position.x += getSpeedX();
      playerMoveInX = true;
      return;
    }
    playerMoveInX = false;
  }
}

And for the frames I have a class Animation which handles the following information:

Uint32 frameRate, oldTime;
int frameDelay;
int frameCount;

And in the function that animates I do the following, much like the MoveX in Sprite:

int Animation::animate() 
{
  if( oldTime + frameRate > SDL_GetTicks() ) 
  {
    return -1;
  }

  oldTime += frameRate;
  frameCount++;

  if ( frameCount > frameDelay )
  {
    animationAlreadyEnd = false;
    frameCount = 0;
    currentFrame += incrementFrame;

    if( currentFrame > maxFrames)
    {
      animationAlreadyEnd = true;
      currentFrame = returnFrame;
    }
  }

  return currentFrame;
}

I got working all that and everything executes apparently fine, but in some points of the game the animation doesn't look really smooth when in other points it is.

I leave the video of the "gameplay" so everyone could see what I mean.

http://www.youtube.com/watch?v=uoxKEYzwkcQ

I currently using during the execution of the game a general Timer in 60 FPS.

If anyone needs more information, don't hesitate in ask.

Thanks a lot for the help.

share|improve this question

2 Answers 2

up vote 3 down vote accepted

Instead of delaying a set number of frames, why not only update frame if the time elapsed since the last update is xx? (for instance 100 ms)

You're animations will look great- and won't depend on your framerate.

In other words: have a class variable to store the update time, and when your update function rolls around, if (the current time - previous update time > desired frame time) increment frame()

share|improve this answer
    
If I understand correctly, you're saying that use a timer for every sprite, right?...I already have a timer for the game in general, so it's a good idea use multiple timers?...Thanks –  oscar.rpr Oct 19 '11 at 5:39
    
It's a 2d game, you won't have any troubles at all with some extra variables =] –  ultifinitus Oct 19 '11 at 5:43
1  
So, the main idea is use a timer for every sprite, and only update the frame and the position if this condition (the current time - previous update time > desired frame time) it's true? Am I right? –  oscar.rpr Oct 19 '11 at 13:12
    
Just the frame, not the position. –  ultifinitus Oct 19 '11 at 16:04
    
In that case, the position must be updated in every frame, but that seems wrong, because if the movement of the player must be consistent with the animation, so the player will be moving a lot but animating a little rate? –  oscar.rpr Oct 19 '11 at 17:32

I use a slightly different approach that you may want to consider. Instead of messing around with frame rates and vectors, I simply define some constants for the 'delay' I want between each frame

const float PLAYER_WALK_ANIMATION_DELAY = 0.5f;

and then I throw around some static's in the draw function

static float playerWalkDelay = 0.0f;
playerWalkDelay += 0.1f;
if (playerWalkDelay > PLAYER_WALK_ANIMATION_DELAY) {
   playerWalkDelay = 0.0f;
   animateWalk();   
}

Like every solution to a problem this has it's pro's and con's. But I have used it in a similar game and it has worked well.

I have two side notes I would like to make. Firstly, your game looks great! Give me a PM if you need some alpha testing. Secondly, I would definitely isolate my player sprite while I am coding and testing the animations (the video is great but it makes it hard to see where/what the problem occurs; if you are debugging like this you are making life hard for yourself).

share|improve this answer
    
I think that your approach is similar to mine, having a top limit of the animation delay and a counter for that, but I think that this method it's the reason why the animation doesn't look really smooth. In the video, you can may see the problem in seconds 11-14. By the way, thanks for the comment, I will have you in mind when we are in alpha testing, and for the debugging we currently have a little project where we only have our sprites and test every animation. –  oscar.rpr Oct 19 '11 at 17:37

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.