Christian Vucossa programming blog

game programming, daily troubles and solutions

Posts Tagged ‘c++’

Finite State Machine: a C++ implementation

Posted by Christian on May 29, 2009

For those who don’t know what a FSM is, here is a summary.

I think FSM are well used in game development, from purposes like AI to game state management.

You know, you have to deal with splash screens, menus, dialogs and so forth, and you need a way to decide what to put on screen at each loop. You can arrange your code into the BUS (aka Big Ugly Switch) and check for a state flag. This works, and I used it many times. Sure, it is not beauty nor elegant (after all, it’s Big and Ugly!) and, if you plan to add features (states) later, you must put other case statement. It is Big because it grows fast.

But there is another way to do the same. If you model your software in a sequence of states, each of them can receive input and generate output, and something catch this output and put on the field another appropriate state which can continue the work, well, you have an OO solution to your problem. Which means that it’s elegant. Which means that you can speak of it with your friends. Which is cool. Well, which is not the Big Ugly Switch…

FSM are this solution. I implemented a really basic version in C++. I have two classes:

  1. FSMState, which is a single state in my machine
  2. FSMManager, which handle the states and make them work together.

In addition, I put a couple of enums which are application-related… you can get rid of them and use simple int values.

So, here are my definitions (fsm.h)

class FSMManager;

enum RawInputType
{
RIT_ESC, RIT_SPACE, RIT_AKEY
};

enum HighInputType
{
HIT_IDLE=0, HIT_EXIT_GAME, HIT_SKIP_SPLASH
};

enum StateId
{
// application states
SID_IDLE=0, SID_SPLASH, SID_MENU, SID_BRIEFING, SID_PLAY, SID_PAUSE,
SID_EXIT, SID_QUIT
};

class FSMState
{
friend class FSMManager;

public:
FSMState(int iId);

// methods to program the state
void addInputPair(RawInputType, HighInputType);
void addTransition(HighInputType, int);

// run the execution
virtual void run();

protected:
void sendInput(RawInputType);
int getOutput();

private:
int m_iId;
HighInputType m_lastInput;
std::map<RawInputType, HighInputType> m_inputTable;
std::map<HighInputType, int> m_transitionTable;

};

class FSMManager
{
public:
FSMManager();

void addState(FSMState*, bool current = false);
void sendInput(RawInputType);
FSMState* getCurrentState();

private:
std::map<int, FSMState*> m_stateTable;
FSMState* m_pCurrentState;
};

The RawInpuType and HighInputType enums are filled with some sample values. The first maps a physical input, such the ESC key press. The second maps a logic input, application-related, such as “Player want to exit”.

FSMState has three public methods, one of them virtual:

  1. addInputPair simply maps physical inputs with logic inputs, in a way that is coherent with the state logic (ESC key may means “Exit from game” in the menu screen, but may means “Go to menu” while playing).
  2. addTransition maps the relative state to which go after a logic input is triggered. Each state has an ID which identify it (in this case it follows the StateId enums, but I used an int cause I plan to use this design to implement some AI too).
  3. run is virtual because real states will inherit from this class and reimplement. For test purposes I left it virtual and not pure virtual, but you can think of it as a pure virtual if you want.

The FSMManager class has a collection of states (pushed in via the addState method), but only one of them is the current state. Current state receive the raw input (which comes from another component, not present in this design) and produces an output (a new state if there is a transition, or itself) which updates the current state itself. This way a single input catching routine can pass the input through the FSMManager to the actual state, which has been programmed to give a result and maybe do a transition. At every loop the run method is called for the current state, which can perform drawings or just some logic (update of other object’s state or… what else you need).

Implementation of these methods are quite straight and boring. I put only the sendInput of the FSMManager, which actually performs the inner state transition:

void FSMManager::sendInput(RawInputType raw)
{
if(m_pCurrentState != 0)
{
m_pCurrentState->sendInput(raw);

int output = m_pCurrentState->getOutput();
map<int, FSMState*>::iterator imap = m_stateTable.find(output);
if(imap != m_stateTable.end())
{
m_pCurrentState = imap->second;
}
else
{
// no state change
}
}
}

That’s all, bye.

Posted in game programming | Tagged: , | Leave a Comment »

The float to int conversion’s big mystery

Posted by Christian on December 31, 2008

Someone must explain me this thing… I was working on my roguelike, namely the wall collision, when I came across one of the strangest things seen recently. My issue was to convert space coordinate of my @ into 2d matrix coordinate of the map, a bi-dimensional array. My space2map function perform some calculation and give me a x,y values, quite straight.

It seemed to work, but after a bit of testing things began to go wrong… when I was expecting a 2 I get a 1 instead, or the like. For some debugging hours I was sure I was wrong, but in the end I found myself in front of a thing like this:

(0.2 + 0.3) / 0.5 = 0

It was enough to make me think that yes, math is an opinion. A compiler opinion, at least.

After a while google gave me the answer: there is something on the float to int conversion. A really magic function came with the answer, this:

int iround(float x)
{
return (int)floor(x + 0.5);
}

where floor() is the math.h C function.

