In XNA4, I have an EnemyManager class that takes care of all of the enemies. When it comes time to draw, however, it needs access to the game's main View, Projection, and World matrices.

I could just pass a reference to my DavesGame object down in there, but that seems like bad design. I could put them in an interface and expose them as a game service.

I'm leaning towards the latter, but I'm wondering what the correct & elegant way to do it is.

Thanks! Dave

  • \$\begingroup\$ Does your EnemyManager extend GameComponent? I ask because GameComponent already has a property Game that points to the class instance that created it. If not, you could collect your matrices in a Camera class and reference that. Pretty normal practice there. \$\endgroup\$ – Seth Battin Apr 11 '13 at 20:44
  • \$\begingroup\$ As Seth commented, just use a camera class and access the matrices from that. \$\endgroup\$ – Jason Coombes Apr 12 '13 at 6:37

First let's assume how the matrices are "bundled" doesn't matter. I'd suggest a Camera class of some kind, but it doesn't matter - it could be a struct or as loose Matrix objects.

Let's look at how you might pass that Camera around:

Passing it around as a service isn't great. It's a lot of extra work and indirection, to fulfil a need that you probably don't have. Services are mostly for people making APIs that will be consumed by third-parties - and I assume you're not doing that. See this answer for a full description.

Grabbing it through Game is essentially no different to grabbing it through Services, but you lose all of the advantages (although you didn't need them anyway, and this saves you making a class).

You could be quick-and-dirty and make it "global" (in C# this would probably be a public static on your game class). This is ok when you want to do something quickly. And in C# it's relatively painless to undo, once you need a "real" architecture.

Passing it into the constructor of your component isn't a great idea. Consider the very possible scenario where you'd like to draw your component twice. Perhaps for split-screen, perhaps for a level-editor. Then you very messily have to modify persistent state before each draw. If you can ignore this downside, it is a reasonable architecture.

But there's one more blindingly obvious option: Why not just pass it in as a parameter to your Draw method?

Oh, you can't because you're using DrawableGameComponent? The solution to that is simple: Stop using DrawableGameComponent! Seriously. It doesn't actually add anything to your architecture unless you're creating drag-and-drop-style components for third-party consumption (which, again, I am assuming you are not doing).

Its limitations are not worth the extra hoops you have to jump through, if you're not actually using it for its intended purpose.

I suggest you replace it with your own base class, where you can modify the method signatures on to your heart's content. The remaining infrastructure you get with DGC amounts to a list and a pair of loops, maybe 5 lines of trivial code.

I've written about why DGC is a terrible basis for an architecture (because it leaves you in these horrible tight spots) here and here and here and here.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.