Animation architecture

I am writing a game project as a hobby, and I am looking for some architecural tips on how best to organize my game objects and their various animations.

For example, I have a Wizard class, and a class called Dragon. The master has at least 10 different specific animations associated with him, depending on his condition, and the same for the Dragon.

So my question is this: is there a standard template for organizing such objects so that they are efficient and easy to expand (i.e. it should be easy to add new animations and new objects)?

I have different ideas on how to move on, but I do not want to be mistaken, since this is such an important part of the game architecture. It seems easy to get this to work for a small game, but I'm afraid of uncontrollable complexity as it is bigger.

+6
architecture animation
source share
2 answers

I suggest having an interface like "Character" that defines what all these entities should do. Then your Dragon and Wizard classes are just implementations.

Another route is to have a base class from which you are spreading, and use it to manage the "hierarchical growth" associated with large projects by creating a hierarchy of your objects and identifying extended base classes.

+1
source share

No, there is no standard template.

My advice is to avoid the novelty of the OO design trap by trying to find a single, common “base class” interface for everything. Your Dragon is very different from your Master, and it doesn’t work, trying to combine two interfaces, except for nice code abstractions. Remember that inheritance is not a code reuse tool.

The simplest approach is for each object to maintain its own internal state (as you already described), and you can draw this state. In this case, the old school switch instruction may be more understandable than using polymorphism for the same effect. Example:

class Dragon { enum State { asleep, flying, breathing_fire }; public: void draw () { /* old-school switch */ switch (cur_state){ case asleep: draw_asleep (); case flying: draw_flying (); case breathing_fire: draw_breathing_fire(); } } private: void draw_asleep (); void draw_flying (); void draw_breathing_fire(); }; 

Experienced C ++ developers will sigh over the above code (as it should be), because the switch statement almost exactly performs a call to the polymorphic method - dispatching runtime. (Or even more mysterious: the table of method addresses.) My personal opinion is that for this particular type of class, that is, one open interface encapsulating a state machine, the switch statement is more understandable and easy to maintain, since it makes the state machine jump obviously. I think it is also clear that I understand that this is generally a bad design in C ++.

The friction of this design is caused by the dividing line between the state machine and the only open interface. A sleeping dragon is clearly not the same as a flying dragon. In fact, it will be almost nothing in common. But a higher-level design says the two are the same dragon. What a mess! Do you create different Dragon objects for each state? No, because that would bring the concept of state to the caller. Do you create different internal helper objects for each state and submit them? Perhaps, but it is quickly becoming erratic. This approach is a compromise between the two. Think of the statement as a switch to isolate ugliness. The open interface is clean, as is the private interface. Only the switch statement contains messy mess. Consider this approach, and consider other suggestions.

Finally, to draw your Master and your Dragon, a simple template or shell functor is enough:

 struct Draw { template <class S> void operator()(S& s) { s.draw (); } }; 

The fact is that you do not need to combine two different classes just because they support the same logical operation.

0
source share

All Articles