Caching rotations as bitmapdata in flex AS3

Well what would be better for PI day then a brief tutorial on caching rotation sprites in adobe flex. While porting “Ava the Firefly” to Flex, I have encountered a bit of a snag in how the Flex framework handles rotation. In XNA, it is as simple as passing a parameter to the draw method on the Spritebatch. In AS3/Flex… not so much. The issue.. discussed here, is that performing a matrix operation to rotate a bitmapdata object once per frame will drastically impact performance in a negative way as the number of rendered sprites increases. The consensus appears to be to use a cache for the rotation information.

Here is how I handled the problem.

		static public function rotate(image:DisplayObject, degrees:Number = 0, colorTransform:ColorTransform = null):BitmapData
		{
			var matrix:Matrix = new Matrix();
			     matrix.translate(-image.width/2,-image.height/2)
			     matrix.rotate(degrees * degreeToRadians);
			     matrix.translate((image.width/2),(image.height/2))
 
			var bitmap:BitmapData = new BitmapData(image.width, image.height, true, 0x000000);
			bitmap.draw(image, matrix, colorTransform, BlendMode.LAYER, null, true);
 
			return bitmap;
		}

This will take an image an rotate it, returning the bitmapdata.
In my case, I create an array of images from a sprite sheet and build a cache of all the possible rotations of each frame in the animation.

		// Create a multidimensional array for the given index
		// ie. increment of 10 will cache all rotations in 10 degree increments (36 bitmaps)
		static public function buildRotationCache(image:DisplayObject,
                                                                       imageArray:Array,
                                                                       frameIndex:Number,
								       increment:Number,
								       colorTransform:ColorTransform = null ):void
		{
			var rotationIndex:Number = 0;
			for (var k:Number = 0; k < 360; k+= increment )
			{
				var bm:Bitmap = new Bitmap(GraphicsUtil.rotate(image , k, colorTransform));
				var gr:GraphicsResource = new GraphicsResource(bm);
 
				imageArray[frameIndex][rotationIndex] = gr;
				rotationIndex++;
			}
		}

the graphics resource class is from a tutorial found here

package
{
	import flash.display.*;
	import flash.geom.ColorTransform;
 
	public class GraphicsResource
	{
		public var bitmap:BitmapData = null;
		public var bitmapAlpha:BitmapData = null;
 
		public function GraphicsResource(image:DisplayObject)
		{
			bitmap = createBitmapData(image);
			bitmapAlpha = createAlphaBitmapData(image);
 
		}
 
		protected function createBitmapData(image:DisplayObject, colorTransform:ColorTransform = null):BitmapData
		{
			var bitmap:BitmapData = new BitmapData(image.width, image.height);
			bitmap.draw(image, null, colorTransform);
			return bitmap;
		}
 
		protected function createAlphaBitmapData(image:DisplayObject):BitmapData
		{
			var bitmap:BitmapData = new BitmapData(image.width, image.height);
			bitmap.draw(image, null, null, flash.display.BlendMode.ALPHA);
			return bitmap;
		}
 
	}
}

All for now. Happy coding..

Leave a Reply

Your email address will not be published. Required fields are marked *


5 × three =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>