Reader small image

You're reading from  SDL Game Development

Product typeBook
Published inJun 2013
Reading LevelBeginner
PublisherPackt
ISBN-139781849696821
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Shaun Mitchell
Shaun Mitchell
author image
Shaun Mitchell

Shaun Mitchell is a developer at a high profile online gaming company. He holds a BSc in Game Programming and Development from Qantm College / SAE Institute London. Shaun is also a moderator and active member of the <dream.in.code> programming community.
Read more about Shaun Mitchell

Right arrow

Chapter 6. Data-driven Design

With the previous chapter adding the ability to create and handle game states, our framework has really begun to take shape. In this chapter, we will explore a new way to create our states and objects by removing the need to hardcode the creation of our objects at compile time. To do this we will parse through an external file, in our case an XML file, which lists all of the objects needed for our state. This will make our states generic as they can be completely different simply by loading up an alternate XML file. Taking PlayState as an example, when creating a new level we would need to create a new state with different objects and set up objects we want for that level. If we could instead load the objects from an external file, we could reuse the same PlayState and simply load the correct file depending on the current level we want. Keeping classes generic like this and loading external data to determine their state is called Data-driven Design.

In this chapter...

Loading XML files


I have chosen to use XML files because they are so easy to parse. We are not going to write our own XML parser, rather we will use an open source library called TinyXML. TinyXML was written by Lee Thomason and is available under the zlib license from http://sourceforge.net/projects/tinyxml/.

Once downloaded the only setup we need to do is to include a few of the files in our project:

  • tinyxmlerror.cpp

  • tinyxmlparser.cpp

  • tinystr.cpp

  • tinystr.h

  • tinyxml.cpp

  • tinyxml.h

Also, at the top of tinyxml.h, add this line of code:

#define TIXML_USE_STL

By doing this we ensure that we are using the STL versions of the TinyXML functions. We can now go through a little of how an XML file is structured. It's actually fairly simple and we will only give a brief overview to help you get up to speed with how we will use it.

Basic XML structure

Here is a basic XML file:

<?xml version="1.0" ?>
<ROOT>
    <ELEMENT>
    </ELEMENT>
</ROOT>

The first line of the file defines...

Implementing Object Factories


We are now armed with a little XML knowledge but before we move forward, we are going to take a look at Object Factories. An object factory is a class that is tasked with the creation of our objects. Essentially, we tell the factory the object we would like it to create and it goes ahead and creates a new instance of that object and then returns it. We can start by looking at a rudimentary implementation:

GameObject* GameObjectFactory::createGameObject(ID id)
{
  switch(id)
  {
    case "PLAYER":
      return new Player();
    break;
    
    case "ENEMY":
      return new Enemy();
    break;
    
    // lots more object types 
  }
}

This function is very simple. We pass in an ID for the object and the factory uses a big switch statement to look it up and return the correct object. Not a terrible solution but also not a particularly good one, as the factory will need to know about each type it needs to create and maintaining the switch statement for many different...

Fitting the factory into the framework


With our factory now in place, we can start altering our GameObject classes to use it. Our first step is to ensure that we have a Creator class for each of our objects. Here is one for Player:

class PlayerCreator : public BaseCreator
{
  GameObject* createGameObject() const
  {
    return new Player();
  }
};

This can be added to the bottom of the Player.h file. Any object we want the factory to create must have its own Creator implementation. Another addition we must make is to move LoaderParams from the constructor to their own function called load. This stops the need for us to pass the LoaderParams object to the factory itself. We will put the load function into the GameObject base class, as we want every object to have one.

class GameObject
{
  public:

  virtual void draw()=0;
  virtual void update()=0;
  virtual void clean()=0;

  // new load function 
  virtual void load(const LoaderParams* pParams)=0;

  protected:

  GameObject() {}
  virtual...

Parsing states from an XML file


The file we will be parsing is the following (test.xml in source code downloads):

<?xml version="1.0" ?>
<STATES>
<MENU>
<TEXTURES>
  <texture filename="assets/button.png" ID="playbutton"/>
  <texture filename="assets/exit.png" ID="exitbutton"/>
</TEXTURES>

<OBJECTS>
  <object type="MenuButton" x="100" y="100" width="400" 
  height="100" textureID="playbutton" numFrames="0" 
  callbackID="1"/>
  <object type="MenuButton" x="100" y="300" width="400" 
  height="100" textureID="exitbutton" numFrames="0" 
  callbackID="2"/>
</OBJECTS>
</MENU>
<PLAY>
</PLAY>

<GAMEOVER>
</GAMEOVER>
</STATES>

We are going to create a new class that parses our states for us called StateParser. The StateParser class has no data members, it is to be used once in the onEnter function of a state and then discarded when it goes out of scope. Create a StateParser.h file and add the following...

Loading the menu state from an XML file


We now have most of our state loading code in place and can make use of this in the MenuState class. First we must do a little legwork and set up a new way of assigning the callbacks to our MenuButton objects, since this is not something we could pass in from an XML file. The approach we will take is to give any object that wants to make use of a callback an attribute named callbackID in the XML file. Other objects do not need this value and LoaderParams will use the default value of 0. The MenuButton class will make use of this value and pull it from its LoaderParams, like so:

void MenuButton::load(const LoaderParams *pParams)
{
  SDLGameObject::load(pParams);
  m_callbackID = pParams->getCallbackID();
  m_currentFrame = MOUSE_OUT;
}

The MenuButton class will also need two other functions, one to set the callback function and another to return its callback ID:

void setCallback(void(*callback)()) { m_callback = callback;}
int getCallbackID() { return...

Loading other states from an XML file


Our MainMenuState class now loads from an XML file. We need to make our other states do the same. We will only cover the code that has changed, so assume that everything else has remained the same when following through this section.

Loading the play state

We will start with PlayState.cpp and its onEnter function.

bool PlayState::onEnter()
{
  // parse the state
  StateParser stateParser;
  stateParser.parseState("test.xml", s_playID, &m_gameObjects, 
  &m_textureIDList);

  std::cout << "entering PlayState\n";
  return true;
}

We must also add the new texture clearing code that we had in MainMenuState to the onExit function.

// clear the texture manager
for(int i = 0; i < m_textureIDList.size(); i++)
{
  TheTextureManager::Instance()->
  clearFromTextureMap(m_textureIDList[i]);
}

These are the only alterations that we will need to do here but we must also update our XML file to have something to load in PlayState.

<PLAY>
<TEXTURES...

Summary


Loading data from external files is an extremely useful tool in programming games. This chapter enabled our game to do this and applied it to all of our existing states. We also covered how the use of factories enabled us to create objects dynamically at runtime. The next chapter will cover even more data-driven design as well as tile maps so that we can really decouple our game and allow it to use external sources rather than hardcoded values.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
SDL Game Development
Published in: Jun 2013Publisher: PacktISBN-13: 9781849696821
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Shaun Mitchell

Shaun Mitchell is a developer at a high profile online gaming company. He holds a BSc in Game Programming and Development from Qantm College / SAE Institute London. Shaun is also a moderator and active member of the <dream.in.code> programming community.
Read more about Shaun Mitchell