Flash Game Development with Flex and Actionscript - Tiled Background Rendering (Page 2 of 4)

Article by Matthew Casperson (4,883 pts ) , published Nov 6, 2009

LevelDefinitions.as

package

{

import flash.geom.*;

import flash.utils.*;

public class LevelDefinitions

{

protected static var instance:LevelDefinitions = null;

protected var levelDefinitions:Dictionary = new Dictionary();

public var levelTileMaps:Dictionary = new Dictionary();

static public function get Instance():LevelDefinitions

{

if ( instance == null )

instance = new LevelDefinitions();

return instance;

}

public function LevelDefinitions()

{

}

public function addLevelDefinition(levelID:int, element:LevelDefinitionElement):void

{

if (levelDefinitions[levelID] == null)

levelDefinitions[levelID] = new Array();

(levelDefinitions[levelID] as Array).push(element);

levelDefinitions[levelID].sort(LevelDefinitionElement.sort);

}

public function getNextLevelDefinitionElements(levelID:int, lastTime:Number):Array

{

var returnArray:Array = new Array();

var nextTime:Number = -1;

if (levelDefinitions[levelID] != null)

{

for each (var levelDefElement:LevelDefinitionElement in levelDefinitions[levelID])

{

if (levelDefElement.time > lastTime && nextTime == -1)

{

returnArray.push(levelDefElement);

nextTime = levelDefElement.time;

}

else if (levelDefElement.time == nextTime)

{

returnArray.push(levelDefElement);

}

else if (levelDefElement.time > nextTime && nextTime != -1)

break;

}

}

return returnArray.length == 0?null:returnArray;

}

public function getNextLevelID(levelID:int):int

{

if (levelDefinitions[levelID + 1] == null) return 0;

return levelID + 1;

}

public function startup():void

{

GameObjectManager.Instance.addCollidingPair( CollisionIdentifiers.PLAYER, CollisionIdentifiers.ENEMY);

GameObjectManager.Instance.addCollidingPair( CollisionIdentifiers.ENEMY, CollisionIdentifiers.PLAYERWEAPON);

GameObjectManager.Instance.addCollidingPair( CollisionIdentifiers.PLAYER, CollisionIdentifiers.ENEMYWEAPON);

defineLevel1();

defineLevel2();

}

public function shutdown():void

{

}

protected function defineLevel1():void

{

var level1Tiles:TiledBackgroundDefinition = new TiledBackgroundDefinition();

levelTileMaps[1] = level1Tiles;

level1Tiles.tileScrollRate = 25;

level1Tiles.tileHeight = 40;

level1Tiles.tileWidth = 40;

level1Tiles.tiles =

[

[

[ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1]

...

,[ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1, ResourceManager.GreenGraphicsID1]

]

,[

[null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]

...

,[null, ResourceManager.GreenGraphicsID62, ResourceManager.GreenGraphicsID63, ResourceManager.GreenGraphicsID64, null, ResourceManager.GreenGraphicsID48, ResourceManager.GreenGraphicsID49, null, null, null, null, null, null, null, null]

]

];

LevelDefinitions.Instance.addLevelDefinition(

1,

new LevelDefinitionElement(

4,

function():void

{

for each (var xPos:int in [150, 350])

{

(Enemy.pool.ItemFromPool as Enemy).startupBasicEnemy(

ResourceManager.SmallBluePlaneGraphics,

new Point(xPos, -ResourceManager. SmallBluePlaneGraphics.bitmap.height),

55);

}

}

));

...

}

protected function defineLevel2():void

{

...

}

}

}

We have added one new property, levelTileMaps, which is a Dictionary used to map TiledBackgroundDefinitions to LevelID’s (much like the levelDefinitions property we added in part 9).

In addition we have also added two new functions: defineLevel1 and defineLevel2. These functions exist as a way of separating out the code used to define separate levels, which as you can see gets quite verbose with the new tiled background definitions. Inside these functions we create one TiledBackgroundDefinition object, initialise its properties and then assign it to the levelTileMaps property.

When you create a level with TaT you get two files that are important for each level: the tileset.xml (which defines the individual tiles that make up a level) file and the YourLevelName.xml file (which defines how the tiles have been laid out to make a level). It’s the data from the YourLevelName.xml file that we put inside the tiles array.

You may be wondering how we went from the XML file created by the TaT editor to a multidimensional array. The short answer is that I cheated and wrote another application that takes the XML from TaT and converts it into the Actionscript code that creates the array you see here. The reason why I didn’t just parse the XML inside the application directly is much the same reason as why I choose not to define the level structure in XML: because parsing XML and converting string references to object references is a tedious process, and in this case writing an application to convert the XML to Actionscript was easier. While I won’t go into the code for the conversion application (it was a very quick and dirty program) you can download it from the Sourceforge SVN repository at http://flexfighters.svn.sourceforge.net/viewvc/flexfighters/TatResourceParser/.

The second XML file created by the TaT editor defines the individual tiles that make up a level. Using the same application I mentioned above we have converted that XML data into the matching Actionscript code that embeds the images and then creates the matching GraphicsResource objects in the ResourceManager class. This new code is vert repetitious, so I will only show a fraction of the new resource definitions here.

ResourceManager.as (sample of new code)

[Embed(source="../media/Green26.png")]

public static var GreenID65:Class;

public static var GreenGraphicsID65:GraphicsResource = new GraphicsResource(new GreenID65());

[Embed(source="../media/Green5.png")]

public static var GreenID11:Class;

public static var GreenGraphicsID11:GraphicsResource = new GraphicsResource(new GreenID11(), 1, 1, new Rectangle(0, 0, 40, 40));

public static var GreenGraphicsID12:GraphicsResource = new GraphicsResource(new GreenID11(), 1, 1, new Rectangle(40, 0, 40, 40));

public static var GreenGraphicsID17:GraphicsResource = new GraphicsResource(new GreenID11(), 1, 1, new Rectangle(0, 40, 40, 40));

public static var GreenGraphicsID18:GraphicsResource = new GraphicsResource(new GreenID11(), 1, 1, new Rectangle(40, 40, 40, 40));

This code is the same as other resource definitions, with the exception of a new parameter passed to the ResourceManager in some cases. This is to accommodate what TaT refers to as “structures” - pictures that have been added to the level that are larger than the tile size. So for example a tile may be 40x40 pixels, but a tree image might be 40x80 pixels. In this case the tree image would be referenced as two separate images by the tile definition, one tile being the top of the tree and the second being the bottom. By allowing the GraphicsResource to reference the same area we can easily reference the same tile areas.

Now that we have a way to define and store the tiled background definitions it’s time to create a class that can read that data and actually draw the level to the screen. For that we create the TiledBackground class. Lets look at that Actionscript code now.

Showing page 2 of 4
Subscribe to Web Development
RSS
Get free weekly updates, directly to your inbox.
Browse Web Development