I tried with this and it works. Then, I wrote a simple program to test this mystery, and this is the result:

The float to int test

The float to int test

For the record, this happens on GCC for Ubuntu 8.04.

Posted in exception solving | Tagged: | Leave a Comment »

3D Pong collision detection: the simple way

Posted by Christian on December 12, 2008

As said in previous posts I’m actually working on a Pong clone in OpenGL, SDL and C++.

Topic of this post is Pong’s collision detection.

In a 2D environment this is quite easy and deserve of a very poor math, since we have a defined screen resolution, defined objects size and a perfect 1 to 1 relationship between units and pixels. We simple need of some x,y calculations.

But what in a 3D env? First, we don’t have relationship between pixels and units. Second, object can be translated and scaled, which means their size can change.

There are quite a few algorithms for 3D collision detection, I know of their existance but I master only one of them at the moment: Bounding Spheres.

Anyway, I tried with bounding spheres (which probably will be topic for another post) but I realize this is not the best suitable alg for the cause. In Pong we have to deal mostly with stretched cubes, and a sphere is not the best geometric figure to surround them. What we need is probably a Bounding Box version of the algorithm but… wait a moment.

Maybe what we really need is only a 3d adaption of our old, plain 2D algorithm.

Sure, we can’t tell how long or how fat is our racket or our ball, but we can calculate where object is on the 3D space, and with a little effort we can tell which vertex is the more up, the more right, the more left and the more bottom.

We can do that simply passing through all our object’s vertexes and locate the one with the higher y value, which will be the most up, then the one with the lowest y, the most bottom and so on with the x values.

At the end we have 4 vertexes for every object in the scene describing their borders.

But the ball is moving, and the rackets too. We need to keep update this borders with the object’s translations. But this is simple: if object translate up (0,1,0) we translate up all 4 border vertexes by the same values. Vertexes follow the object movements, of course.

And if the object scales? Well, we scale the borders too in the same way.

So, here we are with our vertexes. And now? Eheh, now the easy part. Each loop we only have to  check ball borders with rackets and field opposite borders in order to detect collisions.

For example: if ball’s right border is major or equal to player 2 racket’s left border (assuming player 2 is the one on the right) we have a collision.

if( ball.maxX() >= player2.minX() ){

ball.collideRight();

}

Easy, isn’t it?

Posted in game programming | Tagged: , , | Leave a Comment »

SDL: SDL_KeyboardEvent too slow?

Posted by Christian on December 11, 2008

Once again my OpenGL Pong clone gave me a chance to dig more into the common game programming issues.

This time the problem is SDL and its way to manage user keyboard input: SDL_KeyboardEvent.

The scenario is the following: I have my ball bouncing from one side of the game field to the other and my racket that should move up and down according to some key press events. Really simple. But…

The racket moves too later. I press the key, wait for about a second, and then that white rectangle of pixels decide to obey. Too, too too late.

So what? SDL is slow? No, once again computer is right and I’m wrong.

The issue is on my fps. Scene is rendered too speedy, more than 900 times per second. My handleInput() routine is placed at the very beginning on the game loop and no one knows when exactly the “key pressed” event is fired and catched. I have to tell the truth: I don’t know exactly why this happens, but happens. And I found the trick that solve it.

Delay.

Simply reduce in an artificial way the loop speed and the magic will happens: the keyboard response becomes immediate.

How to do that? Using SDL_Delay and SDL_GetTicks to force the fps below to a maximum rate.

At the beginning of the loop you take the current number of ticks and at the end do the same. Then check the difference with a costant of your choice and delay the loop of the difference. Something like that:

Uint32 start = SDL_GetTicks();

/* do graphic stuff and all the game loop logic */

Uint32 end = SDL_GetTicks();

if(end – start < MAX_FPS_RATE){

SDL_Delay(MAX_FPS_RATE – (end – start));

}

I’ve used 33 as MAX_FPS_RATE to have about 30 fps and all the inputs works great.

Posted in game programming | Tagged: , , | Leave a Comment »

OpenGL: how Display Lists can improve performaces

Posted by Christian on December 10, 2008

I’m actually working on a 3D version of Pong, using OpenGL via SDL and coding in C++ under my linux Ubuntu.

This simple game is a great exercise and I’m using it to develop some common routines such as a mesh loader for .x files and related mesh renderer. So I’m having the opportunity to face a serious performance issue.

My scene is composed of about 2500 polys (a plane, 2 rackets and the ball), really low count, but enough to reduce my frames per second (fps) to 3 or 4. Ugh! My ball is moving really bad.

But OpenGL is fast! where is all the power? Well, the reason lays in my way to render polys.

My utility was rendering all the scene’s polys, one a time, between glBegin(…) and glEnd() commands.

This way, I was invoking glBegin() one time for every poly. Definitely not good.

What I did was change my rendering routine in order to use Display Lists.  This gave me a real boost of performances!

Now my fps are about 1000 and I have to face the opposite issue: too fast! But the real message is that OpenGL’s display lists works!

Posted in game programming | Tagged: , , , , | 3 Comments »

 
Follow

Get every new post delivered to your Inbox.