This is a follow-up post to How to Use the Flash IDE as a Level Editor. If you haven’t read that yet, check it out first!
Now that our code can detect the layout of symbols we’ve positioned using the IDE, we can separate levels’ layout from their appearance.
Why bother? Here’s a few reasons:
- We’ve designed level layouts, but not the artwork to go with them.
- There may be different people handling the art and the level design.
- We might want to keep the same game but alter the appearance for different websites
Plus, once we’ve put the work in, other benefits will appear; I’ll show you some of these in this post.
First, let’s look at using this to experiment with different “themes”.
Themed Levels
Going back to the platformer example, suppose that game actually splits levels up into different themes — like Zones in Sonic or Worlds in Mario. We’ve got a forest theme, with lots of grass and wood, a winter theme, with lots of snow and ice, and so on.
Now imagine we’ve designed a level layout and we can’t decide which theme would fit it best. We also need to consider how it slots into the game as a whole; we don’t want a really difficult level to come right at the start.
For the sake of this post I’ll assume we already designed this level using the forest theme’s graphics, and are just now having second thoughts. So here’s how it looks in the IDE:

The simplest thing to do would be to right-click every single object, select Swap Symbol, and choose the correct symbol from the library.

But this is tedious, and there’s a good chance we’ll make mistakes. It will be much simpler to automate this with code — and thanks to the loadLevelFromSymbol() function we wrote in the first part of this tutorial, we can do just that.
It just needs a little tweaking. First, we need to let the function create a new MovieClip based on the symbols from the IDE, rather than using the MovieClip that we pass it:
public function createLevelFromMovieClip( p_level:MovieClip ):MovieClip { var levelToReturn:MovieClip = new MovieClip(); var newObject:MovieClip; _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 ); newObject = null; if ( currentChild is BasePlatform ) { if ( currentChild is WoodPlatform ) { newObject = new WoodPlatform(); newObject.x = currentChild.x; newObject.y = currentChild.y; //set other properties here... levelToReturn.addChild( newObject ); } else if ( currentChild is GrassPlatform ) { newObject = new GrassPlatform(); newObject.x = currentChild.x; newObject.y = currentChild.y //set other properties here... levelToReturn.addChild( newObject ); } if ( newObject != null ) { _platformsArray.push( newObject ); } } if ( currentChild is BaseEnemy ) { //do the same thing with the enemy } childIndex++; } return levelToReturn; } |
That’s quite long, and could certainly be optimised, but you get the idea. The code that calls this function would now use the MovieClip that’s returned, rather than the one that was passed. This new MovieClip contains brand new GrassPlatforms, WoodPlatforms, and so on, with the same properties as in the IDE. All the arrays have been changed to hold these new objects, so they work as before.
Now this lets us introduce a new argument which holds the theme:
public function createLevelFromMovieClip( p_level:MovieClip, p_theme:String ):MovieClip |
…which in turn requires some changes to the while-loop:
while ( childIndex < _currentLevel.numChildren ) { currentChild = _currentLevel.getChildAt( childIndex ); newObject = null; if ( currentChild is BasePlatform ) { if ( currentChild is WoodPlatform ) { if ( p_theme == "Forest" ) { newObject = new WoodPlatform(); newObject.x = currentChild.x; newObject.y = currentChild.y; //set other properties here... levelToReturn.addChild( newObject ); } else if ( p_theme == "Winter" ) { newObject = new IcePlatform(); newObject.x = currentChild.x; newObject.y = currentChild.y; //set other properties here... levelToReturn.addChild( newObject ); } //check other themes... } else if ( currentChild is GrassPlatform ) { //same thing here: //depending on theme, create either GrassPlatform or SnowPlatform } if ( newObject != null ) { _platformsArray.push( newObject ); } } if ( currentChild is BaseEnemy ) { //do the same thing with the enemy } childIndex++; } |
So now we can switch from forest levels to winter levels on the fly, but we can’t do the other way round. Just as in the first post in this series, we could fix this by using messy chains of if statements:
if ( currentChild is BasePlatform ) { if ( ( currentChild is WoodPlatform ) || ( currentChild is IcePlatform ) ) //will get long! { if ( p_theme == "Forest" ) { newObject = new WoodPlatform(); //etc |
…and again we can avoid this by using inheritance. All we need to do is make both WoodPlatform and IcePlatform extend a common class — let’s say BridgePlatform — which in turn extends BasePlatform, and we can simplify the above:
if ( currentChild is BasePlatform ) { if ( currentChild is BridgePlatform ) { if ( p_theme == "Forest" ) { newObject = new WoodPlatform(); //etc |
(Naturally we would also make GrassPlatform and SnowPlatform extend a new class GroundPlatform which in turn extends BasePlatform.)
Now a level designed with one theme can be given another theme at run-time.
Bonus Benefits
If we create new symbols called BridgePlatform, GroundPlatform, and so on, we can even just use those to design our levels:

Actually, if you’re willing to write the code you could even make your function take a level like this:

…and automatically replace that long GroundPlatform with two regular (themed) ones, positioned side by side. Perhaps it could even choose different styles of GroundPlatform (within the same theme, of course!) to go next to each other, so that the ground isn’t just the same tile repeated over and over again.
Something to bear in mind here: the function I wrote above won’t do anything with any objects it doesn’t recognise. This can be beneficial; for example, I can write notes about certain layout decisions I made in order to share them with other people working on the game, or just so that I don’t forget them.

Since the function doesn’t have a if ( currentObject is SimpleText ) check, nothing will be done with this annotation and the player won’t see it. Admittedly, this could have been done before simply by adding all such text to a guide layer.
However, doing it this way gives us the opportunity to show the annotations inside the game — perhaps in debug mode, or an unlockable “developer’s commentary”. We’d just have to alter the above code so that it added the text objects to the new level MovieClip if (and only if) this were true.
This is Getting Silly
OK, I’ll admit I may be getting a bit too wrapped up in the technology here, and not looking at whether this would actually be useful in a game. The truth is, if a simple spritesheet swap is all that separates your forest levels from your winter levels, your game is probably quite dull. At the very least, you’d want your ice blocks to make the character slide around uncontrollably, like in every game ever, right? And speaking at a higher level, perhaps you’d want the forest levels to feel very claustrophobic, with obstacles all over the place, while winter levels were vast open spaces with a lot of bottomless pits.
Perhaps platformers are the wrong sort of game to use this with. A game like Breakout makes more sense, since all those tiles would be a pain to place with a text editor (in Flash we can just turn on Snap to Grid) and the appearance of the tiles shouldn’t affect the core gameplay (as evidenced by the million clones).
We can also use this approach for games where layout is not used to position actual in-game items. For example, suppose we were making a point and click game with several rooms. Naturally we’d need each room to know which other rooms surrounded it — the ballroom is north of the dining room, which is east of the drawing room, etc. This gets more complicated if you allow for different sizes of room.
We could just write code like:
ballroom.southRoom = diningRoom; diningRoom.northRoom = ballroom; //etc
But why not just create a bunch of movie clip symbols, one for each room, and lay them out in the IDE as you imagine them in the game world? A little code can work out how all the rooms connect, and you can reposition and resize them however you like. These symbols will never actually be seen in-game, but who cares? Remember, you have access to all the properties of a standard MovieClip, so that includes x, y, scaleX, scaleY, height, width, and many more besides. In fact, in a later post I’ll show you how to add properties of your own that can be edited within the IDE.
Having said all that, I do think there are two big reasons this is useful for all types of game (including platformers).
First, for prototyping. If you’re trying a whole bunch of different art styles out (pixel, photo, cartoon, …) it’s very handy to be able to switch between them by altering a few lines of code.
Second, you might not actually have access to the art assets. If you’re working with an artist, you wouldn’t expect them to finish all the art before you started on the code and level design. You might not even hire an artist until you have a demo up and running, in which case you can send them your programmer art spritesheet and say “like this, only good”. Again in a later post, I’ll show you how to keep your art assets, your code, and your level design all in separate files so that everyone involved can work on their part separately.
Click here to subscribe for free so that you don’t miss it

{ 5 comments… read them below or add one }
O_o This may be hard to use in an avoiding game, but for other games, this could be useful.
Gonna write a platformer tutorial soon?
Actually, I think you could use this in an avoider game. Check out the conversation between Fred and I in the comments of Turn Your Avoider Game into a Shoot-’Em-Up. He wanted to be able to define what time various enemies appeared; you could do this by creating a tall thin movie clip and dragging enemies onto it — your code would then interpret distance along the y-axis as time before the enemy appears.
Platformer games… I would love to write such a tutorial but don’t have the time. I wrote more about that in the comments of the About page actually. Mr Sun and Emanuele both have platformer tutorials, though
Great MJW! I loved this tutorial. You are getting close to what I saw on scripts of game emulators. They worked with many weapons, armors, spells, and just putting things as BaseWeapon, BaseArmor, BaseSpell made everything easier. I’m waiting for the next tutorial to start thinking on the structure of the engine of my next game. About the shape modelling I was searching: I found a good site (http://www.flashandmath.com/basic/drawpathCS4/index.html) with some cool scripts. I will use them on my starting code.
I wanna talk to you about some colision detection methods I found on the web, and about some other interesting things. When and where can we meet? Maybe at night on FGL? Thank you.
Thanks Daniel! I’m glad you found something for your modelling, that sounds like it’ll be a cool game. I’ll try to pop on FGL later tonight
Yay, another great tutorial Michael! I really like where this is going
and thanks for the link Daniel. This looks very nice.