Adding animation

As we already know, in each frame before we draw something, we use black color to clear everything that is left there from the previous frame. We use gl::clear() to do that. To create the effect of moving something, we need to change the object's position in each frame.

To do that, we will need to replace the values of the drawSolidCircle position parameters to variables. Let's declare a new variable that will hold the position of the circle on the screen:

  void prepareSettings( Settings *settings );
  Vec2f currentPosition;
};

This variable will hold the x and y position of the circle that we are drawing inside the draw() method.

Now we will set the initial value of the variable in the setup() method:

void BasicAnimationApp::setup() {
  currentPosition = getWindowCenter();
}

As you can see, a part of the preceding code snippet is the same as we used in the drawSolidCircle() function call. We just made it changeable.

Finally, we have to replace the values in the drawSolidCircle() function to the newly created variable:

void BasicAnimationApp::draw() {
  gl::clear( Color( 0, 0, 0 ) );
  gl::drawSolidCircle( currentPosition, 30 );
}

Compile and run our application. Nothing much has changed. Don't worry about that and add the following line of code before the drawSolidCircle() function call:

currentPosition.x++;

Compile and run the application again and there it is, a moving circle. Cool! We have our first animation! Now let's do something with the radius of the circle. To apply animation to it, we have to declare a new variable again:

  void prepareSettings( Settings *settings );
  Vec2f currentPosition;
  float circleRadius;
};

Now, set its starting value:

void BasicAnimationApp::setup() {
  currentPosition = getWindowCenter();
  circleRadius = 100;
}

And add an animation rule and replace the constant value of the circle radius parameter of the drawSolidCircle() function call in the draw() method implementation:

  currentPosition.x++;
  circleRadius--;
  gl::drawSolidCircle( currentPosition, circleRadius );
}

Compile and run our application. You should see a big white point disappearing in front of your eyes. It might seem that you did something wrong, but don't worry, everything is correct. The trick is that we decreased the circle radius by one pixel for each frame. It is happening at a rate of 60 times per second and that means that the radius of the circle will reach 0 in approximately 1.5 seconds. Therefore, if the radius is 0, the circle becomes invisible as there can be no circle without a radius.

So far so good. Let's try to move our circle to some fixed location over time. Let's say we want to move it from the top-left corner of the screen to the bottom right. To do that we need to set the initial position of the circle to 0. and let's change the initial circleRadius to something smaller as well:

void BasicAnimationApp::setup() {
  currentPosition = Vec2f(0,0);
  circleRadius = 100;
}

Let's declare another Vec2f variable that will hold the target position of the circle in the class declaration:

  Vec2f currentPosition;
  Vec2f targetPosition;
  float circleRadius;
};

We need to set the initial target position somewhere, so we have to add a new line in the setup() method implementation:

void BasicAnimationApp::setup() {
  currentPosition = Vec2f(0,0);
  targetPosition = Vec2f(800,600);
  circleRadius = 100;
}

Finally, we need to write some code that creates a smooth transition between currentPosition and targetPosition. Let's do it in the update() method implementation as it is meant for such calculations. Remember, try to use the draw() method just for drawing and place all your calculations inside update(). It does not matter much for a small application such as this one, but as your code grows bigger, it is possible that the application won't perform so well or will even crash if you don't stick to this simple rule.

void BasicAnimationApp::update() {
  Vec2f difference = targetPosition - currentPosition;
  difference *= 0.95f;
  currentPosition = targetPosition - difference;
}

These three lines of code calculate the difference between the current circle position and the target circle position. Then, we make the difference between these positions smaller by multiplying it with a floating point number that is smaller than 0. Finally, we calculate the new current position by subtracting the new difference from the target position of the circle.

This would require a longer code if we didn't make use of the integrated vector algebra features of Cinder. As a Vec2f object contains two values (the x and the y coordinate), when we multiply it with a single value, both values inside the Vec2f object are multiplied by this value. Furthermore, if we multiply a Vec2f object with another Vec2f object, the first element of the first vector is multiplied with the first element of the second one, and the second element of the first one is multiplied with the second element of the second one, and so on.

Now compile and run our application. You should see a circle moving from the top-left corner to the bottom-right corner of the screen.

Adding animation
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.124.177