Moving Sprites With SDL
After my first SDL tutorial, you should have a pretty good idea of how to set up SDL and display an image on the screen. The next logical step is to read from the keyboard and make something move around on the screen.
This program builds on the example from tutorial 1 in a couple of places, so if you haven't read it yet, or if you're not clear on the basics of SDL, now's a good time to go check it out.
The Moving Sprite Program
Here's a breakdown of what's happening in this sample program.
- The program starts of just like the first example, SDL is initialized, the window is created, etc.
- The first difference is loading the sprite, not only do we convert the sprite to the display format, we also set a color key. This means that anything in the image that is purple (255, 0, 255), will be treated as transparent.
- The program then continues as before. The background is loaded, and we enter the main loop.
- After we check for events, we get the current state of the keyboard with SDL_GetKeyState(). This function returns a pointer to an array data describing each key on the keyboard. If a key is pressed, the array will contain a 1, otherwise it will contain 0.
- The keystate array is then tested for each of the arrow keys. If any arrow key is pressed, we will move the sprite in that direction.
- Now that things are moving, we must test to see if we've moved off the edge of the screen. If so, the sprite is moved back.
- Next the for loop blits the background tile all over the screen.
- Then the sprite is drawn over the background.
- The program ends as before, we free the memory for the surfaces with SDL_FreeSurface, and cleanup SDL with SDL_Quit().
Save this file as sdlmove.cpp, or sdlmove.c if you'd like to use straight C instead of C++. You'll also need the bitmap files that go with this program. They're available for download with the source code at the bottom of this page.
#include "SDL.h" #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 480 #define SPRITE_SIZE 32 int main ( int argc, char *argv[] ) { SDL_Surface *screen, *temp, *sprite, *grass; SDL_Rect rcSprite, rcGrass; SDL_Event event; Uint8 *keystate; int colorkey, gameover; /* initialize SDL */ SDL_Init(SDL_INIT_VIDEO); /* set the title bar */ SDL_WM_SetCaption("SDL Move", "SDL Move"); /* create window */ screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); /* load sprite */ temp = SDL_LoadBMP("sprite.bmp"); sprite = SDL_DisplayFormat(temp); SDL_FreeSurface(temp); /* setup sprite colorkey and turn on RLE */ colorkey = SDL_MapRGB(screen->format, 255, 0, 255); SDL_SetColorKey(sprite, SDL_SRCCOLORKEY | SDL_RLEACCEL, colorkey); /* load grass */ temp = SDL_LoadBMP("grass.bmp"); grass = SDL_DisplayFormat(temp); SDL_FreeSurface(temp); /* set sprite position */ rcSprite.x = 0; rcSprite.y = 0; gameover = 0; /* message pump */ while (!gameover) { /* look for an event */ if (SDL_PollEvent(&event)) { /* an event was found */ switch (event.type) { /* close button clicked */ case SDL_QUIT: gameover = 1; break; /* handle the keyboard */ case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_ESCAPE: case SDLK_q: gameover = 1; break; } break; } } /* handle sprite movement */ keystate = SDL_GetKeyState(NULL); if (keystate[SDLK_LEFT] ) { rcSprite.x -= 2; } if (keystate[SDLK_RIGHT] ) { rcSprite.x += 2; } if (keystate[SDLK_UP] ) { rcSprite.y -= 2; } if (keystate[SDLK_DOWN] ) { rcSprite.y += 2; } /* collide with edges of screen */ if ( rcSprite.x < 0 ) { rcSprite.x = 0; } else if ( rcSprite.x > SCREEN_WIDTH-SPRITE_SIZE ) { rcSprite.x = SCREEN_WIDTH-SPRITE_SIZE; } if ( rcSprite.y < 0 ) { rcSprite.y = 0; } else if ( rcSprite.y > SCREEN_HEIGHT-SPRITE_SIZE ) { rcSprite.y = SCREEN_HEIGHT-SPRITE_SIZE; } /* draw the grass */ for (int x = 0; x < SCREEN_WIDTH / SPRITE_SIZE; x++) { for (int y = 0; y < SCREEN_HEIGHT / SPRITE_SIZE; y++) { rcGrass.x = x * SPRITE_SIZE; rcGrass.y = y * SPRITE_SIZE; SDL_BlitSurface(grass, NULL, screen, &rcGrass); } } /* draw the sprite */ SDL_BlitSurface(sprite, NULL, screen, &rcSprite); /* update the screen */ SDL_UpdateRect(screen, 0, 0, 0, 0); } /* clean up */ SDL_FreeSurface(sprite); SDL_FreeSurface(grass); SDL_Quit(); return 0; }
Note, there is no error checking in this program. If something fails, it will be hard to track down. I left out the error checking just to make the program shorter and easier to follow. In a real program you should check the return values of all the SDL function calls.
Compiling
On Linux you can compile this program by typing this command:
g++ sdlmove.cpp `sdl-config --cflags --libs` -o sdlmove
Then run the program by typing:
./sdlmove
If everything worked correctly, a 640x480 window should open with a field of grass and a small sprite that you can move with the keyboard
In Visual C++ you'll need to follow these steps:
- Create a new empty Windows Application Project.
- Add the "sdltest.cpp" file to your project.
- On the menu click Project, then Properties.
- Double-click "Configuration Properties".
- Double-click "C/C++".
- Click "Code Generation".
- Change "Runtime Library" to "Multi-threaded DLL".
- Double-click "Linker".
- Click "Input".
- Beside "Additional Dependencies", type "sdl.lib sdlmain.lib".
At this point, you should be able to press F7 to Build the program.
Before we can run the program, you'll need to put the "SDL.dll" file where Windows can find it. Copy the file from "C:\Program Files\SDL-1.2.9" to your new Visual C++ project's folder. If your program compiled without errors, you can now press F5 to execute the program.
Downloads
- sdlmove.zip - Tutorial Source, Graphics, and Project files for Visual C++ 2005.
- sdlmove.tar.gz - Tutorial Source, Graphics, and Makefile for Linux.
Resources
Game Programming in C++ is a fairly new book that's getting good reviews. The examples in this book use SDL and OpenGL. There's only one book that I know of that just talks about SDL, Focus on SDL. The book that taught me the most about SDL is actually Programming Linux Games. This book is not just for Linux geeks, most of the information here can be applied to other platforms as well.
This is the next step in learning SDL. You should now be able to create simple games with moving sprites. Feel free to contact me if you have a suggestion about what I should cover next. I'm open for ideas.