Firstly astute readers will notice that there is no part 13. This is because I’m slightly superstitious and would rather skip part 13, call me strange but that’s the way it is.
There were a few problems with the way that I’d written animations. One being that animations were tightly coupled with the actions that they animated and another being that it was hard to know when an animation had finished so that I could start a new animation. This will be important in the future when I want to chain animations together.
To solve both of these problems I have moved the animations to an event driven model. Now when actions happen like the selection being rotated, events get raised out and something else can listen to it. This means that the action is totally decoupled from the animation.
To implement events I first defined an IGameEvent interface. This is just a marker interface that all game events have to implement. I then defined an IEventHandler<T> interface where T has to implement IGameEvent and there is one method on the interface Handle(T gameEvent). Next I defined the EventDispatcher. The job of the event dispatcher is to dispatch events to the correctly handlers. It takes in it’s constructor an event handler factory that can return a collection of event handlers that can handle a certain event. Note that it is possible for multiple handlers to handle the same event.
The next stage is simply to wire up all of these classes. One interesting design decision that I have made is to define a static GameEvents class that has one method Raise. The raise method calls dispatch on the event dispatcher to dispatch the event. The event dispatcher is assigned to raise when the IoC container is built. I have done this for a number of reasons. Firstly it means that during testing I can swap out the event dispatcher for a action event dispatcher that simply calls a lambda expression that you can pass in. Secondly it means that at any place in the game I can raise out a game event by calling the static Raise method. It also means that I don’t have to inject the GameEvents class into every class.
As always there are many unit tests (that were written first) to test all of the code described above. If you want to check out the latest code you can do so by pulling down the source from github and looking at the part 14 branch. If you are unsure how to do that the follow the steps on this page.