Flash Game Development with Flex and Actionscript - User Input and an Animated Background (Page 4 of 5)

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

BackgroundLevelElement.as

package

{

import flash.geom.Point;

import mx.core.*;

import mx.collections.*;

public class BackgroundLevelElement extends GameObject

{

static public var pool:ResourcePool = new ResourcePool(NewBackgroundLevelElement);

protected var scrollRate:Number = 0;

static public function NewBackgroundLevelElement():GameObject

{

return new BackgroundLevelElement();

}

public function BackgroundLevelElement()

{

}

public function startupBackgroundLevelElement(bitmap:GraphicsResource, position:Point, z:int, scrollRate:Number):void

{

startupGameObject(bitmap, position, z);

this.scrollRate = scrollRate;

}

public override function enterFrame(dt:Number):void

{

if (position.y > Application.application.height + graphics.bitmap.height )

this.shutdown();

position.y += scrollRate * dt;

}

}

}

Functionally the BackgroundLevelElement is very similar to the Bounce class from part 3. It extends the GameObject class to display a graphic on the screen, and moves in a straight line in the enterFrame function. Unlike the Bounce object, a BackgroundLevelElement object will eventually move completely off the screen, at which point the shutdown function is called. This returns the object back into a ResourcePool, ready to be reused.

So what is a ResourcePool? To explain that we first need to explain the basic concepts of memory management.

In its simplest form, memory management is the process of creating new objects in memory and then removing them from memory (or destroying them) when they are no longer needed. Languages like C++ expect you to manually keep track of any new object you create, and then later manually destroy them. Failure to do so leads to a memory leak; a situation where objects never get destroyed causing the memory usage of a program to grow continuously. Most modern languages (including ActionScript) employ a garbage collector to destroy objects that are no longer referenced, thus automating the process of destroying objects.

On the surface a garbage collector looks like an ideal solution, but it has its own drawbacks. Whereas C++ would have a memory leak if objects were not manually destroyed, ActionScript can have the same problem if objects are unintentionally referenced after they are no longer required. While the semantics are different the end result is the same: continuously growing memory usage. Another downside to garbage collection is that object destruction in non-deterministic, which is a fancy way of saying that you as the developer have no way to know exactly when an unreferenced object will actually be destroyed. Garbage collection also incures a performance hit. Having the garbage collector trawl through hundreds of objects and destroy those that are no longer referenced takes time, and while it may or may not be noticeable, its doesn’t hurt to be aware that it is happening.

Resource pooling solves many of these problems. Basically it keeps a collection of objects in a pool. As the objects are needed they are taken out of the pool and initialised (note initialised is not the same a being created from scratch with the new function). Once they are no longer needed they are cleaned up and put back in the pool.

By keeping the objects in a pool you avoid having to continuously create new objects. This in turn reduces the number of objects that exist in memory, which reduces the workload for the garbage collector. Also, by creating and destroying resources in a deterministic way (when the object is taken out of the pool, and before it is returned) we gain more control over the memory management process.

ResourcePool.as

package

{

import mx.collections.*;

public class ResourcePool

{

protected var pool:ArrayCollection = new ArrayCollection();

protected var newObject:Function = null;

public function ResourcePool(newObject:Function)

{

this.newObject = newObject;

}

public function get ItemFromPool():GameObject

{

for each (var item:GameObject in pool)

{

if (!item.inuse)

return item;

}

var newItem:GameObject = newObject();

pool.addItem(newItem);

return newItem;

}

}

}

If you found the wordy description of a resource pool a little overwhelming, you’ll find the actual code to be surprisingly simple. There are two properties to the ResourcePool. The pool property contains a collection of the GameObjects that have bee created through the pool object. The newObject property points to a function that is used to create a new GameObject if there are no free objects left in the pool. The ItemFromPool function is used to get an unused GameObject from the pool. It loops through the pool collection looking for the first unused (i.e. where inuse is false) object and returns it. If none can be found it calls the newObject function to create a new GameObject, adds that to the pool, and returns it.

Looking back to the BackgroundLevelElement class you will see that we have created a function called NewBackgroundLevelElement. This function creates a new BackgroundLevelElement, and is the function that is passed to the constructor of the ResourcePool, which allows the ResourcePool to create new BackgroundLevelElements when the pool is exhausted.

Having created the BackgroundLevelElement class we now need some way of adding them to the game. For this we create the Level class. Lets take a look at the code.

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