Sunday, October 24, 2010

C++ Project - Final Fantasy Battle System pt.2

So with any programming project, the initial question is "where do I start?" I have ClanLib installed and the compiler configured and ready build, so now it's time to start planning exactly how to approach this project.


The heart of every game is essentially a loop which is responsible for updating and rendering. Since ClanLib does not provide a standard game loop or the means to track objects in our game, this seems like a good place to start.

So, we'll start with a base class, Game which will contain our loop.

 class Game   
{
private:
enum GameState {Stopped,Running,Paused};
// Singleton instance
static Game* m_instance;
. . .
Game();
Game(const Game& a);
public:
~Game();
static Game* GetInstance();
void Start();
void Initialize();
}

Notice that I have made the class a Singleton. Since I am anticipating other objects wanting to add/remove themselves from the main game loop, I want this class to be accessible anywhere within the program. Since the Game class is guaranteed to exist during the lifetime of the game, there should be no problems with initialization that is inherent with Singleton objects.

Also, I anticipate that we might want to add some simple functions for pausing the game, etc., so I have added an enum to track the current state of the loop.

Now that we have the outline for a basic loop, we need objects to actually render and update. In order to facilitate this I created a basic interface that we can use for any class that we might want to add to our loop.
 class IGameComponent  
{
public:
virtual void Initialize() = 0;
virtual void Update() = 0;
virtual void Draw(CL_GraphicContext& graphicsContext) = 0;
};

Now, let's add a container and a couple of operations to our Game class to actually track these objects.
 vector m_gameComponents;  
void AddComponent(IGameComponent*);
void RemoveComponent(IGameComponent* const)
Here is the full update loop for the game loop.
 void Game::Start()  
{
m_currentGameState = Running;
CL_Font font(gc, "Tahoma", 30);
while (m_currentGameState == Running)
{
Update();
gc.clear(CL_Colorf::cadetblue);
Draw();
gui_manager->exec(false);
wm->draw_windows(gc);
// Make the stuff visible:
window->flip(1);
// Read messages from the windowing system message queue, if any are available:
//CL_KeepAlive::process();
// Avoid using 100% CPU in the loop:
CL_System::sleep(10);
}
}
void Game::Update()
{
// Update loop
for (int i = 0; i < m_gameComponents.size();i++)
{
m_gameComponents[i]->Update();
}
}
void Game::Draw()
{
for (int i = 0; i < m_gameComponents.size();i++)
{
m_gameComponents[i]->Draw(gc);
}
}

And there you have it! A simple system for dealing with the game loop. Next up, I will need to add some sort of Scene Manager in order to track scene transitions and to encapsulate the elements that form each scene. I will also be adding in some hooks for the GUI system and the Input system into Game as well. Once, I have those in place I will start working on the design for the actual RPG gameplay.

No comments: