So let’s say you’ve started work on your latest awesome game, and you’ve come up with this level design:

Graphics taken from Danc’s Miraculously Flexible Game Prototyping Tiles, which are awesome and free!
How are you going to store this map layout in code?
The One-Dimensional Case
If we just had a single line of tiles, it’d be easy:

We could just store it in a simple Array, like this:
var level:Array = new Array( 5 ); //there are five tiles level[0] = STONE; level[1] = WATER; level[2] = WATER; level[3] = WATER; level[4] = DIRT; |
…or like this:
var level:Array = new Array( 5 ); //there are five tiles level.push( STONE, WATER, WATER, WATER, DIRT ); |
…or this:
var level:Array = new Array( STONE, WATER, WATER, WATER, DIRT ); |
…or even just like this:
var level:Array = [STONE, WATER, WATER, WATER, DIRT]; |
All those code snippets do the same thing.
Then, when we want to find out what tile to place at each position, we can just look up the value of the element of the level array at that index. So, level[0] will be equal to STONE, level[3] will be WATER, and so on.
It’s difficult to imagine how it could be simpler. So how can we do this for a 2D map?
There is No Native 2D Array Class
In other programming languages (like C#, for example) , we could just create a 2D array which works in the same way as the regular array. So, if I label the rows and columns of the level design I posted above:

…then I can write how this would work in code:
var level:Array = new Array( 4, 5 ); //there are 4 rows and 5 columns level[0,0] = STONE; level[0,1] = WATER; level[0,2] = WATER; level[0,3] = WATER; level[0,4] = DIRT; level[1,0] = STONE; level[1,1] = WOOD; level[1,2] = WOOD; level[1,3] = WOOD; level[1,4] = DIRT; level[2,0] = STONE; level[2,1] = STONE; level[2,2] = WATER; level[2,3] = WATER; level[2,4] = DIRT; level[3,0] = STONE; level[3,1] = WATER; level[3,2] = WATER; level[3,3] = DIRT; level[3,4] = DIRT; |
Like before, we can look at individual elements in the array; for example, level[1,3] is equal to WOOD and level[2,0] is STONE.
But we cannot do this in AS3! There is no built-in 2D array class. If you write:
var level:Array = new Array( 4, 5 );
…then Flash will just make a new regular, one-dimensional array with level[0] equal to 4 and level[1] equal to 5.
The Solution: Nested Arrays
We know we can store an entire single row in an array, so why not just make four arrays, and store one row in each?
var firstRow:Array = [STONE, WATER, WATER, WATER, DIRT]; var secondRow:Array = [STONE, WOOD, WOOD, WOOD, DIRT]; var thirdRow:Array = [STONE, STONE, WATER, WATER, DIRT]; var fourthRow:Array = [STONE, WATER, WATER, DIRT, DIRT]; |
And there’s nothing to stop us putting arrays inside another array, so…
var level:Array = [firstRow, secondRow, thirdRow, fourthRow]; |
Now, level is an array of arrays. We call this “nesting arrays”, and we call each of firstRow, secondRow etc. “nested arrays”.
This means that level[0] is actually an array itself; level[0] is equal to [STONE, WATER, WATER, WATER, DIRT]. And we can access elements within this sub-array — so, level[0][0] is equal to STONE, level[0][3] is WATER, and so on.
In other words, we can access any element of this array of arrays using level[row][column]. Not bad!
Also, we don’t have to create the individual row arrays separately from the level array. It’s fine to do this:
var level:Array = new Array( 4 ); //there are four rows level[0] = [STONE, WATER, WATER, WATER, DIRT]; level[1] = [STONE, WOOD, WOOD, WOOD, DIRT]; level[2] = [STONE, STONE, WATER, WATER, DIRT]; level[3] = [STONE, WATER, WATER, DIRT, DIRT]; |
…or even:
var level:Array = [ [STONE, WATER, WATER, WATER, DIRT], [STONE, WOOD, WOOD, WOOD, DIRT], [STONE, STONE, WATER, WATER, DIRT], [STONE, WATER, WATER, DIRT, DIRT] ]; |
Looping Through Nested Arrays
To loop through nested arrays, we can use (not surprisingly) a nested loop. It looks like this:
for ( var row:int = 0; row <= 3; row++ ) { for ( var column:int = 0; column <= 4; column++ ) { trace( row, column, level[row][column] ); } } |
This would output:
0 0 STONE 0 1 WATER 0 2 WATER 0 3 WATER 0 4 DIRT 1 0 STONE 1 1 WATER 1 2 WATER
…and so on, down to:
3 4 DIRT
Ragged Arrays
Using an array of arrays like this allows us to create ragged arrays — that is, arrays where the rows can be of different lengths.
Suppose we have a level like this:

Those aren’t “invisible” tiles and the end of the rows; there are just no tiles there. We can easily store this level like so:
var level:Array = new Array( 4 ); //there are four rows level[0] = [STONE, WATER, WATER, WATER]; level[1] = [STONE, WOOD, WOOD, WOOD, DIRT]; level[2] = [STONE, STONE, WATER, WATER]; level[3] = [STONE, WATER, WATER]; |
Of course, you’ll get an error if you try to access level[3][4], so watch out for that. It’s a particular problem when looping; the above nested loop code needs to be modified like so:
for ( var row:int = 0; row < level.length; row++ ) { for ( var column:int = 0; column < level[row].length; column++ ) { trace( row, column, level[row][column] ); } } |
Note that instead of checking row <= 4, the outer loop checks row < level.length. level.length is the number of elements in the level array — i.e., the number of rows.
Similarly, the inner loop now checks column < level[row].length, i.e. it makes sure column is less than the number of tiles in the current row.
3D Arrays
We aren’t restricted to two dimensions. We could use as many dimensions as you like, but anything above 3D becomes hard to draw.

Here’s a map with rows, columns, and a third dimension: layers. Can you figure out how we could store it using nested arrays?

{ 1 trackback }
{ 39 comments… read them below or add one }
Beginner’s guide to using multidimensional arrays in AS3: http://bit.ly/8aTWOS
This comment was originally posted on Twitter
@keyeske This might be helpful to you: http://gamedev.michaeljameswilliams.com/2010/01/13/multidimensional-arrays-in-as3/
This comment was originally posted on Twitter
Please help im trying to figure out how I can attach movie clips to what i put in the array im trying to figure out how to make a inventory. Please help
Hey Keyeske,
I’m a little confused — do you mean you want to add movie clips to the screen (or to the inventory) based on what’s in the array?
Sory about that. add movie clips to the screen based on the array. I understand how the array works but I dont know how to use it
Ah, OK. Well, suppose you’re using Strings in your array, like:
…then to make it add movieclips corresponding to each item, you could start with a function like this:
for ( var i:int = 0; i < inventory.length; i++ ) { if ( inventory[i] == "potion" ) { var potionMC:MovieClip = new PotionMC(); addChild( potionMC ); potionMC.x = 50 * i; } else if ( inventory[i] == "hat" ) { var hatMC:MovieClip = new HatMC(); addChild( hatMC ); hatMC.x = 50 * i; } //...and so on for all your other items }That’s a basic start point using a 1D array. How’s that? Does it make sense?
Thanks im going to go and try it. oh sorry if i keep buggin you but how do i use splice and push? sorry if i seem noobish im more of an artist but im trying to learn programming to do my rpg
No problem. I actually get a lot of questions about arrays; maybe I should expand this into a series?
You use
push()to add one or more new items to the end of an existing array. So, if you have this:…and you
trace( inventory ), you’ll get this:But if you put this after the existing code:
…and then
trace( inventory )again, you’ll get:Splicing an array has the opposite effect; it’s used to remove items. You tell it where to start and how many to remove, and it does that. So, if we continue with the above “inventory” array, and do:
…it’ll remove two items, starting with
inventory[1]. That means that if you nowtrace( inventory ), you’ll get:Make sense?
Dru Kepple wrote a great guide to arrays over at activetuts+, and there’s loads of info about arrays on the livedocs page, by the way
Multidimensional Arrays in AS3 http://bit.ly/7HzpW7
This comment was originally posted on Twitter
Multidimensional Arrays in AS3 http://bit.ly/7HzpW7 (via @bioRex21)
This comment was originally posted on Twitter
Thanks Michael for another great tutorial. “Can you figure out how we could store it using nested arrays?” We should add an new dimension to the array for the layers. Maybe like this:
For the readout we need to add an another for-loop. I think this should work. A little question: What is the best way to store this data, if you have for example 10 gamelevels? Should I store it into in xml-files like for each gamelevel?
Hey Martin, cheers for your kind words
Nice solution! Yes, it’ll work. But, I’m curious as to how you’ll choose to store the second and third layers, where there are some blank spaces?
You could use XMLs, if you wanted to, or you could even just create the arrays directly in code, like:
if ( levelNumber == 1 ) { level = new Array(); level[0] = [STONE, WATER, WATER, WATER, DIRT]; level[1] = [STONE, WOOD, WOOD, WOOD, DIRT]; ///...etc... } else if ( levelNumber == 2 ) { level = new Array(); level[0] = [WATER, STONE, STONE, DIRT, DIRT]; level[1] = [WATER, WATER, STONE, STONE, DIRT]; //...etc... } //...etc...…but that’s a bit messy. Still, it works, but XML’s probably going to be neater, yeah.
Yes pleas do turn this in to a series.
-Wes
Multidimensional Arrays in #AS3. Good primer for dealing with arrays in #flex http://bit.ly/8aTWOS
This comment was originally posted on Twitter
And how about encrypting the level code to an much shorter string, it saves up alot of space especially on large maps.
Tom — smart idea! You mean, like, we’d store the level as
"12223/14443/11223/12233"in a String and then use code to convert it in to tiles in an Array later?So yeah, I prefer this method
I used this in my Bloons clone to create waves like this here
var waveColors = new Array(); waveColors[0] = new Array(); waveColors[0][1] = "green"; // so green enemies will be the first part wave waveColors[0][2] = "yellow"; // so yellow enemies will be the second part wave
I actually don’t like the way it’s shown here, I prefer my way, but I guess that’s anyone’s decision which style he/she prefers =D
EDIT: To you two guys with your string idea, thats quite neat, e.g. having such a format like “(1/1,grass)(1/2,sea)” so f.e. tile at position 1/1 will be created as a grass tile. Reading out with substrings would be one way, but I myself dislike working with substring or other string functions though they are very useful, I don’t like them (as I’m having troubles using ‘em lol)
ANOTHER EDIT: To your small challenge (3D Arrays), to me, that’s mere child’s play lol (yep, I’m a poser lulz)
ANOTHEROTHER EDIT: How about not coding this at all and using Flash IDE to simply create Areas that you render to the screen and then giving actions to the single tiles? That would be far better for you to create
Best regards
So, does that code mean you’d have 25 green enemies followed by 10 yellow enemies in the first wave?
I can see that laying out the code like that makes it much clearer, in that case. Though, I would personally prefer interspersing them like so:
waves[0][0] = 25; waveColours[0][0] = "green"; waves[0][1] = 10; waveColours[0][1] = "yellow" //...etc...
…but as you say, it’s up to the coder which style they like
Fast answer, lol, yeah I thought about that one, too, but came along to not change it (because of laziness (I got PLENTY)) after I’ve set it up for the first time =D
Euhm… pherhaps, but I found this:
http://www.newgrounds.com/bbs/topic/1107353
It’s by a guy named glaiel gamer … he’s kind-off good
Wow, OK, that’s… a little more complex than I was thinking, haha!
Awesome post, thanks for linking to it.
Edit: Ooh, he made Closure, I thought his name was familiar.
Multidimensional Arrays in AS3 by @MichaelJW http://bit.ly/7HzpW7 great stuff as always
This comment was originally posted on Twitter
Multidimensional Arrays in AS3 by @MichaelJW http://bit.ly/7HzpW7 great stuff as always
This comment was originally posted on Twitter
Interesting… now I want to see a flash game in 4D… And the string idea would be especially good for user level creation.
4D game? Miegakure. OK, not Flash, but still
Yeah, that’d make it easy to share levels, just copy and paste the string into a comment or email or whatever.
Not only that, you could probably embed it into a link via GET to change the flashvars, so someone could just go online and automatically load that level (if that makes any sense).
Also, I don’t think that is 4D (technically). See this: http://en.wikipedia.org/wiki/Four_dimensionalism
Even better! So you’d have http://mysite.com/mygame.html?levelCode=4jh7fgdfjh874n and it’d load it up immediately. Awesome.
Hmm, but if 4D games involve treating time like the three spatial dimensions, then how do you play?
how about creating a multidimensional array by a loaded xml file of unknown depth. its easy to make a recursive function and parse the xml file, its also easy to know in each step of the way the depth inside the xml file you are into, but how about creating a multidimensional array representing the structure of the xml file, and inside each sub array storing the data and attributes from the xml file. let me give you an example :
public class sec_xml { private var xml:XML; private var results_array,temp_arr,temp_results_arr,inner_arr:Array; private var depth:int; private var xml_parent,xml_prev_parent:String; private var had_same_parent:Boolean; public function sec_xml(xml:XML) { this.xml=xml; var intial_attr_len:int=xml.attributes().length()-1; results_array=[]; inner_depth=0; if (intial_attr_len>=0) { for (var i:int=0; i<=intial_attr_len; i++) { results_array[xml.attributes()[i].name().toString()]=xml.attributes()[i]; } } for each (var xml_l:XML in xml.elements()) { temp_arr=[]; temp_results_arr=[]; had_same_parent=false; depth=0; dig_deeper(xml_l,temp_results_arr); } } private function dig_deeper(xml:XML,arr:Array=null):void { /// if the xml instance is new hold its depth for later use xml_parent=xml.parent().name(); if (xml_parent!=xml_prev_parent&&temp_arr[xml.parent().name()]==null) { temp_arr[xml.parent().name()]=depth; trace("storing value ---- "+xml.parent().name()+" = "+temp_arr[xml.parent().name()]); } /// reads attributes for each (var att:XML in xml.attributes()) { //trace("attribute "+att.name()+" = "+att); arr[att.name().toString()]=att; } /// reads text if (xml.children()==xml) { arr[xml.name().toString()]=xml; //trace("final "+xml.name()+" = "+xml); } insert_into_array(arr,xml_parent); if (xml.children()!=xml) { /// reads next xml instance for each (var new_xml:XML in xml.elements()) { dig_deeper(new_xml,arr); } } } /// when data from each node is collected store it to temp_results_arr private function insert_into_array(arr:Array,xml_parent:String):void { if (xml_parent==xml_prev_parent) { /// if node was from the same depth dont increase it had_same_parent=true; temp_results_arr=arr; handle_temp_res_arr(arr,depth-1); } else if (xml_parent!=xml_prev_parent) { /// if node its from diffenet depth get correct depth if (had_same_parent) { depth=temp_arr[xml_parent]; } temp_results_arr=arr; handle_temp_res_arr(arr,depth); depth++; } xml_prev_parent=xml_parent; } private function handle_temp_res_arr(arr:Array=null,in_depth:int= 0):void { if (inner_depth==in_depth) { /// its the first line results_array.push(temp_results_arr);Great turorial. Game I’m working on right now is pretty similar to this one. However, I used another method of doing this. However it doesn’t do same thing also, but in my game it works same
@theo: whoa, impressive code… but wouldn’t it require all your attributes and so on to be named after numbers? I say that because of lines like this:
@Kustrle: Cheers. Ah, is that the game you posted screenshots of in the Frozen Haddock forums?
hi, yes they can be named after numbers in order to represent the depth , so when you read the multidimensioanl array to sort it out according to the numbers, or text and attributes can be saved as objects inside the array as well. its a matter of choice
Yes, do you think I am able to developing two games at same time
? Just one is too hard for me…
@theo: Nice! Are you using that anywhere?
@Kustrle: hehe; well, how’s that one game going then?
Thank you for explaining this so well
haha if you can develop one game you can develop 2 or as many as you want.
Cheers
As 3D arrays are very large – then a Voxel or nested arrays of might be less advantageous than a scene graph.
I think this is nested lists of objects and their children.
every object knows where it is and which way it facing.
the advantage is you don’t need to iterate over empty space 8-*.
objects are usually lists of vertices, with corresponding facet groups, then colours and decals stuck on them and maybe skeletal sytems for character animation.
as regards the 4th dimension of time usually some algorythmic shorthand is required such as only storing keyframes and tweening, morphing and interpolating and deforming objects based on their skeletons.
A type of XML is usually used for this, for instance.
a scene graph in XML with the indentation indicating “is a child of” so everything is a child of Level1. The Location Details can be nested so the Sword is a child of the hero and moves relative to him.
Back when the Web was born it was in 3d and 2d and they called it VRML and HTML. :=)
Hope this helps and thanks for all the hard work, your tutorials are excellent and bug free – rare and fine qualities.
VRML! Wow, I remember that
So basically, you’re talking about basing the data structure on the objects in the space, rather than on the points in space themselves?
Good point! And yeah, XML is a good fit for this. But also, AS3’s own object/class model works well, too —
hero.addChild( sword )Thanks for the kind words
<
p>First of all, great stuff here/p>
Hello everyone,
i have the following problem:
I have to describe a colored grid where at x,y position the colour can be red, green etc. etc.
This was really easy for me in basic, but i can’t do in the right way in actionscript.
basic
dim grid%(1 To 10, 1 To 10) grid%(4,5)=3: rem grid cell at 4,5 will have color 3 (red)
now, what will be this code in actionscript?
Moreover, i want to add a description for the colored cell of the grid
thank you Best regards