Hello.
I write games in C++, using SDL and OpenGL (mostly). Here I will update and maintain a list of snippets that you might find useful. I post this in the tutorial section because you could learn from it.
I'll begin with an SDL Event handling system.
events.h:
#ifndef EVENTS_H_INCLUDED
#define EVENTS_H_INCLUDED
#include "SDL.h"
class EventHandler
{
public:
virtual void handle(const SDL_Event sdl_event) = 0;
EventHandler();
~EventHandler();
};
void updateEvents();
#endif
events.cpp:
#include <deque>
#include "events.h"
std::deque<EventHandler*> handlers;
EventHandler::EventHandler()
{
handlers.push_back(this);
}
EventHandler::~EventHandler()
{
bool found = false;
for(unsigned int i = 0; i < handlers.size() && !(found); i++)
{
if(handlers[i] == this)
{
found = true;
handlers[i] = handlers[handlers.size() - 1];
handlers.pop_back();
}
}
}
void updateEvents()
{
SDL_Event sdl_event;
while(SDL_PollEvent(&sdl_event) > 0)
{
for(unsigned int i = 0; i < handlers.size(); i++)
{
handlers[i]->handle(sdl_event);
}
}
}
This is basically a listener that registers once it's instantiated. Read more:
http://en.wikipedia.org/wiki/Observer_patternNow, let's say you want to
use the event handling system I showed above.
Let's write a mouse class!
mouse.h:
#ifndef MOUSE_H_INCLUDED
#define MOUSE_H_INCLUDED
class MouseEventHandler;
class Mouse
{
public:
friend MouseEventHandler;
enum ButtonState
{
BUTTONSTATE_UP,
BUTTONSTATE_DOWN
};
private:
ButtonState left;
ButtonState middle;
ButtonState right;
unsigned int x;
unsigned int y;
signed int offx;
signed int offy;
public:
bool isLeftButtonDown() const { return left == BUTTONSTATE_DOWN; }
bool isMiddleButtonDown() const { return middle == BUTTONSTATE_DOWN; }
bool isRightButtonDown() const { return right == BUTTONSTATE_DOWN; }
bool isLeftButtonUp() const { return left == BUTTONSTATE_UP; }
bool isMiddleButtonUp() const { return middle == BUTTONSTATE_UP; }
bool isRightButtonUp() const { return right == BUTTONSTATE_UP; }
unsigned int getX() const { return x; }
unsigned int getY() const { return y; }
signed int getXOffset() const { return offx; }
signed int getYOffset() const { return offy; }
Mouse();
};
extern Mouse mouse;
#endif
mouse.cpp:
#include "mouse.h"
#include "events.h"
Mouse mouse;
class MouseEventHandler : public EventHandler
{
public:
void handle(const SDL_Event sdl_event)
{
switch(sdl_event.type)
{
case(SDL_MOUSEBUTTONDOWN):
switch(sdl_event.button.button)
{
case(SDL_BUTTON_LEFT):
mouse.left = Mouse::BUTTONSTATE_DOWN;
break;
case(SDL_BUTTON_MIDDLE):
mouse.middle = Mouse::BUTTONSTATE_DOWN;
break;
case(SDL_BUTTON_RIGHT):
mouse.right = Mouse::BUTTONSTATE_DOWN;
break;
}
break;
case(SDL_MOUSEBUTTONUP):
switch(sdl_event.button.button)
{
case(SDL_BUTTON_LEFT):
mouse.left = Mouse::BUTTONSTATE_UP;
break;
case(SDL_BUTTON_MIDDLE):
mouse.middle = Mouse::BUTTONSTATE_UP;
break;
case(SDL_BUTTON_RIGHT):
mouse.right = Mouse::BUTTONSTATE_UP;
break;
}
break;
case(SDL_MOUSEMOTION):
mouse.x = sdl_event.motion.x;
mouse.y = sdl_event.motion.y;
mouse.offx = sdl_event.motion.xrel;
mouse.offy = sdl_event.motion.yrel;
break;
}
}
};
MouseEventHandler mouse_event_handler;
Mouse::Mouse() :
left(BUTTONSTATE_UP),
middle(BUTTONSTATE_UP),
right(BUTTONSTATE_UP),
x(0),
y(0),
offx(0),
offy(0)
{
}
Please note that for the mouse to work, you need to use the mouse in the header. Don't instantiate your own. However, for unit testing, you could write your own handler & use that. I didn't make it a singleton just because of unit testing. More about singletons:
http://en.wikipedia.org/wiki/Singleton_patternBy the way, to see it in action:
main.cpp:
#include <exception>
#include "SDL.h"
#include "events.h"
#define GAME_NAME "Sample Game 1"
bool running = true;
class WindowEventHandler : public EventHandler
{
public:
void handle(const SDL_Event sdl_event)
{
if(sdl_event.type == SDL_QUIT)
{
running = false;
}
}
};
int main(int argc, char* argv[])
{
try
{
if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
throw(std::runtime_error(SDL_GetError()));
}
SDL_WM_SetCaption(GAME_NAME, NULL);
if(SDL_SetVideoMode(852, 480, 0, SDL_OPENGL) == NULL)
{
throw(std::runtime_error(SDL_GetError()));
}
WindowEventHandler window_event_handler;
while(running)
{
updateEvents();
}
SDL_Quit();
}
catch(std::runtime_error& error)
{
fprintf(stderr, "%s", error.what());
return 1;
}
return 0;
}
More will come, so stay up to date!