Actionscript Code:
var myMap:Array = [
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1]
];
/*game will be an instance of GameBoard. This differs from your original
code because GameBoard is also a display object and will manage the tiles it
displays as well.
*/
var game:GameBoard = new GameBoard(30,30);
//Call a method in your GameBoard instance to associate numbers with Tile classes
game.setTileTypeIndex(0, GrassTile);
game.setTileTypeIndex(1, WaterTile);
/*call a method in your GameBoard instance to build the map and display
based on your myMap array
*/
game.buildMap(myMap);
/*put your GameBoard on the displayList as a child of the calling instance
(which is probably the main timeline)
*/
addChild(game);
Actionscript Code:
package{
//you will have to add imports here, such as:
import flash.display.Sprite;
/**
GameBoard is a class that models a grid of Tiles, and holds them as display
children
*/
/*extends Sprite because we need a DisplayObjectContainer, but we do
not need a timeline
*/
public class GameBoard extends Sprite{
/*in the top section of the class, we declare (but do not instantiate) the
class level variables.
*/
//public variables for tile width and height.
//these could just as easily be private
public var tileW:int;
public var tileH:int;
/*private variable to hold our 2d collection of Tiles
tiles is a Vector of Vectors, each of which holds Tiles
This is very similar to a 2d array, but with typechecking
Vectors are a flash 10 feature. If you must publish for versions below 10,
you will have to change this to a 2d Array
*/
private var tiles:Vector.<Vector.<Tile>>;
/*This will hold the associations between numbers and Tile Classes.
ideally, it would be something like a Map<int, Class>, but that sort of
parameterized type is not available in actionscript.
so I used an Array, which already maps ints to arbitrary Objects.
*/
private var tileDefinitionMappings:Array;
/*The GameBoard constructor. This is called when you call new
GameBoard(somewidth, someheight);
*/
public function GameBoard(tw:int, th:int){
/*by using "this." we explicitly call out the fact that we are setting
instance properties. In this case, it's not necessary because we
named our parameters to not conflict. But it's a good habit to get
into in the constructor
*/
//set tile width and height from parameters
this.tileW = tw;
this.tileH = th;
/*instantiate our tiles 2d vector and mapping array
if we didn't do this, they would remain null.
*/
this.tiles = new Vector.<Vector.<Tile>>();
this.tileDefinitionMappings = [];
}
/*this is a public function, meaning that any other class can call it, as
you see in the timeline code.
tileClass is a parameter of type Class, so we are not storing actual Tiles
in tileDefinitionMappings, but rather the Classes necessary to create
them.
*/
public function setTileTypeIndex(index:int, tileClass:Class):void{
tileDefinitionMappings[index] = tileClass;
}
//build our map based on a 2d array
public function buildMap(map:Array):void {
var mapWidth:int = map[0].length;
var mapHeight:int = map.length;
//it's convenient to have a variable to hold an entire row of Tiles.
var tileRow:Vector.<Tile>;
for (var i = 0; i<mapHeight; ++i) {
/*since our 2d tiles vector exists, but starts out empty, before we can
add a Tile, we must add the row the Tile goes in.
*/
tileRow = new Vector.<Tile>();
tiles.push(tileRow);
for (var j = 0; j<mapWidth; ++j) {
//I expanded the tile creation line into three parts
//get the int for the tile type from the map
var tileTypeIndex:int = map[i][j];
//get the tile class associated with that int from the definition mappings array
var tileClass:Class = tileDefinitionMappings[tileTypeIndex];
//create a new Tile from that class
/*I cast it to Tile here, because I'm not sure if the compiler will
complain otherwise. I'd have to try it.
*/
var tile:Tile = Tile(new tileClass());
//position your new tile.
tile.x = tileW * j;
tile.y = tileH * i;
//add the tile to the row
tileRow.push(tile);
//add the tile to the display
addChild(tile);
}
}
}
//this method retrieves a Tile from the grid by column and row.
public function getTile(col:int, row:int):Tile{
//check whether the row exists
if (row < tiles.length){
//get the row
var tileRow:Vector.<Tile> = tiles[row];
//check whether the column exists in that row
if (col < tileRow.length){
//return the Tile at that index.
return tileRow[col];
}
}
//if we get here, either the row or column didn't exist.
return null; //or throw error.
}
}
}