tags:

views:

56

answers:

1

How do you control the speed of an animation? My objects animate faster on another's machine.

void idle(void){

if (!wantPause){    
    circleSpin = circleSpin + 2.0;      //spin circles
    if(circleSpin > 360.0)
{
        circleSpin = circleSpin - 360.0;
}

        diamondSpin = diamondSpin - 4.0;    //spin diamonds
    if(diamondSpin > 360.0)
{
        diamondSpin = diamondSpin + 360.0;
}
        ellipseScale = ellipseScale + 0.1;  //scale ellipse
    if(ellipseScale > 30)
{
        ellipseScale = 15;
}
glutPostRedisplay();
}
}

void drawScene()
{
 ...
glColor3f(1,0,0);
glPushMatrix();
glRotatef(circleSpin,0,0,1);
drawOuterCircles();
glPopMatrix();
}


int main (int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(400,400);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Lesson 6");
init();
glutDisplayFunc(drawScene);
glutKeyboardFunc(keyboard);
glutReshapeFunc(handleResize);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
+5  A: 

This is the poor man's solution:

FPS = 60.0;
while (game_loop) {
    int t = getticks();
    if ((t - t_prev) > 1000/FPS)
        process_animation_tick();
    t_prev = t;
}

this is the better solution:

GAME_SPEED = ...
while (game_loop) {
    int t = getticks();
    process_animation((t - t_prev)*GAME_SPEED/1000.0);
    t_prev = t;
}

In the first one, getframe moves your object by a fixed amount, but that is prone to errors if framerate drops.

In the latter, you move the objects based on the time passed. E.g. if 20ms pass, you rotate an object 12 degrees, and if 10ms pass, you rotate it 6 degrees. In general, the animation if a function of time passed.

Implementation of getticks() is up to you. For a start you could use glutGet(GLUT_ELAPSED_TIME).


In your case it would look something like:

int old_t;

void idle(void) {
  int t = glutGet(GLUT_ELAPSED_TIME);
  int passed = t - old_t;
  old_t = t;
  animate( passed );
  glutPostRedisplay();
}

void animate( int ms )
{  
  if (!wantPause){    
    circleSpin = circleSpin + ms*0.01;      //spin circles
    if(circleSpin > 360.0)
    {
      circleSpin = circleSpin - 360.0;
    }
    diamondSpin = diamondSpin - ms*0.02;    //spin diamonds
    if(diamondSpin > 360.0)
    {
        diamondSpin = diamondSpin - 360.0;
    }
    ellipseScale = ellipseScale + ms*0.001;  //scale ellipse
    if(ellipseScale > 30)
    {
        ellipseScale = 15;
    }
  }
}
Kornel Kisielewicz