# Multidimensional Arrays in AS3

by on January 13, 2010 · 62 comments

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:

?View Code ACTIONSCRIPT3
 ```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:

?View Code ACTIONSCRIPT3
 ```var level:Array = new Array(); //no tiles yet level.push( STONE, WATER, WATER, WATER, DIRT );```

…or this:

?View Code ACTIONSCRIPT3
 `var level:Array = new Array( STONE, WATER, WATER, WATER, DIRT );`

…or even just like this:

?View Code ACTIONSCRIPT3
 `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:

?View Code ACTIONSCRIPT3
 ```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?

?View Code ACTIONSCRIPT3
 ```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…

?View Code ACTIONSCRIPT3
 `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:

?View Code ACTIONSCRIPT3
 ```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:

?View Code ACTIONSCRIPT3
 `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:

?View Code ACTIONSCRIPT3
 ```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:

?View Code ACTIONSCRIPT3
 ```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:

?View Code ACTIONSCRIPT3
 ```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?

Bret July 11, 2011 at 5:36 am

Is there a way to accomplish this using Object literals?

something like :

```public var map = new Object();
map.row1 = 'row1';
map.row1.a = 'Stone';
map.row1.b = 'Stone';
```

Roland October 3, 2011 at 6:01 am

Hi! How i could add a mouse event.CLICK to each of those graphics, which are placed on the stage using these methods?

And after i have been clicked, then check what have i clicked and after that trace something or something like that.

Thank.

patrik October 3, 2011 at 1:37 pm

FIRECREATURE January 29, 2012 at 2:54 pm

Very useful post. Thanks.

TJenner2 February 9, 2012 at 2:46 pm

@ROLAND

I think you want to look at this site here:
http://www.learningactionscript3.com/2008/05/17/grids-arranging-clips/

It explains how to do grids in ActionScript 3.0 which is nothing like it was in 2.0

Eddie J February 21, 2012 at 5:08 pm

Thank you for writing this. It’s always a little confusing for me when working with multidimensional arrays. Also, this is how to define a 2D array

`var _myArr:Array = [[],[]];`

Cheers

jeetendra singh September 3, 2012 at 7:42 am

```var level:Array = new Array( 5 );    //there are five tiles
level.push( STONE, WATER, WATER, WATER, DIRT );
```

this code will not produce same result as other snippet it will produce 10 element array (not 5)

am i wrong?

Michael James Williams September 3, 2012 at 8:54 am

Jeetendra: you are correct. Oops.

Juliorob December 29, 2012 at 8:42 pm

Thanks, this helped me a lot. You presented the solution very clearly and clean, keep it up.

Ivan July 10, 2013 at 6:16 pm

var squares:Array = new Array(new Array());
squares[x][y] = new square_object();

moneyisshame July 25, 2013 at 3:19 pm

for 3D is it?:

``` //start creating 2D z = 0
var firstRow:Array = [STONE, WATER, WATER, WATER, DIRT]; // y = 0
var secondRow:Array = [STONE, WOOD, WOOD, WOOD, DIRT];// y = 1
var thirdRow:Array = [STONE, STONE, WATER, WATER, DIRT]; //y = 2
var fourthRow:Array = [STONE, WATER, WATER, DIRT, DIRT];//y = 3
//stop creating 2D z = 0  x = 0       x = 1       x=2       x=3    x=4
var z0 = [firstRow, secondRow, thirdRow, fourthRow];```

//start creating 2D z = 1
var firstRowZ:Array = [AIR, AIR, AIR, AIR, PLAYER]; // y = 0
var secondRowZ:Array = [STAIR, WOOD, WOOD, WOOD, STAIR];// y = 1
var thirdRowZ:Array = [AIR, CHEST, AIR, AIR, AIR]; //y = 2
var fourthRowZ:Array = [AIR, AIR , AIR, GEM, AIR];//y = 3
//stop creating 2D z = 1 x = 0 x = 1 x=2 x=3 x=4
var z0 = [firstRowZ, secondRowZ, thirdRowZ, fourthRowZ];

//start creating 2D z = 2
var firstRowZ2:Array = [AIR, AIR, AIR, AIR, AIR]; // y = 0
var secondRowZ2:Array = [AIR, AIR, LADYBUG, AIR, AIR];// y = 1
var thirdRowZ2:Array = [AIR, AIR, AIR, AIR, AIR]; //y = 2
var fourthRowZ2:Array = [AIR, AIR, AIR, AIR, AIR];//y = 3
//stop creating 2D z = 2 x = 0 x = 1 x=2 x=3 x=4
var z2 = [firstRowZ2, secondRowZ2, thirdRowZ2, fourthRowZ2];

var myLevel:Array = [z0,z1,z2];