A GameLooper class for ActionScript 3 projects

When creating games (or, really, any sort of animation) using ActionScript, most developers rely on the ENTER_FRAME event to synchronize their actions with when a frame is being rendered on the screen (effectively using it as their game loop). In any way you look at it, that’s the right way to do it, but it has some limitations of its own.

In the past, when I needed to control something using ENTER_FRAME equivalents, I normally used a TickController class. The advantage of this class is that it allowed me to dispatch a “tick” event any number of times per second, skipping actual Flash frames as needed, or repeating tick calls per frame as necessary (something rarely recommended, I must add, but necessary under some conditions).

Recently, I started taking a different approach with a class I called GameTicker. This class was somewhat more flexible, in that it had its own control of time and allowed objects attached to it to be paused and resumed. It was heavily influenced by the way Unity works; it does things with somewhat of as rigid approach, as it could only use objects of a specific interface, requiring every kind of class to be especially prepared for it.

Over the past couple of weeks I’ve put together a different class that, in my opinion, solves both problems in a much more elegant fashion. It’s called GameLooper and it’s available on GitHub. It’s used like so:

// Create GameLooper instance and start it
var looper:GameLooper = new GameLooper();

// Add a signal callback, using a Signals-like approach
looper.onTicked.add(onTick);

// Actual callback function
private function onTick(currentTimeSeconds:Number, tickDeltaTimeSeconds:Number, currentTick:int):void {
	var speed:Number = 10; // Speed of the box, in pixels per seconds
	box.x += speed * tickDeltaTimeSeconds; // Easy, accurate calculation
}

At the very basic level, GameLooper doesn’t do anything more than what ENTER_FRAME already does (and, obviously enough, that’s the event it uses internally). Its advantages, however, are:

  • GameLooper keeps track of relative time and ticks passed via currentTimeSeconds, tickDeltaTimeSeconds, and currentTick. This is not just a getTimer() call; time can actually be manipulated internally and the GameLooper instance can be paused, resumed, and have its timeScale changed.
  • The “tick” event call is flexible: by specifying minFPS or maxFPS parameters when creating the GameLooper class, it can be dispatched more than once per Flash frame (if you absolutely need something checked a number of times per second), or skip frames as needed (if something only needs to be executed a few times per second).

Previously, in games, I’d either use the old GameTicker, or create my World instances with its own ENTER_FRAME engine and time calculation. By offloading the responsibility of dispatching the tick event and controlling time to an auxiliary class, I think it makes development of World-controlling classes much simpler and more flexible, with no discernible trade-off.

. . .

One thing I have started realizing recently – especially when creating games for Ludum Dare – is that I tend to spend too much time obsessing over creating subsystems and refactoring them until I’m happy, often forgetting to create a cool, fun game around it. That is to say, while this new GameLooper class is a result of things I have actually created at work, it’s also part of preparation for the next Ludum Dare (#27), which has just been announced (it will take place in August 23-26th; and theme suggestions are now open). My plan right now is to create something for the OUYA and its controller using Adobe AIR (and its new GameInput APIs), hence why I’m getting some kind of generic framework ready for it before it starts. We’ll see where it goes.