Getting Comfortable with C++ and SDL

Ranked #26,152 in Education, #497,387 overall

It Won't Bite!

Sometimes, just seeing those two little plus signs is enough to scare away a potential game developer. But take heart! Programming in C++ is no harder than any other part of the development process. In fact, there is something fun about turning a logical sequence of game events into neat, impressive code.

By the way, this is the second in a series of tutorials addressing hopeful game developers. If you missed the first section ("Getting Started"), you can view it here: squidoo.com/gametutorials_gettingstarted.

The Anatomy of a Program

C++ programs always follow this format:


#preproccessor directives

int main(int argc, char *argv[]) {

// this is where we'll write the code

return 0;
}


Preproccessor directives (don't let the name scare you!) are simply instructions that tell the compiler to do something before your program is run. The two most common directives are #include (which is used to include code that is already written, so we don't have to rewrite it every time) and #define (which we use to substitute certain letters for something else).

int main(int argc, char *argv[]) is called a function header. Yikes, but doesn't it look complicated! Well, it actually is - but don't worry! I'll try and explain it the best I can, but you won't have to create anything this complex when you write your own functions. This line simply means, "main is a function that takes 2 parameters, an integer number named argc and a pointer to an array of characters named argv, and when it is called, it returns its answer as an integer (int)." In fact, main is a special function that we always write in every program. It tells the computer where to start executing your program. In case you were curious, argc stands for argument count - it tells your program how many arguments (parameters) were passed to your main function when it was started. argv is stands for "argument vector" and it actually contains the arguments that were passed in. But because we won't be dealing with command line programs, these parameters will not interest us much here.

The curly braces ({}) wrap around a function body show what is part of the function and what is not.

The line // this is where we'll write the code does nothing at all. Because it starts with //, it's called a comment and will have no effect on your program. You can put comments anywhere in your program.

The line return 0; is an "answer" to the function definition. (Remember? We started out function definition with int. Thus we must return an integer.) Because this is the main function, the return code has special meaning: a zero indicates that everything went smoothly with no errors. Later, when we write our own functions, we will make great use of the return statement. The semicolon after the zero means "end of statement". Besides function declarations and preprocessor directives, just about every statement must end with a semicolon.

My First Program

Not your typical "Hello World"

When most people learn C++, they start by writing some cute little phrase like "Hello World!" onto a console window (think MS-DOS). But I realize you're here to make games, and so I'll skip the baby steps for today (but if you are interested in crawling into the world of C++ instead of diving in headfirst, as we are about to, check out any book about C++ or try a Google search).

So now it's time to fire up Dev-C++. Remember, we made a shortcut to it inside of the GameDev folder during the last tutorial. Once you're staring at a blank Dev-C++ window, select File > New > Project. Click the Multimedia tab and select SDL. Where it says name, type "MyFristProgram" (or something along those lines). Now this is a good habit to get into: every time you make a new project and you are prompted with the "Save File" window, always create a new folder inside PROJECTS with the same name as your project (in our case, "MyFirstProgram"). Save your project into the new folder.

Something like 150 lines of code should pop up. Don't worry about it. Just select everything and clear it out, so you have a blank slate.

I'm going to give you the program one line at a time and explain it. Don't just copy and paste it! Read each line, and the explanation that follows, and type it by hand. Otherwise you won't learn to do it on your own.

#include <SDL/SDL.h>

This is the first line of our program. It means that we will be using the SDL functions and datatypes from the SDL header file. The <> brackets tell Dev-C++ that this is among the "standard" header files (we made it standard by installing that devpak a while back).

int main (int argc, char *argv[]) {

There's our friendly main function again.

SDL_Surface *screen;

This statement is declaring a variable named screen as an SDL_Surface pointer. An SDL_Surface is basically a picture we can draw onto the screen. In 2D SDL game programming, everything you see on the screen is an SDL_Surface. screen happens to be a surface that we will use to represent the whole game window. The asterisk means "this is a pointer" and the screen does just that - instead of actually being an SDL_Surface, it points somewhere in your computer's RAM at a block of memory the size of an SDL_Surface (don't worry about what that means just yet).

