D2TM Rewrite – Development Blog – SDL initialization & initial game setup

In my previous post I have described a way to compile your project with a Maven style like project structure. Using that as basis I am busy rewriting my project Dune II – The Maker. This time I am using SDL.

Because I have started over I thought of writing blog posts about my progress. Blog posts will be about progress made, decisions taken, etc. This is by no means a real tutorial sequence, but you could follow the blog posts probably and make something out of it. Do note: In reality I am much further in development then my blog posts. The blog posts are based upon older revisions than HEAD. If you are interested in the most recent version you can get the source yourself.

In this blog post I will describe how I have started to setup the project. I already have a directory structure as described in my previous blog post.

My goal is to have a primitive architecture set up, I have used the first SDL tutorial as starting point.

The reason I went with a tutorial is that I wanted to be inspired by a different approach than I have done myself in the past. In fact, I have always just tried to do what I thought what was best. In this case I took the tutorial and from there I will change it how I think it should be. Its never bad to take a fresh look at things 🙂

The very first start was to create a Game class, it has the following class declaration:

#ifndef GAME_H
#define GAME_H

#include <SDL/SDL.h>   /* All SDL App's need this */

class Game {

	public:
		int execute();

	private:
		bool running;

		int init();
		void shutdown();

		void handleEvents();
		void update();
		void render();

		void onEvent(SDL_Event * event);

		SDL_Surface * screen;

};

#endif

The only function that needs to be exposed is the execute method. All other functions are used internally.
The SDL surface screen represents the main display (screen).

The Game class is implemented as follows:

#include "gamerules.h"
#include "game.h"

#include <iostream>

using namespace std;

int Game::init() {
	if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) {
        	printf("Could not initialize SDL: %s.n", SDL_GetError());
	        return -1;
	}

	screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
	if ( screen == NULL ) {
		printf("Unable to set 640x480 video: %sn", SDL_GetError());
		return -1;
	}

	return 0;
}

void Game::handleEvents() {
	SDL_Event event;
	while (SDL_PollEvent(&event)) {
		onEvent(&event);
	}
}

void Game::onEvent(SDL_Event * event) {
	if(event->type == SDL_QUIT) {
		running = false;
	}
}

void Game::update() {

}

void Game::render() {

}

void Game::shutdown() {
	SDL_Quit();
}

int Game::execute() {
	if (init() != 0) {
		return -1;
	}

	while (running) {
		handleEvents();
		update();
		render();
	}

	shutdown();

	return 0;
}

The execute function does basically everything. A game loop is in essence very simple. In fact the game is one big loop which does two things:
– update state
– show state

To update state, in this case we have separated two things:
– handle events (in SDL terminology, this means we handle input events. Which can have effect on the game state)
– update (here you actually update the game state)

That still remains updating game state, though a bit more split up. We could later split it into keyboard/mouse states. But, these things all are depended on the certain kind of game state you’re in. A main menu screen should react differently on mouse input than lets say the actual game playing. The current design has not given any direction yet what to do. We could have one big switch statement, but we could also do something better… I’ll come to that in a future blog post.

The init function basically sets up the application. I am not too happy about this in this stage, but for the initial setup it is good enough. I believe the factory pattern should be used for constructing a game object though, so I have already created a class for it. The reason is that i want to respect the Single Responsibility Principle. Constructing a Game object, which requires loading resources, setup SDL, etc, has nothing to do really with the basic Game object itself. In fact, as you will see in later blog posts, the Game object has the only responsibility and that’s calling all the right collaborator classes that make the game what it is.

Since I already know I will be using a factory class I already introduce one which for now does nothing spectacular:

Header:

#ifndef GAMEFACTORY_H
#define GAMEFACTORY_H

#include "game.h"

class GameFactory {

	public:
		Game create();

};

#endif

Implementation:

#include "gamefactory.h"

Game GameFactory::create() {
	Game game;

	// TODO: load resources for game, do SDL initialization, etc.

	return game;
}

Finally the main.cpp which has the entry point of the application:

#include "gamefactory.h"

int main(int argc, char **argv) {
	GameFactory gameFactory;
	Game game = gameFactory.create();
	return game.execute();
}

And thats it! The result is a game that is able to start, it has functions that declare several phases in the game and allows us to expand it further. Because of the factory we can also easily move initialization code out of the Game class.

If you would compile this, and run it, you would see:

A running application

As for developing applications, I believe a certain principle lies behind it. Most of it, you won’t really see. Often, with a few lines of code you can make a lot of stuff happen on the screen. But the actual work is ‘under water’:

Comments

    1. No, this is not TDD driven. Although I do have written a test later on. But really test driven is still something I’d like to know more of. The project structure should allow it now, I can compile and run a test seperately, which was impossible in the old source code. Its on my TODO list though 😉

      Testing in C/C++ is doable, but it is not as ‘nice’ and fluent as in Java or C# (or Ruby for that matter). I bet some real experienced C/C++ programmers have found ways to make it much more fluent and to get real tight red-green-refactor loops, but I haven’t found any yet.

        1. Be my guest to try it in Ruby, I have all the resources you need (gfx wise). Would be cool to see a Ruby attempt 😉

      1. I’m checking out Rubygame, seems abandoned. Actually, I’d like to confer with you about the game aspects, you have far more experience. First step will be decoding the assets.

        1. No need to decode assets, you can grab a bunch from here.

          What do you want to discuss? I will blog more about how I set the game up, like the next post will be about drawing stuff on the screen (simple challenges), so I can start drawing a terrain/map.

          My advice would be, just do, try, experience, learn! (and have fun! :))

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.