NOGDUS

Articles, Tutorials, and other things. => SDL Game Programming => : Richard Marks March 07, 2009, 07:25:37 PM



: C++ and SDL Linux Game Development
: Richard Marks March 07, 2009, 07:25:37 PM
C++ and SDL Linux Game Development

I am going to assume a few things.
First; You are using ubuntu.
Second; You possess the knowledge of how to use your Linux system like running programs, installing, etc.

We will be needing these tools:
  • g++
  • scons
  • git
  • giggle
  • gedit
  • wget
  • SDL
  • SDL_image
  • SDL_mixer
  • Ruby
  • ImageMagick

If you don't have any of the aforementioned tools then find the right command below and execute it in a terminal.
:
$ sudo apt-get install binutils
$ sudo apt-get install g++
$ sudo apt-get install scons
$ sudo apt-get install git
$ sudo apt-get install giggle
$ sudo apt-get install gedit gedit-plugins
$ sudo apt-get install wget
$ sudo apt-get install libsdl1.2-dev
$ sudo apt-get install libsdl-image1.2-dev
$ sudo apt-get install libsdl-mixer1.2-dev
$ sudo apt-get install ruby1.8 ruby-full
$ sudo apt-get install imagemagick

Now, lets get our project directory setup.
I recommend you follow this to the letter.

:
$ cd ~/
$ mkdir Projects
$ cd Projects
$ mkdir SDLShooter
$ cd SDLShooter
$ mkdir src include docs release
$ mkdir release/data
$ mkdir release/data/graphics
$ touch readme.txt changes.txt SConstruct src/main.cpp src/SDLShooter.cpp include/SDLShooter.h
$ convert -size 640x480 plasma:fractal release/data/graphics/background.png
$ git init
$ git add .
$ git commit -a

You will be in an editor called Nano.
Type in "initial project started" hit ENTER, then press CTRL+O and hit ENTER to save changes then press CTRL+X to exit.

Now, we open all our source files and our build script into gedit:

