Growing Away From GameMaker — part 3: Embracing StageXL
In my previous post I talked about why I chose Dart over JavaScript. In this post, I want to explore my chosen framework, StageXL.
StageXL is a framework born out of the need to find a replacement for Adobe Flash. Since Flash doesn’t run on mobile and HTML5 is now at a place where games can run in the browser without plugins, there came a need for game frameworks that run natively in the browser. StageXL tries to match the same methods and ideology from Flash so that developers that are comfortable with the old way should be able to adapt very easily to Dart and the framework.
Well, I’m not coming from a Flash background. I’ve done most of my game developing using GameMaker so the effort to match my previous experiences is pretty much lost on me. So why did I choose StageXL? It, by far, looked to be the most mature game framework available for my chosen language. So, in one sense I was stuck with it. But rather than being a negative, I consider it a positive since I wouldn’t have to prototype in multiple frameworks to figure out which one was best for me.
Since I had no idea how to start, I used an example. And since I decided to port my card game over, I chose the “memory” example as it uses cards. I tore out all the fancy flipping and skewed perspective to boil it down to just a grid of playing cards. Once I had the playing cards in and displaying, I attached events for dragging and dropping. It worked. Now was the hard part of converting the game from one framework design to another.
GameMaker: Studio (GMS) divides the game into discrete pieces, the most important is the room. Every screen you see is a room in GMS. It’s quite possible that there’s only one room, but some games have thousands. A room is a distinct piece and can be thought of as a “level”. For my game, Slam, I used 5 rooms: 1 for the game itself and 4 “menu” rooms that housed the main menu, computer selection, store and help screens.
StageXL doesn’t have rooms. It has a stage. If there are children of the Stage, they’ll get drawn. If they’re not children, they won’t. I decided to emulate GMS so I could quickly transition the game. So I created DisplayObjectContainers for my rooms: main menu, computer selection, game, etc.
GMS defines user interaction using “objects”. These aren’t objects in the “Object-oriented programming” sense, but rather they’re just a collection of interactive events. They can have a sprite attached to them. They can respond to user events. Objects are created in one of two ways: either dropped in the room by using the editor or programmatically using a function. But in either case, if there are no objects in your game, the user is going to be very bored.
In StageXL, things are a bit more complicated. The base, abstract class InteractiveObject defines user interaction. The Sprite class is the concrete version that I used a lot. And I mean, a lot. Since it’s a card game, the most simple interactive object is the Card. I made the Card class extend (inherit from) Sprite so it can have an image (the card face) while also having access to user interactions like dragging. I implemented these along with my converted “memory” work and I had a very basic game of “how many cards can you move at once?” (turns out it’s 5).
GMS has a drag-n-drop interface for defining interactions and events, but I never use it. It’s really there just for people who are brand new to programming. But since an object is the only way to interact and since the event handlers are all in the drag-n-drop interface, all of my events are variations of “run this piece of code”. So, for when the user taps their deck to refill their hand, I have this:

A single event that all it does is run a piece of code. That code refills the player’s hand. All of my objects look like this. Some with multiple event handlers that all “execute a piece of code”. This is very annoying.
In contrast, in Dart I have a Player object. This player has two child objects: a hand and a draw deck. I’m using “children” to mean “objects that belong to me and that I can control”. The player adds a handler to listen for when the user taps to refill their hand. The code looks like this:
var clickHandler = (_){
if (_drawDeck._disabled) {
return;
}
refillHand();
};this._drawDeck.onMouseClick.listen(clickHandler);
this._drawDeck.onTouchTap.listen(clickHandler);
This way the code is easy to reason about and find what’s happening. In general, all my objects in Dart know only about themselves and their children.
One part of using GMS that I had to research was how best to do tweening. Tweens are animations between something. In Slam, I’m using tweens to animate the cards to their various positions. For example, the computer player checks each card in their hand for a move. This is shown visually by moving the card down a few pixels and then returning it to the hand. Instead of manually having to calculate each frame where the card should be drawn, I use a tween library. This library is great and works as expected.
In StageXL, there is a built-in tweening library named “Juggler”. Since it’s built-in, it’s easy to use and extend. In general, getting tweens to work as desired in both platforms was easy once I read the documentation. StageXL has the leg up because it’s built-in.
Once I figured out these key things, most of the work consisted of copying the code functionality over to StageXL. I was able to build a fully-working version in Dart and StageXL over the course of maybe 30 hours spread over 4 weeks.
In my next part, I’ll talk about how I planned to actually get it running on mobile phones using Cordova/Phonegap.