Uint8 *keys;

This is very similar to the last statement. Uint8 is a data type that means unsigned (meaning not negative) integer that is 8 bits long. There's really no sense in going into what bits are versus bytes, etc., but suffice it to say that an 8 bit number can hold the values 0-255. Why are we using such a small range? Well, as you might have guessed, keys will hold (or rather, point to - remember the asterisk) the state of the keyboard. We really only need two values for each key: up (0) and down(1). How can one variable hold the information of every key? Well, that's why we made it a pointer. We will change where it points to get information about different keys.

SDL_Init (SDL_INIT_VIDEO);

This is a standard SDL function that sets up the rest of the SDL functions. SDL_INIT_VIDEO is a code that means we'll be using 2D video functions.

screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);

This is the line that opens up our game window. SDL_SetVideoMode takes four arguments. The first two are the width and height of the window, respectively, the third is the color depth we want to use (16 is pretty low, but fine for most purposes), and the last is a combination of codes that tell SDL how to set up the window. In this case, we want a software surface (slow but okay) and we want it to be double-buffered (an absolute necessity for games). SDL_SetVideoMode returns a pointer to the window it set up, which we are assigning to the screen pointer we just created.

SDL_WM_SetCaption ("Hello World!", NULL);

Here's a fun one. SDL_WM_SetCaption (WM stands for window manager) sets the title bar of our window. Come on, we had to work "Hello World" in somewhere!

keys = SDL_GetKeyState(NULL);

Like we did with the screen variable, we are setting keys to point at the area in memory, this time where the key states are located. NULL means that we are ignoring the first (and only) argument of SDL_GetKeyState.


while (keys[SDLK_ESCAPE] == false) {
    SDL_PumpEvents();
}


Let's call these lines the "game loop". This is where you'd draw enemies, check for game events, interact with the player, etc. It is a while loop, meaning it will loop until the condition is parenthesis is fulfilled. In our case, we're saying "run this stuff in curly brackets while the escape key code is 0 (up)" (that is, until the escape key is pushed). The square brackets ([]) after keys mean that the keys pointer is shifting to a different place in memory. The code SDLK_ESCAPE is the location in memory where the escape key code is located. The function SDL_PumpEvents(); updates the area in memory where keys is pointing - it pumps the state of the keyboard (among other things). That way, if the state of the keys changes (meaning the escape key is pushed) our while loop will catch it when it repeats.

return 0;
}


The standard ending of a C++ program.

The Exciting Result

If this is what you see, congradulations on your first successful SDL program! Remember to hit Escape to exit!



Here's the full program, so you can see if you messed up:


#include <SDL/SDL.h>

int main (int argc, char *argv[]) {

    SDL_Surface *screen;
    Uint8 *keys;

    SDL_Init (SDL_INIT_VIDEO);
    screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
    SDL_WM_SetCaption ("Hello World!", NULL);

    keys = SDL_GetKeyState(NULL);

    while (keys[SDLK_ESCAPE] == false) {
        SDL_PumpEvents();
    }

    return 0;
}

Other Game Developer Tutorials

Game Development: Getting Started
Part 1 of this series
Game Development: Getting Comfortable with C++ and SDL
Part 2 of this series (you're lookin' at it!)

Did You Learn Something?

Any pointers on how I could make this tutorial more accurate, understandable, or interesting would be very appreciated. If I have sparked your interest in game development or if you learned something new, please let me know!

  • David Oct 29, 2009 @ 1:51 pm | delete
    this was awesome, but it's a real shame you didn't post more :/
  • DM Oct 1, 2009 @ 11:36 am | delete
    Great tutorial! Works just fine on any resolution, If you'l get the chance you should post some further tutorials and explain how to create some animations or something like that.

    Thanks!
  • Max Jul 28, 2009 @ 7:45 am | delete
    Nice work.
  • un_criado_fiel Jun 2, 2009 @ 12:44 am | delete
    This is another great tutorial. I would really like to know how to make a game, so don't fall off the charts.

by

WeekendEngineer

Critically damped.

Feeling creative? Create a Lens!