| |
|
PC Games
• Orb Tutorials
• 2D shoot 'em up Latest Updates
SDL2 Quest game tutorial
SDL2 Versus game tutorial
Download keys for SDL2 tutorials on itch.io
The Legend of Edgar 1.37
SDL2 Santa game tutorial 🎅
Tags • android (3) • battle-for-the-solar-system (10) • blob-wars (10) • brexit (1) • code (6) • edgar (9) • games (44) • lasagne-monsters (1) • making-of (5) • match3 (1) • numberblocksonline (1) • orb (2) • site (1) • tanx (4) • three-guys (3) • three-guys-apocalypse (3) • tutorials (18) • water-closet (4) Books ![]() Alysha When her village is attacked and her friends and family are taken away to be sold as slaves, Alysha Tanner sets out on a quest across the world to track them down and return them home. Along the way, she is aided by the most unlikely of allies - the world's last remaining dragon. |
Basic Tutorials Basic Game Tutorial #8 - Sprites and animation
Introduction The easiest way to approach an animation is to think of it as a series of images that are shown one after the other. This tutorial will show you one way of achieving this. Compile and run tutorial08. The star will spin on the screen until the window is closed or Escape is pressed. An in-depth look We will start this tutorial by looking at the animation file, data/anim/star.dat. The animation data file contains two lines. The first line is the number of frames in the animation and the rest are the names of the individual frames to load. This file is read by the loadAnimation function in animation.c which we will look at later. For the moment we will start with structs.h. We define a structure for our animation as follows:
typedef struct Animation
{
int frameCount, frameIndex, counter;
SDL_Surface **frame;
} Animation;
The frameCount variable stores the number of frames in the Animation.
frameIndex is the frame number that we are currently indexing.
counter is the timer we will count down from before incrementing the
frameIndex. Finally frame is an array of
pointers to SDL_Surfaces. We will now look at the animation.c
file.
The animation.c file contains 4 functions. As always, we will look at each one in turn.
void loadAnimation(char *name, Animation *anim)
{
/* Load up the data file that describes the animation */
int i;
FILE *fp = fopen(name, "rb");
char frameName[20];
if (fp == NULL)
{
printf("Failed to load animation file %s\n", name);
exit(1);
}
/* Read the frame count */
fscanf(fp, "%d", &anim->frameCount);
/* Allocate space for the animation */
anim->frame = (SDL_Surface **)malloc(anim->frameCount * sizeof(SDL_Surface *));
if (anim->frame == NULL)
{
printf("Ran out of memory when creating the animation for %s\n", name);
exit(1);
}
/* Now load up each frame */
for (i=0;i
The loadAnimation function takes 2 parameters, the animation file to load
and the address of the animation structure we wish to use. Firstly, we try and read the animation file and
if this attempt fails then we flag the error and exit. Once we have successfully opened the file we read the
first line of the file which is the number of frames in the animation and set this to the
frameCount. We then use this value to allocate the memory required for the frames.
Again, if this fails then we flag the error and exit. Now we loop through the frameCount,
read the location of the image and load it using the loadImage function. We then assign
the image to the current frame of the animation. If any of the images fails to load the will log the error and exit.
Once all the frames have been loaded, we assign the frameIndex to 0, which is the first
frame in the animation and set the counter to ANIM_SPEED.
void freeAnimation(Animation *anim)
{
int i;
/* Loop through each of the frames and free it */
if (anim->frame != NULL)
{
for (i=0;i<anim->frameCount;i++)
{
if (anim->frame[i] != NULL)
{
SDL_FreeSurface(anim->frame[i]);
}
}
free(anim->frame);
}
}
freeAnimation works by simply looping through all of the frames in the animation
and frees each one of them. We call this function once we are done with the animation.
Performing the animation is relatively straight forward:
void doAnimation(Animation *anim)
{
anim->counter--;
if (anim->counter <= 0)
{
anim->frameIndex++;
if (anim->frameIndex == anim->frameCount)
{
anim->frameIndex = 0;
}
anim->counter = ANIM_SPEED;
}
}
doAnimation is the function which updates the frames in the animation. It does this
by decrementing the counter of the animation. When the counter reaches zero or less,
we increase the frameIndex of the animation. If our frameIndex
is equal to the animation's frameCount, we set the frameIndex
back to 0 to continue to loop the animation. When we move another frame, we reset the counter
back to ANIM_SPEED, which is defined in defs.h.
The final function in this file draws the current animation frame:
void drawAnimation(Animation *anim, int x, int y)
{
drawImage(anim->frame[anim->frameIndex], x, y);
}
This function simply calls drawImage function and passes in the surface of the
animation's current frameIndex.
In graphics.c, we use the updateScreen function to draw our animation to the screen. In graphics.c, we call the drawAnimation function as follows: drawAnimation(&starAnim, 288, 216);We pass in the animation we wish to draw and render it to 288, 216 on the screen. Finally, in main.c, we load up the animation and update and draw it in our standard loop:
/* Load up the star animation */
loadAnimation("data/anim/star.dat", &starAnim);
/* Loop indefinitely for messages */
while (go == 1)
{
getInput();
/* Update the animation frame */
doAnimation(&starAnim);
/* Draw the animation to the screen */
updateScreen();
/* Sleep briefly to stop sucking up all the CPU time */
delay(frameLimit);
frameLimit = SDL_GetTicks() + 16;
}
Conclusion The disadvantage to the way that we have done animation is that any game objects using this method will all animate in synchronization. This might not be a bad thing though, depending upon what you want to do. In another tutorial we will look at making game objects animate independently. Downloads |