31
\$\begingroup\$

I'm in the midst of developing a 2D sprite-based game for Windows 7 Phone, using XNA. The training and tutorials available for it are pretty helpful, but the problem I face is that each of them approaches their class design differently, and the code is not particularly well-factored. As a result, it has been difficult for me to gain a good understanding of which responsibilities I should give to a particular class.

For example, I could have a base sprite class BaseSprite that knows how to draw itself, check for collisions, etc. I could then have an AnimatedSprite class that would know how to navigate its sprite sheet, an ExplodingSprite class, and so on. This technique is demonstrated in the Space Invaders example in the Windows 7 Phone Jumpstart Session 2 materials.

Alternatively, I could instead place the bulk of rendering and running the game responsibility in a GameScreen class; that class and its derived classes behave more like forms or web pages in terms of their responsibilities. Sprite classes are more simple containers with much less logic.

This is the technique used in the Windows 7 Phone Training Kit's Alien Sprite game and other game state manager examples.

What is the correct object-orientated approach to class design in game development?

\$\endgroup\$

4 Answers 4

26
\$\begingroup\$

I do use a more component-oriented approach, where you would have a Sprite class which has components like Visual, Collision, Animation, Input, etc. With this approach I don't end up having a deep class hierarchy (which is good).

For some info on Component Oriented Design see here.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ +1 the article you linked to was fantastic. I was so focused on pure OO design, I completely overlooked the component/decorator type model. \$\endgroup\$
    – Josh E
    Commented Jul 27, 2010 at 13:51
  • 1
    \$\begingroup\$ The component pattern isn't really "less pure" OO :) \$\endgroup\$
    – Srekel
    Commented Jul 27, 2010 at 15:40
  • 2
    \$\begingroup\$ Indeed. OO is often equated with inheritance. But inheritance is only one tool OO offers, composition is another. \$\endgroup\$
    – haffax
    Commented Jul 27, 2010 at 19:37
  • \$\begingroup\$ Just so. I should have been more precise in my wording; what I meant is that I focused to much on the inheritance side of OO instead of thinking of OO design patterns / other OO aspects that could help me achieve what I wanted. \$\endgroup\$
    – Josh E
    Commented Jul 31, 2010 at 23:55
  • \$\begingroup\$ While a comoposition based approach is pretty obvious and used frequently, I have yet to see a solution to keeping the rendering component portable. Any hints would be great. \$\endgroup\$
    – Andreas
    Commented Aug 6, 2010 at 6:45
11
\$\begingroup\$

In games, the Component pattern is a common solution.

\$\endgroup\$
2
  • \$\begingroup\$ that's another fantastic article - well worth the read. \$\endgroup\$
    – Josh E
    Commented Aug 1, 2010 at 0:21
  • 1
    \$\begingroup\$ Great, great, great article! \$\endgroup\$
    – Kevin
    Commented Dec 19, 2010 at 20:13
6
\$\begingroup\$

The SOLID Principles apply as much to game code design as to any other profession - at least until you come to optimise, so I'd use your first example as a starting point.

I'd go further though, because BaseSprite sounds like it has the tendency to become a megaclass. The Single Responsibility Principle dictates that collision, rendering and navigation should all be handled by components, rather than individual entries in a class hierarchy. The holding class of all these components should only handle pushing world positions between them.

\$\endgroup\$
5
\$\begingroup\$

For the last few projects I have leaned more towards an MVC style approach.

At first we weren't sure if this would work, but it worked perfectly.

Model

The data objects. Just the pure data. No behaviour, no rendering.

Data manager. Just handling "lists" of data objects. (Can also be enhanced to support pooling.)

View

We call them renderers. For every data object type there is a renderer. When called with a manager it will render all objects in that list.

Controller

Same as the renderers, but controls the behaviour.

Example

The ShipManager has a list of Ships. The ShipController will move the Ships according to their state. The ShipRenderer will render the Ships according to their state.

Why

This way the view and the logic are strictly seperated. It makes porting to a new platform pretty easy. Optimizing the data layout inside the XxxManager is also very easy.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I'm voting you down because I'm sick of seeing more-or-less bare "Use MVC" as an acceptable answer. If you are developing on any modern platform, you're already using MVC at multiple levels. It's not a specific answer, and it's not a good answer, because it doesn't actually tell people how to structure classes, which is task/domain-specific. You just end up with a lot of people writing "class Modal...; class View...; class Controller..." MVC is a pattern with a lot of good high-level explanatory power when talking about existing code. It is not a pattern with a lot of good planning power. \$\endgroup\$
    – user744
    Commented Jul 27, 2010 at 20:31
  • 4
    \$\begingroup\$ @Joe I get your point, but find your choice of words unnecessary rude. I just explained how we do it. Since the higher level architecture choice makes the lower level design choice obsolete, I consider it a valid answer. \$\endgroup\$
    – Andreas
    Commented Jul 28, 2010 at 9:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .