| Game Architecture Day 2 |
|
|
| Written by Markus Ewald | |||
| Tuesday, January 19 2010 19:24 | |||
|
Welcome to day 2 of the XNA Game Architecture series! I have thought hard about whether I should just assume a certain level of object oriented programming knowledge in this series. People picking up these articles likely already have some knowledge about objects and design, so I settled on a quick run-over of the principles that hopefully won't bore the seasoned developers and provide a good reference for people just starting out!
If you already know all this, feel free to skip ahead until it becomes interesting
again or to the next chapter ModularizationMany programmers using XNA to learn programming end up with something like this:
That's quite okay for someone doing his first steps, but obviously, as the code grows larger, this kind of design becomes pretty hard to maintain and it will be increasingly difficult to remember what all those fields are there for and where the code for doing something needs to go. No programmer is capable of keeping every method and every field of even a moderately sized game in his head at once, so we break the problem down into small parts that we can understand - using methods and classes. It's a bit more work to write those classes and to wire them up to each other, but if we do our job well, the project is much easier to maintain and we have more fun working on it, too! Here's what might become of above class with some modularity applied:
Knowing what to turn into classes and how to make them interact with each
other comes with experience. And hopefully, by the end of this series, you will
have a bit more of that! EncapsulationAs the game grows, the number of classes will also grow until there are too many of them interacting with each other to keep track of. So classes alone are not the final solution to keeping a game's code base manageable. One method of combatting this complexity is to limit the amount of members exposed by a class. This is best illustrated with an example: Imagine you were writing a DVD burning application. At some point, you will have to delve into the gory details of the some obscure API used to control the DVD drive. One could sprinkle bits of this code all over the application. The drive selection dialog would contain some code that looks at what DVD drives are available, the burn dialog would contain some code that sends the data to be burned to the DVD drive bit by bit, and so on -- like this:
But this makes it hard to keep track of what's going on. Worse even, if you later port that application, say from WinForms to WPF, you have to isolate all those pieces of code from its dialogs and re-add them to the WPF code. And if you decide to also create a command-line version of the application, oh well... Instead of spreading the DVD drive control code everywhere, you can encapsulate all that complicated stuff behind a small class: There might be a lot going on behind those three methods, there might even be multiple classes involved - the point is, from the outside (meaning the rest of the application), only those three methods are visible.
Of course, the art lies in finding appropriate places where the interactions between classes can be trimmed down to just a few methods. This, too, is a matter of experience. Good programmers intentionally design towards making it possible to build self-contained, encapsulated classes. One trick is to look for where the concerns change: the dialog is concerned with managing the user interface, the DVD drive control code is concerned with burning data to a DVD - thus, these two don't belong together. Abstraction
Quite often, classes have to interact with each other. As an example, one
class might manage your particle systems,
another might manage
your graphics device (like XNA's
Where is the problem with that?
What you need then is an interface for the
Luckily, the XNA Framework provides just such an interface. It's called
Now the Next ChapterIn the next chapter, I will finally start writing some code and explain the concept of Dependency Injection and how to wire up a game's classes with each other using an Inversion of Control container.
|


!
Comments
Allan
There are less articles explaining how to start programming a game than articles explaining OOP.
My worry was that this series might turn into yet another OOP intro, of which there are already enough out there that explain this topic better than me.
Summarizing the concepts like I did in this part of the series feels like the right way to go, too. I can keep those with a basic grasp of OOP in the boat and get on with my goal of explaining how to put together a game.
I am trying to avoid going down to the basics, but without this intermediate chapter, it would have been hard to explain the 'why' when I begin using IoC.
I'll keep the OOP concepts at the summary level, that way, those readers hearing something for the first time know what I'm talking about and what search terms to use for finding further information on the topic and those already aware of a concept hopefully won't get bored!
RSS feed for comments to this post.