A lot of tutorials talk about designing levels in code, using XML or an array of arrays, or just setting x and y properties of various objects. This approach works, but it feels primitive. I mean, I spent £500 on a piece of professional design software, and you’re telling me I should lay out my levels with a text editor?
No thanks, Chuckles!
Fortunately, it’s really not that difficult to use the Flash IDE (that is, the actual Flash CS3/CS4 program) to design levels for games, and in fact using it in this way makes it easier for us to separate level design, art assets, and code. It even lets us create in-game level editors without much effort at all!
This article is an introduction to using Flash as a level editor, explaining how we can grab information about the symbols on the stage. In the next part we’ll take this further.
The Most Basic (and Common) Method
There’s a very simple method people have been using since AS2 was popular.

In the above screenshot, I’ve got a number of Platform movie clips, each with an instance name of platform1, platform2, and so on. Same deal with the enemies. The player’s character has an instance name of hero.
All of these are either placed directly onto the stage, or is inside a movie clip that is linked to an AS file which contains all the code to power the engine. (The details aren’t important.)
We can then write collision detection code like this:
if ( ( hero.hitTestObject( platform1 ) ) || ( hero.hitTestObject( platform2 ) ) ) { //deal with this collision } |
…where “dealing with the collision” involves checking which side of the platform the hero is hitting and stopping it falling if necessary.
Obviously that if statement is going to get very long! There are other problems, too; when we add a new platform we have to add a new clause to the if statement; removing platforms is similarly messy.
We need a way to loop through all the platforms, without having to manually add new platforms to the loop.
Automatic Loops
In AS2 it was common to write code like this:
for (i = 1; i < 10; i++) {
var currPlatform = this["platform" + i];
//check currPlatform for collision with hero
//and deal with it
} |
this["platform" + i] gets a reference to the variable whose name is in the square brackets — so this["platform" + 1] is equal to platform1. As long as all our platforms have instance names that follow this pattern, the above code will deal with looping through them without any further changes on our part.
Well… except we have to change that i < 10 if we have more than 10 items. And we have to make sure that no two platforms have the same name. And, OK, it might be a bit of a pain to name every single platform.
We can do better. In AS3, every MovieClip (indeed, every DisplayObjectContainer) has a function, getChildAt() that returns each display object that has been “addChild()-ed” to them. This includes all the library symbols that you drag on to the clip at design time. If we use this with the numChildren property we can easily loop through every single object in the level:
var childIndex:int = 0; while ( childIndex < currentLevel.numChildren ) { currentLevel.getChildAt( childIndex ).alpha = 0.5; childIndex++; } |
(Here I’m assuming that we’ve made a new movie clip library symbol, dragged a bunch of objects into it, and have created a new instance of it called currentLevel.)
That’s just a simple demo that shows how to create such a loop, and sets the alpha of every item in the level to 50% to prove it works. Note: this entire article assumes that you have turned on Automatically declare stage instances in the Publish Settings. This may interfere with the rest of your code; we’ll look at getting around this in a follow-up article.
Thanks to OOP, we don’t need to give every platform an instance name. Instead, we can just give the platform symbol a class in the library — let’s call it Platform, for simplicity’s sake. In our code, we can use the is keyword to see whether the child of the level that we are currently looking at is an instance of the Platform class:
var childIndex:int = 0; while ( childIndex < currentLevel.numChildren ) { if ( currentLevel.getChildAt( childIndex ) is Platform ) { if ( hero.hitTestObject( currentLevel.getChildAt( childIndex ) ) ) { //deal with this collision } } childIndex++; } |
That code could be run every tick.
Of course, we can simplify this:
var childIndex:int = 0; var currentChild:DisplayObject; while ( childIndex < currentLevel.numChildren ) { currentChild = currentLevel.getChildAt( childIndex ); if ( currentChild is Platform ) { if ( hero.hitTestObject( currentChild ) ) { //deal with this collision } } childIndex++; } |
…and support other classes of object:
var childIndex:int = 0; var currentChild:DisplayObject; while ( childIndex < currentLevel.numChildren ) { currentChild = currentLevel.getChildAt( childIndex ); if ( currentChild is Platform ) { if ( hero.hitTestObject( currentChild ) ) { //deal with this collision } } else if ( currentChild is Enemy ) { if ( hero.hitTestObject( currentChild ) ) { //deal with this collision } } childIndex++; } |
In fact, we could just move most of the logic in here. For example, how about the enemy’s movement?
else if ( currentChild is Enemy ) { currentChild.moveABit(); if ( hero.hitTestObject( currentChild ) ) { //deal with this collision } } |
Looks good, but unfortunately currentChild.moveABit() will cause an error. That’s because all Flash knows about currentChild is that it’s a DisplayObject — and DisplayObjects don’t have a function called moveABit(). That’s OK; we can use casting:
else if ( currentChild is Enemy ) { (currentChild as Enemy).moveABit(); if ( hero.hitTestObject( currentChild ) ) { //deal with this collision } } |
(The as keyword just tells Flash, “treat this object as an instance of this class”.)
Sub-Classes of Objects
Suppose you wanted to create a new type of platform:

We’d set the class of this new platform to WoodPlatform, and change the old platform’s class to GrassPlatform to be consistent.
The obvious thing to do next is change our code like so:
currentChild = currentLevel.getChildAt( childIndex ); if ( ( currentChild is GrassPlatform ) || ( currentChild is WoodPlatform ) ) { if ( hero.hitTestObject( currentChild ) ) { //deal with this collision } } |
…but this leaves us with a similar problem to before; whenever we want to add a new class of platform, we’ll have to edit our code.
No need to worry, though, because we’ve got inheritance. Just create a new AS file like so:
package { import flash.display.MovieClip; public class BasePlatform extends MovieClip { public function BasePlatform() { } } } |
Now, whenever you create a new platform symbol, just set BasePlatform as its base class, like so:

If you don’t create the WoodPlatform class yourself, Flash will do it for you — and it’ll make it extend BasePlatform, too. This means that any instance of the WoodPlatform class counts as being an instance of the BasePlatform class, as far as the is keyword is concerned, so if you do this for all your platform symbols, you can simplify the troublesome code:
currentChild = currentLevel.getChildAt( childIndex ); if ( currentChild is BasePlatform ) { if ( hero.hitTestObject( currentChild ) ) { //deal with this collision } } |
Of course, you can do the same thing with enemies, and any other group of objects that share a common class.
Right now we’re looping through all the on-stage objects once per tick, and dealing with them as we come to them. But what happens if we want to check, for example, whether any bullet is colliding with any enemy? The normal method would be to use a nested loop — but the only way we can do that here is to loop through all the on-stage objects again.
We need to split everything into separate arrays. Let’s look at how to do that.
Arrays of Classes
I’d like to have a few arrays; one containing references to all the platforms, one for all the enemies, one for all the bullets, and so on. That way, I could organise my tick() function like so:
public function tick():void { for each ( var platform:BasePlatform in _platformsArray ) { if ( hero.hitTestObject( platform ) ) { //deal with collision } } for each ( var enemy:BaseEnemy in _enemiesArray ) { enemy.moveABit(); if ( hero.hitTestObject( enemy ) ) { //deal with collision } } for each ( var bullet:BaseBullet in _bulletsArray ) { bullet.moveABit(); for each ( var enemy:BaseEnemy in _enemiesArray ) { if ( bullet.hitTestObject( enemy ) ) { //deal with collision } } } } |
(That code could be optimised, but you get the idea.)
Not only does this allow shorter loops, and remove the need to cast elements of an array every time, it also lets us remove an object from the stage without destroying our means of access to it.
Getting the objects into the arrays is really simple. At the start of the level, we just call a function createLevelFromMovieClip() that works like this:
public function createLevelFromMovieClip( p_level:MovieClip ):void { _currentLevel = p_level; _enemiesArray = new Array(); _platformsArray = new Array(); _bulletsArray = new Array(); var childIndex:int = 0; var currentChild:DisplayObject; while ( childIndex < _currentLevel.numChildren ) { currentChild = _currentLevel.getChildAt( childIndex ); if ( currentChild is BasePlatform ) { _platformsArray.push( currentChild ); } if ( currentChild is BaseEnemy ) { _enemiesArray.push( currentChild ); } childIndex++; } } |
You could also make one master array of all the items inside the movie clip, then filter() it down to separate the platforms from the enemies.
Wrapping Up
We’ve separated the code from the layout to a great extent, and now we can use Flash’s toolbox to add, move and resize level objects without having to worry about changing the engine to deal with them.
The next step is separating the layout from the art, coping with multiple levels and objects with more properties than just position (like HP, for instance), and looking at the possibilities for in-game level editing.
Click here to read on

{ 17 comments… read them below or add one }
great! in as3, everything is more easy.
You are an absolute genius … :p
Thanks guys! Also thanks to Snurre for pointing out I forgot to put
childIndex++in my while loops. Whoops…It’s good to see how much work are in your articles. cheers!
Good article. I hope this is a begining of a mini series, because I’m really looking forward to the next step!
Cheers
And yep, I’ll be writing another post on this topic soon — probably this weekend.
So it seems I’m in the top Google results for ["No thanks, Chuckles!"]. That’s pretty funny. I feel I should mention that I came across the phrase in my favourite web comic about talking dinosaurs.
great explanation.
Cheers mitomane
I’m planning to make a level editor for my box2D based platformer game. And after reading your article, I feel like, “why should I make my own level editor if the flash IDE itself can be used as a level editor?” This really is a great Idea. Genius! Thanks for sharing
Thanks Ecky — that’s exactly how I feel! Glad you liked it
Funnily enough I’ve been working with Box2D myself recently, so I’ll be writing about that soon too.
Great article! I necessarily use it in my new game. Thanks a lot.
Cheers, buagaga.
Where does currentLevel come from? I understand you can drag an item to the stage and export it for actionscript, but how do you make everything you drag onto the stage a child of that one object?
Oh, good point, I didn’t explain that very clearly. The idea is, you create a new movie clip in the library, edit it, drag in a bunch of objects (platforms, etc), then export it for actionscript and create an instance called
currentLevel.Cheers for your comment, I’ve updated the tutorial to clear that up.
What should I do to think like you… I’m jealous you are a genius !
Quakeboy´s last blog: Simflex Image Gallery – Full Free Flex Image Gallery
Ahaha thanks man. Best comment ever