:
$ gedit src/*.cpp include/*.h SConstruct &

Now we add our project's framework code.

main.cpp
:

// CODESTYLE: v2.0

// main.cpp
// Project: SDLShooter Project (SHOOTER)
// Author: Richard Marks

// C STANDARD LIBRARY
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cctype>
#include <cstdarg>

// STL
#include <vector>
#include <string>
#include <map>
#include <algorithm>

// SDL
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

// GAME
#include "SDLShooter.h"

int main(int argc, char* argv[])
{
// instance the game class
SHOOTER::Game game;

// init game
if (game.Initialize(argc, argv))
{
// make sure SDL exits correctly
atexit(SDL_Quit);

// start the main loop
game.Execute();

// clean up
game.Destroy();
}
else
{
fprintf(stderr, "Game Init Failed!\n");
}

// return to the OS
return 0;
}



SDLShooter.h
:

// CODESTYLE: v2.0

// SDLShooter.h
// Project: SDLShooter Project (SHOOTER)
// Author: Richard Marks
// Purpose: all game class definitions

#ifndef __SDLSHOOTER_H__
#define __SDLSHOOTER_H__

struct SDL_Surface;
union SDL_Event;

namespace SHOOTER
{
class Game
{
public:
/// constructor -- only purpose is to init every pointer to zero
Game();

/// destructor -- has no purpose. use Destroy() method
~Game();

// inits the game
bool Initialize(int argc, char* argv[]);

/// the main game loop
void Execute();

/// clean up after everything
void Destroy();

private:
/// stops the main loop
void Stop();

/// begin drawing the scene (clears the entire screen to black)
void BeginScene();

/// no drawing should take place after this (flips screen buffers so we see what we have drawn)
void EndScene();

private:
/// the SDL screen
SDL_Surface* mainScreen_;

/// the SDL event
SDL_Event* mainEvent_;

/// used by the main loop to tell if we should end it or not
bool gameIsRunning_;

}; // end class

} // end namespace
#endif


SDLShooter.cpp
:

// CODESTYLE: v2.0

// SDLShooter.cpp
// Project: SDLShooter Project (SHOOTER)
// Author: Richard Marks
// Purpose: all game class definitions

// C STANDARD LIBRARY
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cctype>
#include <cstdarg>

// STL
#include <vector>
#include <string>
#include <map>
#include <algorithm>

// SDL
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

#include "SDLShooter.h"


namespace SHOOTER
{
Game::Game() :
mainScreen_(0),
mainEvent_(0),
gameIsRunning_(false)
{
}

////////////////////////////////////////////////////////////////////////////

Game::~Game()
{
}

////////////////////////////////////////////////////////////////////////////

bool Game::Initialize(int argc, char* argv[])
{
// initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
// log the error
fprintf(stderr, "SDL Library Initialization Failed!\n\tSDL Error: %s\n", SDL_GetError());

// return failure
return false;
}

// initialize the screen
mainScreen_ = SDL_SetVideoMode(800, 600, 24, SDL_HWSURFACE | SDL_DOUBLEBUF);

if (!mainScreen_)
{
// log the error
fprintf(stderr, "SDL Screen Initialization Failed!\n\tSDL Error: %s\n", SDL_GetError());

// return failure
return false;
}

// set the window caption
SDL_WM_SetCaption("SDLShooter -- An SDL game project by Richard Marks <ccpsceo@gmail.com>", 0);

// create the SDL event handler instance
mainEvent_ = new SDL_Event;
if (!mainEvent_)
{
// log the error
fprintf(stderr, "Unable to create event handler instance!\n");

// return failure
return false;
}

// start our engines ^-^
gameIsRunning_ = true;

// return success
return true;
}

////////////////////////////////////////////////////////////////////////////

void Game::Destroy()
{
#define _TMP_DELOBJ(object) if (object) { delete object; object = 0; }

// we do NOT delete the mainScreen_ variable because SDL does that itself!
_TMP_DELOBJ(mainEvent_)

#undef _TMP_DELOBJ
}

////////////////////////////////////////////////////////////////////////////

void Game::Execute()
{
// better input handling
const int MOTIONBUTTON_UP = 0x0;
const int MOTIONBUTTON_DOWN = 0x1;
const int MOTIONBUTTON_LEFT = 0x2;
const int MOTIONBUTTON_RIGHT = 0x3;
bool motionButtonDown[4] = { false, false, false, false };

// main loop
while(gameIsRunning_)
{
// process the events
while(SDL_PollEvent(mainEvent_))
{
switch(mainEvent_->type)
{
// the window was closed
case SDL_QUIT:
{
// stop the engine
this->Stop();
} break;

// a key was pressed
case SDL_KEYDOWN:
{
// what key is down
switch(mainEvent_->key.keysym.sym)
{
case SDLK_ESCAPE:
{
// stop the engine
this->Stop();
} break;

case 'w':
case 'W':
case SDLK_UP:
{
motionButtonDown[MOTIONBUTTON_UP] = true;
} break;

case 's':
case 'S':
case SDLK_DOWN:
{
motionButtonDown[MOTIONBUTTON_DOWN] = true;
} break;

case 'a':
case 'A':
case SDLK_LEFT:
{
motionButtonDown[MOTIONBUTTON_LEFT] = true;
} break;

case 'd':
case 'D':
case SDLK_RIGHT:
{
motionButtonDown[MOTIONBUTTON_RIGHT] = true;
} break;

default: break;
} // end switch
} break;

// a key was released
case SDL_KEYUP:
{
// what key is up
switch(mainEvent_->key.keysym.sym)
{
case 'w':
case 'W':
case SDLK_UP:
{
motionButtonDown[MOTIONBUTTON_UP] = false;
} break;

case 's':
case 'S':
case SDLK_DOWN:
{
motionButtonDown[MOTIONBUTTON_DOWN] = false;
} break;

case 'a':
case 'A':
case SDLK_LEFT:
{
motionButtonDown[MOTIONBUTTON_LEFT] = false;
} break;

case 'd':
case 'D':
case SDLK_RIGHT:
{
motionButtonDown[MOTIONBUTTON_RIGHT] = false;
} break;
default: break;
}
} break;

default: break;
} // end switch
} // end while


////////////////////////////////////////////////////////////////////
// update game objects
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// render game
////////////////////////////////////////////////////////////////////

// begin the scene
this->BeginScene();

// draw objects here

// end the scene
this->EndScene();

// reduce the cpu hoggingness of SDL ^-^
SDL_Delay(20);


} // end while -- main loop
}

////////////////////////////////////////////////////////////////////////////

void Game::Stop()
{
gameIsRunning_ = false;
}

////////////////////////////////////////////////////////////////////////////

void Game::BeginScene()
{
SDL_FillRect(mainScreen_, 0, SDL_MapRGB(mainScreen_->format, 0, 0, 0));
}

////////////////////////////////////////////////////////////////////////////

void Game::EndScene()
{
SDL_Flip(mainScreen_);
}

} // end namespace


Finally, here is the SConstruct file that will build our project:

SConstruct
:
#
# SConstruct
# this scons build script produces the executable for the project
################################################################################
# a little preparation for building an SDL project
buildEnv = Environment(CCFLAGS = '-g -Wall')
projectConfig = {}
buildEnv.ParseConfig('sdl-config --cflags --libs')

################################################################################
# this is the file name of the executable file to output
projectConfig['executable'] = 'GameExe'
################################################################################
# if you need to look in special folders for include files add them here
projectConfig['include path'] = Split("""
.
./include/
""")
################################################################################
# if your libs are in special locations set their paths here
projectConfig['library path'] = Split("""
""")
################################################################################
# if you need to link against other libs, add them here
projectConfig['libraries'] = Split("""
SDL_image
""") + buildEnv['LIBS']
################################################################################
# add your sources for your project here
projectConfig['sources'] = Glob('src/*.cpp')
################################################################################
buildEnv.Program('release/'+projectConfig['executable'], projectConfig['sources'],
LIBS = projectConfig['libraries'],
LIBPATH = projectConfig['library path'],
CPPPATH = projectConfig['include path'])
################################################################################

Save everything.
Now, in your terminal:

:
$ scons
$ cd release
$ ./GameExe

Cool eh? 8)


Sorry, the copyright must be in the template.
Please notify this forum's administrator that this site is missing the copyright message for SMF so they can rectify the situation. Display of copyright is a legal requirement. For more information on this please visit the Simple Machines website.