Should entities know how to draw themselves? I've used this approach: it's simple and it works, but after learning MVC-patterns I feel uneasy about this. It's hard to change the art style when all the display logic is buried in the model.
One could introduce a view class, which takes the level as an argument and draws it, but this would mean it has to identify entity types and introduce a "switch"-statement, which I learned is also bad.
Where should one place code for drawing, in a way that is extensible, easy to change, clean and dry?
This question still comes up frequently in game development as various studios and groups start on new engines.
The short answer is that it depends on how complex your game entities will be. For simple entities, it doesn't really matter.
When you get into much more complicated entities, you have to rethink your approach. In general, you'll want to resist the urge to have the uber loop that iterates over every entity and calls some update/render/whatever function. That doesn't scale at all, unless every update, render, or whatever hierarchy is exactly the same. Which is fine for a game like Geometry Wars, but not for anything more complicated than that.
What you want to do is given the most general entity collection extract a usage specific traversal. For example, if you wanted to render the scene you should have a way of extracting all the renderable entities from the entity collection and then rendering all of them in some arbitrary batchable order. Same goes for physics, collision, AI, etc.
Some helpful links:
http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf
I highly recommend both; the first goes into design rationale for building game entities out of components, i.e., render component, physics component, AI component. The second goes into performance characteristics of various game entity approaches.
Theres nothing inherently wrong with having an abstract Draw() style method in your entities that lets them decide how they will be drawn, especially for smaller games that probably won't be extended significantly. I've used this method in a ton of small projects and it works great.
An improvement you can make to that strategy is to use your game resources as a proxy for the actual drawing operations. For example an enemy entity can defer all the rendering through a resource object it owns that represents the mesh; likewise for the texture/skin and effects.
I've recently switched to using my entities as 'dumb' containers for interfaces that define their behaviours. A player entity might contain IMoveable, IControllable, IRenderable, and many more interfaces that simply apply a specialized operation to that entity depending on the data it contains. The entity doesn't know much about this and all the execution happens when the scene graph is traversed for culling/rendering.
MVC isn't necessarily a great fit for games. MVC was designed for traditional GUIs which typically update infrequently based on discrete events, whereas games are more like simulations where there is constant updating going on and the presentation needs to reflect that instantly.
Still, there's no reason why you shouldn't still strive to separate state from presentation. Entities don't need to know how to draw themselves as such - that would mean they know about rendering operations, which is unnecessary - but it should be possible to ask them how they look at this point in time and then to use that information to render the scene. eg. a 2D entity should be able to return its current frame of animation. Or a 3D entity should be able to return its 3d mesh, position, and orientation. No need for the switch statement here, as long as you have generic representations that you can return to the renderer. Entities with wildly differing rendering algorithms might have to return rather different objects at this point.
Typically I solve this issue with inheritance.
For example, on a project I'm working with at the moment I'm using Test-Driven Development to write the game logic, with manual testing for the rendering. This example below in C# shows the rough idea.
class GameObjecet {
// Logic, nicely unit tested.
}
class DrawableGameObject : GameObject {
// Drawing logic - manual testing
}
This is generally what I've found to be the best solution. This allows code to be tested, while not cluttering the game logic with presentational code such as drawing, and model loading etc...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With