I'm trying to build a simple game with a number of screens - 'TitleScreen', 'LoadingScreen', 'PlayScreen', 'HighScoreScreen' - each of which has it's own draw & update logic methods, sprites, other useful fields, etc. This works well for me as a game dev beginner, and it runs.

However, on my 'PlayScreen' I want to run some animations before the player gets control - dropping in some artwork, playing some sound effects, generally prettifying things a little. However, I'm not sure what the best way to chain animations / sound effects / other timed general events is.

I could make an intermediary screen, 'PrePlayScreen', which simply has all of this hardcoded like so:

But this doesn't seem so great - surely their must be a better way? I then thought, 'Hey - an AnimationManager! That'd be awesome!'. But then that creeping OOP panic set in as I thought about it some more.

If I create the Animation in my Screen, then add it to the AnimationManager (which may or may not be a GameComponent hooked up to Update/Draw), how can I get 'back' to it? To signal commands like start / end / repeat? I'd still need to keep a reference to the object in my Screen so that I could still communicate with it once it's buried in the bosom of a List in my AnimationManager. This seems bad.

I've also tried using events - call 'Update' on all the animations in the PlayScreen update loop, but crucially all of the animations have a bool flag ('Active') which determines whether they should begin. The first animation has this set to 'true', all others 'false'. On completion the first animation raises an event, which sets animation 2's bool flag to true (and so it then runs). Once animation 2 is complete another 'anim complete' event is raised, and the screen state changes.

Considering the game I'm making is basically as simple as it gets I know I'm overthinking this... it's just the paradigm shift from web -> game development is making me break out in a serious case of the stupids.

1 Answer
1

Here's my solution to this common problem. First let's choose a name for an action that spans several frames, such as an animation. I'll call it a Process which is the terminlogy I found in this book, but don't mistake it with the processes on your OS, it's a different concept. In this context, a process is anything that needs to be updated, possibly several times, before it completes.

I'll start by defining a base class for our process. Something as simple as this is enough (I kept the name as Process for consistency with the discussion above, but since .NET already has a class named like that, you might want to give it another name):

Now let's create a class that serves as a process queue. You add processes to this queue, and they get executed in turn. This is where my implementation differs from the one in the book above. In the book every process is updated every frame, but in this case I'll make them sequential instead, so that the second process only starts when the first one ends. Once again it's a simple class:

And that's it, although you're free to add more methods, for example to clear the queue or to know how many processes are currently queued. Now just make your Animation class inherit from Process and chain them like:

Here's how you can use these processes. Let's say for instance that you would like to play animation A, wait 2 seconds, play animation B, and finally write a message to the debugger. By using the processes above you can implement this entire sequence as four lines of code:

And the only thing you need to do is remember to call Update on the process queue. Can you see how powerful this concept can be when properly used? Pretty much everything in your game can be considered as a process!

What About Looping?

What if I wanted to take the example above and make it loop infinitely? Well, this too, is extremely simple to implement with this framework, using a sort of "delayed recursive" call. Just put the processes you want to loop inside a function, and then add a GenericProcess at the end that adds that calls that function once more:

Nice, I had this framework in a game I did once, but with the name of Event, instead of Process. To tell the truth, processes sounds way better for me, I just didn't mind the name in the time :D
–
Gustavo MacielApr 6 '12 at 3:07

1

@codinghands That's the most simple way, yes! But once again that's a design decision with a lot of room for variation. There's even a very interesting thing you can do which is make your ProcessQueue class itself a Process, and give it two different modes of operation - sequence and parallel (although the name queue is no longer appropriate). Then you could just create a ProcessQueue (in parallel mode) and add your other ProcessQueues (in sequence mode) to it, just like as any other process. This is basically the composite design pattern and allows many other tricks too :)
–
David GouveiaApr 6 '12 at 13:58

1

Proception! Baaarm! That's a great idea. I really need to read some game design architecture stuff, that wasn't immediately obvious at all. Going to give implementing this a shot right now. Thanks again!
–
codinghandsApr 6 '12 at 15:59

1

@codinghands Don't feel ashamed, I only realized the benefits of treating the queue itself as a process yesterday, when speaking about the subject with a fellow game developer :) You're always learning new tricks in this business.
–
David GouveiaApr 6 '12 at 16:02

1

@codinghands This will vary from situation to situation, but I don't think that dependency should be a responsibility of the queue. So I tend to add dependencies to the processes themselves. E.g. pass a reference to A to B's constructor. I think I know what you're trying to do though, but it's a bit hard to explain so compare what I will say with this example. Basically, pass a reference to the character to the animation process, and use the reference to get the character's position but on the first update, not in the constructor (see example in link).
–
David GouveiaApr 6 '12 at 17:56