Using the Dynamic Factory

Now that we have a completed Factory class, let's look at how we would use it. Since the goal of this class was to decouple our M5StageManager from our specific derived M5Stage classes, it makes sense that it will be used in the M5StageManager class:

class M5StageManager 
{
public:
//Lots of other stuff here...
static void AddStage(M5StageTypes type, M5StageBuilder*
builder);
static void RemoveStage(M5StageTypes type);
static void ClearStages(void);

private:
//Lots of other stuff here
static M5StageFactory s_stageFactory;
};

Since the factory will be private in the M5StageManager, we will add interface functions so the user can control the factory without knowing the implementation. This allows us to change the details, without affecting the user.

Inside the M5StageManager::Update function, we will use the factory to get access to the current stage. Notice that this class is completely decoupled from any specific M5Stage derived classes. This give the user freedom to change the game design, including stage types, stage count, and stage names, without needing to modify the M5StageManager class.

In fact, that is the purpose of creating the Mach5 Engine the way we are. It can be used and reused in many game projects without changing the engine code. Here is a simplified version (pausing/restarting code has been omitted) of the M5StageManager::Update showing code relevant to the stages and factory:

void M5StageManager::Update(void) 
{
float frameTime = 0.0f;
/*Get the Current stage*/
M5Stage* pCurrentStage = s_stageFactory.Build(s_currStage);

/*Call the initialize function*/
pStage->Init();

/*Keep going until the stage has changed or we are quitting. */
while ((s_currStage == s_nextStage) &&
!s_isQuitting &&
!s_isRestarting)
{
/*Our main game loop*/
s_timer.StartFrame();/*Save the start time of the frame*/
M5Input::Reset(frameTime);
M5App::ProcessMessages();

pStage->Update(frameTime);

M5ObjectManager::Update(frameTime);
M5Gfx::Update();
frameTime = s_timer.EndFrame();/*Get the total frame time*/
}

/*Make sure to Shut down the stage*/
pStage->Shutdown();

ChangeStage();
}

As you can see, the M5StageManager is completely decoupled from any derived M5Stage classes. This allows the user to change, add, or remove any stages during development without needing to modify the M5StageManager class. This also allows the M5StageManager and M5StageFactory classes to be reused in another game, shortening the development time of that project.

Now that we have seen the dynamic factory and how to use it, an important question should come to your mind: what are the benefits of the Dynamic Factory? Both the Static and Dynamic Factories allow us to decouple our code. Since they both offer that benefit and the Static Factory is much easier to implement, why should we bother spending time on the Dynamic Factory? Asking questions like these is always a good idea. In this case, I think there are two benefits to using the Dynamic Factory over the Static Factory.

The first benefit of the Dynamic Factory is that it is dynamic, meaning that we can load builders from a file at runtime or remove a stage if we will never use it again (SplashStage). Being dynamic allows us to swap out a builder at runtime. For example, depending on the difficulty the player selects, we can swap out a difficulty component on enemies. The code to these difficulty component builders could be put into the menu, and the rest of our game no longer needs to care about the difficulty, the levels just create enemies the same way, no matter what.

The second and more important benefit of creating the Dynamic Factory comes in the next step. Since we have successfully created a StageFactory, we should do the same thing for components and game objects. In the next section, we will take a look at creating these factories.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.14.98