package
{
import flash.display.*;
import flash.geom.*;
import mx.collections.*;
import mx.core.*;
public class TiledBackground extends BaseObject
{
public var scrolling:Boolean = true;
protected var yOffset:Number = 0;
protected var definition:TiledBackgroundDefinition = null;
static public var pool:ResourcePool = new ResourcePool(NewTiledBackground);
static public function NewTiledBackground():TiledBackground
{
return new TiledBackground();
}
public function TiledBackground()
{
super();
}
public function startupTiledBackground(definition:TiledBackgroundDefinition):void
{
super.startupBaseObject(ZOrders.BACKGROUNDZORDER);
this.definition = definition;
this.yOffset = 0;
this.scrolling = true;
}
override public function shutdown():void
{
super.shutdown();
}
override public function enterFrame(dt:Number):void
{
if (scrolling)
{
var mapHeight:int = definition.tiles[0].length * definition.tileHeight;
var mapOverlap:int = mapHeight - Application.application.height;
yOffset += definition.tileScrollRate * dt;
if (yOffset > mapOverlap)
{
scrolling = false;
yOffset = mapOverlap;
}
}
}
override public function copyToBackBuffer(db:BitmapData):void
{
var startRow:int = yOffset / definition.tileHeight;
var startRowNumber:Number = yOffset / definition.tileHeight;
var startRowHeight:int = definition.tileHeight * (startRowNumber - startRow);
var drawnHeight:int = 0;
var drawnWidth:int = 0;
var layer:int = 0;
var row:int = startRow;
var col:int = 0;
// loop through each layer
for (layer = 0; layer < definition.tiles.length; ++layer)
{
// loop through each row
var count:int = 0;
for (row = (definition.tiles[layer] as Array).length - 1 - startRow; row >= 0 ; --row)
{
// loop through each column of the current row
for (col = 0; col < (definition.tiles[layer][row] as Array).length; ++col)
{
var graphics:GraphicsResource = definition.tiles[layer][row][col] as GraphicsResource;
var top:int = Application.application.height - drawnHeight - definition.tileHeight + startRowHeight;
if (graphics != null)
{
db.copyPixels(
graphics.bitmap,
graphics.drawRect,
new Point(
col * definition.tileWidth,
top),
graphics.bitmapAlpha,
new Point(
graphics.drawRect.x,
graphics.drawRect.y),
true);
}
drawnWidth += definition.tileWidth;
if (drawnWidth >= Application.application.width)
break;
}
drawnWidth = 0;
drawnHeight += definition.tileHeight;
if (drawnHeight >= Application.application.height + definition.tileHeight)
break;
}
drawnHeight = 0;
}
}
}
}
We have 3 properties to note here. The scrolling property is true while the level is scrolling, and false once the level has scrolled completely to the end. The yOffset property is used to store how far the level has scrolled. The definition property holds a reference to one of the tiled background definitions we created in the Level class.
The two functions that do the bulk of the work are the enterFrame and copyToBackBuffer functions. During the enterFrame function the TiledBackground scrolls down using the tileScrollRate property of the TiledBackgroundDefinition class to define the scrolling speed. Once it detects that it has reached the end of the level it sets scrolling to false and stops updating the yOffset property. The copyToBackBuffer function does the work of determining where to draw the tiles. It first loops through the layers, then the rows and then finally the columns to draw each tile individually in the correct position on the screen.
The creation of the TiledBackground class also required splitting up the old GameObject class. Originally the GameObject assumed that each element in the game could be represented by one GraphicsResource. Until TiledBackground that was a valid assumption, however the TiledBackground needs to access many hundreds of individual GraphicsResources to draw itself on the screen. To accommodate this we have created a new class called BaseObject which contains all the common properties of game elements, excluding the GraphicsResource. TiledBackground and GameObject both now extend BaseObject, while all other game element classes like Player and Enemy remain unaffected.
It’s the Level class that ultimately puts all this work together and creates a TiledBackground with the appropriate definition. Lets look at the new Actionscript for the Level class now.