The last tutorial we took our chance at making a Tic-Tac-Toe game. Hopefully most of you were successful in getting it to work. If not, don’t fret, you’ll get the hang of all of this eventually.
In this tutorial we are going to take our hand at SDL Animation. As before, we’ll be building on top of the previous SDL lessons (but not including the Tic Tac Toe one). So lets get started.
We’ll be creating a new class to handle Animation, and in the next tutorial we will create a class to handle Entities. Please keep in mind that these two things are seperate, and while I know they could be one class, I don’t wish to take that approach. So please hold back your criticism.
Create two new files (I am sure you are seeing a pattern now, hopefully), called CAnimation.h and CAnimation.cpp. Eventually, our CEntity class will inherit this class, but for now we’ll be testing through an object we create later. And before we get started add the include directive within CApp.h (before #include “CEvent.h” is just fine).
Now open up CAnimation.h and lets start coding. Add the following basic class structure to your file.
#define _CANIMATION_H_
#include <SDL.h>
class CAnimation {
private:
int CurrentFrame;
int FrameInc;
private:
int FrameRate; //Milliseconds
long OldTime;
public:
int MaxFrames;
bool Oscillate;
public:
CAnimation();
void OnAnimate();
public:
void SetFrameRate(int Rate);
void SetCurrentFrame(int Frame);
int GetCurrentFrame();
};
#endif
Now, open up CAnimation.cpp and add this code:
CAnimation::CAnimation() {
CurrentFrame = 0;
MaxFrames = 0;
FrameInc = 1;
FrameRate = 100; //Milliseconds
OldTime = 0;
Oscillate = false;
}
void CAnimation::OnAnimate() {
if(OldTime + FrameRate > SDL_GetTicks()) {
return;
}
OldTime = SDL_GetTicks();
CurrentFrame += FrameInc;
if(Oscillate) {
if(FrameInc > 0) {
if(CurrentFrame >= MaxFrames – 1) {
FrameInc = -FrameInc;
}
}else{
if(CurrentFrame <= 0) {
FrameInc = -FrameInc;
}
}
}else{
if(CurrentFrame >= MaxFrames – 1) {
CurrentFrame = 0;
}
}
}
void CAnimation::SetFrameRate(int Rate) {
FrameRate = Rate;
}
void CAnimation::SetCurrentFrame(int Frame) {
if(Frame < 0 || Frame >= MaxFrames) return;
CurrentFrame = Frame;
}
int CAnimation::GetCurrentFrame() {
return CurrentFrame;
}
Some explanation on what this class is all about now. There is one basic element of animation that we need to handle, that is the current frame of the animation. Take the Yoshi image below for example (we’ll be using him in this tutorial). You’ll notice we have 8 frames of Yoshi on one image. Each frame would then be labeled 0, 1, 2 from Top to Bottom.

Remember the second tutorial where we create a function to draw part of an image? Well, if we take that function in conjunction with the frame of the animation, voila!
So the first variable I want you to see is CurrentFrame. This is the current frame of the animation that we are going to draw on the screen. Whatever value it has, will determine what part of the surface we will draw to the screen. So, when we call our draw function, we would do something like this:
Since our Yoshi is really 64 x 64 pixels, that’s the width and height we will grab, and is also how we grab the frame. Look at the image below for an illustration.

When the CurrentFrame increases by 1, we jump down 64 pixels (the height of Yoshi’s frame), and draw that frame.
The other part of this class is that we need to know how many frames this animation is, thus the MaxFrames. The last vital part to know is how many frames per second, or rather, how fast this animation is going to display. In order to determine that we find use this bit of code found in the OnAnimate function.
return;
}
By taking the Old Time in milliseconds plus the desired frame rate, we can check it against how long the SDL has been running. So, for example, we just started our program. SDL_GetTicks is 0, and OldTime is 0. Our desired frame rate is 1 frame per second. So FrameRate = 1000 (milliseconds). So, is 0 + 1000 greater than 0? No, thus we will skip over the function and wait. But once 0 + 1000 is less than SDL_GetTicks, that must mean 1 second has passed. So we increment the frame, and then reset OldTime to the current time, and start over.
The next interesting tid bit is Oscillate and FrameInc. Not that I wanted to confuse anyone by adding this, but I feel it’s necessary for certain things later on. Basically, when the Oscillate flag is true, the animation will increase frames, and then decrease frames. If we had an animation with 10 frames, it would do something like this:
0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 2 …
You see, it goes up to 9, and then decreases back down to 0, and so on. There are some interesting uses for this, but we’ll get into that in other lessons. So how does this work? Take a look at the OnAnimate function.
if(OldTime + FrameRate > SDL_GetTicks()) {
return;
}
OldTime = SDL_GetTicks();
CurrentFrame += FrameInc;
if(Oscillate) {
if(FrameInc > 0) {
if(CurrentFrame >= MaxFrames – 1) {
FrameInc = -FrameInc;
}
}else{
if(CurrentFrame <= 0) {
FrameInc = -FrameInc;
}
}
}else{
if(CurrentFrame >= MaxFrames – 1) {
CurrentFrame = 0;
}
}
}
We already know what the OldTime and such do, but what about the rest? For now, look at the else statement of the Oscillate if statement. You’ll notice we’re simply checking if the CurrentFrame has exceeded the Max Frames. If it has, reset back to 0. Pretty simple. Then below that, outside of the block, we increase to the next frame.
Now, the more confusing part is the Oscillate if statement. This is where the FrameInc variable comes in. Basically, the FrameInc is set to 1 or -1, depending on how we are increasing or decreasing the frames. Remember, Oscillating causes the frames to go from 0 to 9 back to 0. So if the FrameInc is greater than 0, we are increasing the frames, otherwise we are decreasing frames. The innermost if statements basically inverse the FrameInc if we reached the end of 0, or MaxFrames.
Now that that is all taken care of, lets put this class into action. Create a new CAnimation object within CApp.h:
Now, lets set the MaxFrames, add this to CApp_OnInit:
If you want to see your animation Oscillate, set this:
Okay, now to make our animation loop, add this to CApp_OnLoop:
Now, the last thing, to make it actually animate; add this to CApp_OnRender:
Now try compiling, and watch your Yoshi workout! Make sure you replace the myimage.bmp with the Yoshi image.
SDL Animation – Tutorial Files:
Win32: Zip, Rar
Linux: Tar (Thanks Gaten)
Did you like this tutorial/blog post? Feel free to donate to keep more comin', and have more contests.
Nice work… i am learning SDL it is very helpful tutorial to me..thanks
Chris,
You’re making it more difficult than it should be.
1) Load all your images at once
2) Have a variable that says which state they are in (0, 1, 2)
3) According to the variable state, display the correct image (and animate). Have a timer or whatever change the state after X seconds.
4) Once all done, free up all the surfaces
Hi, Tim;
I’ve been playing around with everything up to here, except events.
Basically, I’m making a loader for a game. I’m trying to figure out how to load an image, display it for a while, then load another image, which is animated, and then finally load a third image, which will also be animated. The second image is a loading bar; I took the Ubuntu stripy loading bar and extended it such that I have a bar that goes from empty to full. Anyway, I’m trying to animate the program so that it loads a logo at the top, then loads the loading bar, and once that is finished, it loads some credits.
Any ideas how I could do that?
If it’s any help, here are the files:
http://www.mediafire.com/?sharekey=19b4ee11c735202b7f7ec40ada4772a6e04e75f6e8ebb871
The larger, 260KB folder, is the more recent one.
Thanks.
Hi, thanks for the lovley guides, really easy and fun to follow.
On this tutorial I get a problem when compiling,
the line
“if(CurrentFrame >= MaxFrames – 1) {” is getting an error.
“In member function `void CAnimation::OnAnimate()’:”
“stray ‘\150′ in program”
“expected `)` before numeric constant”
Any idea on what is going wrong? I’m using dev-c++ compiler if that makes any difference, thanks in advance.
Acke,
After a quick google search (hint), the – (hyphen) is causing the problem. Delete it, and then type it in again. Then retry.
Thanks
Just came over this site. Very nice SDL tutorial. Thanks to the author for such interactive SDL tutorial. PS: I am looking forward for more tutorials.
Mohit,
Thanks! More tutorials coming soon… hopefully.
Just a quick question on the design choices you made Tim. Is there a particular reason you’ve included the framerate inside the animation class itself? It would make sense if you wanted different animations moving at different speeds (perhaps a slow spell in an RPG?) but this seems to be the exception rather than the rule.
Doesn’t it make more sense to create a timer class and use that to regulate framerate somewhere in either the CApp_OnRender file or in the body of the application object’s OnExecute while loop? That way you don’t have to check the time difference on each entity, and instead can check it once at the beginning of a render and just be done with it. If enough time has passed for the first entity to advance a frame, all subsequent entities will similarly be redrawn.
And further, what if all entities have had their state changed in OnLoop but the first half don’t get redrawn because not enough time has passed?
Anyway, I’m sure there are very good reasons for your decision, so please let us all know!
Again, thanks so much!
My Yoshi is not walking smoothly at some point.
When each foot is on the front, it moves twice.
Loop ( R_up, R_down, R_up, R_down, L_up, L_down, L_up, L_down)
This is what it looks like.
Thanks guys!
Great tutorial. Best tutorial i saw while searching for sdl tutorials in the web!
Great tutorial, and a great site all around. I’ve been looking for some concise, simple tutorials on topics such as Animation, for a while, off and on. It’s great to see an active SDL tutorials site, and with such good information too. Keep it up!