Pages

Friday, November 30, 2012

The Friday Project - Update 6

Cats and Programmers

The day after my last update, two weeks ago, we went on a short visit to the local RSPCA centre. Just after arriving, we found ourselves in the cattery. As she often does, my daughter asked, "Dad, can we have a cat?" For some reason, which still escapes me, I didn't say "no", with the result being that Marillion joined us last Saturday.

Shouldn't you be programming?
I often work from home, but didn't do so this week, which meant that today was my first real opportunity to see what it would be like using a laptop with a cat in the house. Ordinarily I use the large PC in the room that serves as my office, but I thought I would keep the cat company as she's still confined to the ground floor. As it turns out, we got on just fine. Sure, at first she wanted to hunt a bit, which provided a bit of fun for both of us, and she was very curious about the mouse, but she soon settled down into her routine of purring and sleeping. And I settled down into my routine of refactoring and cursing the idiot who wrote the code two weeks ago.

The moral of the story? Cats and programmers have similar personalities and get on very well.

Using Otto (no, not the evil one)

But back to the game. As you probably noticed, this update is a week late, mostly because I didn't get anything done last Friday. During the earlier part of this week, I started to look at the code, and realised that there were simply too many dependencies. I'd originally started the game by hacking a few ideas together to see if they worked. This got things off to a flying start, but I felt that things were getting a little too complicated and that I simply had too many listeners, and, for that matter, too many layers in the code.

If this had been something that I was working on every day then it wouldn't even have reached this state, because I'd have changed it much earlier, or thrown it away and put it back together properly. But this is something I work on once a week. Throwing things away is not an option. I know I shouldn't have let it get to that state. Lesson learned. But what to do to make it better?

The first thing that I decided to tackle was to decoupling event producers from event consumers. By events, I mean things like "game over", or "the score has changed", or "the player has hit a wall". There are many ways of doing this. For example, a few years ago I wrote CSharpMessenger to solve this problem in Unity. However, an idiom that works in C# doesn't necessarily translate well to Java, and besides, why reinvent the wheel?

And so, by a lucky coincidence, I happened to watch this presentation on Android App Anatomy by one of the guys from Square, and found myself incorporating Otto into Whirling Frenzy. I am happy to report that it works very well indeed and my code is now much more manageable.

Let's see some examples.

Event handlers and subscriptions

First of all, let's look at an event handler.

Here's a piece of code that handles what happens when a level ends. Note the @Subscribe annotation. This tells the bus to listen for an event of the type given in the method signature, in this case a LevelEndEvent.

 @Subscribe  
 public void onLevelEnd(LevelEndEvent e) {  
   newLevel = true;  
   level = levelManager.nextLevel(level);  
 }  

Registration and deregistration

Of course, the bus has to be told that a class is interested in events. It does this by calling Otto's register() method.

 bus.register(this);  

And when it no longer needs to listen, it calls unregister().

 bus.unregister(this);  

Posting events

That's all very well, but how do we get the events onto the bus? Again, it's very simple.

 bus.post(new LevelEndEvent());  

And that's it. The code that posts the event knows nothing of the event handlers. There could be one. There could be several. I'm sure that there doesn't even have to be one. It doesn't matter as Otto takes care of it.

You can read more about it here.

Music

I've also been lucky to acquire the musical services of Marcus Borg. Marcus is a talented musician (and he's also a rather good co-op partner in Orcs Must Die 2). He has started to put together some ambient sounding music that goes absolutely perfectly with the game. I've put a sample of it into the game already, and even though it isn't complete, I really think it makes a difference.

Playable Demo

There are no visible changes to the game, as much of the work was behind the scenes, using Otto. You will be able to hear the difference though, because the music starts up when you play the game. Follow this link or scan the QR code to download the latest playable demo.


No comments:

Post a Comment