Starling ImageBatch is an optimized image batching for Starling. It can efficiently (in terms of CPU and memory) render a large number of images sharing the same texture. This class is designed as an object pool: items are recycled and vectors are never modified.

ImageBatch allows you to animate each element independently, even though they all share the same texture.

Some features:

  • low memory footprint, items pooling
  • animate: x, y, scale, alpha, color, rotation, texture
  • (shared) spritesheet support
  • store custom data in items’ “tag” property

Sample

package  
{
	import starling.events.EnterFrameEvent;
	import starling.events.Event;
	import starling.extensions.BatchItem;
	import starling.extensions.ImageBatch;
	import starling.textures.Texture;
	import starling.textures.TextureAtlas;

	/**
	 * Animate plenty of stars
	 * @author Philippe / http://philippe.elsass.me
	 */
	public class Stars extends ImageBatch 
	{
		[Embed(source = "stars.png")]
		private const starTexture:Class;
		[Embed(source = "stars.xml", mimeType = "application/octet-stream")]
		private const starAtlas:Class;

		private var steps:int = 60;
		private var anim:Vector.;
		private var atlas:TextureAtlas;

		public function Stars() 
		{
			super(Texture.fromBitmap(new starTexture()));

			var xml:XML = XML(new starAtlas());
			atlas = new TextureAtlas(texture, xml);

			addEventListener(Event.ADDED_TO_STAGE, addedToStage);
		}

		private function addedToStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStage);

			anim = new Vector.();
			for (var j:int = 0; j < steps; j++) 
				anim.push(0.5 + 0.5 * Math.cos((j / steps) * Math.PI * 2));

			var n:int = 8000;
			var t1:Texture = atlas.getTexture("star1");
			var t2:Texture = atlas.getTexture("star2");

			for (var i:int = 0; i < n; i++)  			{ 				var item:BatchItem = addItem(); 				item.x = Math.random() * stage.stageWidth; 				item.y = -10 + Math.random() * (stage.stageHeight + 20); 				item.scale = 0.2 + Math.random() * 0.2; 				item.angle = Math.random() * Math.PI * 2; 				item.color = Math.random() * 0xffffff >> 0;
				item.texture = (i / 100) & 1 ? t1 : t2; // use a custom texture from atlas
				item.tag = Math.random() * steps >> 0; // store any data in item.tag
			}

			addEventListener(EnterFrameEvent.ENTER_FRAME, enterFrame);
		}

		private function enterFrame(e:EnterFrameEvent):void 
		{
			var sh:int = stage.stageHeight + 10;
			var item:BatchItem;

			var items:Vector. = getItems(); // items pool
			var n:int = count; // active items count

			for (var i:int = 0; i < n; ++i)  			{ 				item = items[i]; 				item.y += item.scale * 2; 				item.tag = (item.tag + 1) % steps; 				item.alpha = anim[item.tag]; 				item.angle += item.scale / 5; 				if (item.y > sh) item.y = -10;

				// WARNING when using removeChild:
				// - you can call removeChild/removeChildAt(i), the array isn't modified,
				// - however the item at index 'i' will be swapped by the item previsouly at index 'count-1'
				//   and count will be decreased by one as there is one item less to render,
				//   and finally this means you have to decrement i to re-process the item at index 'i'
			}
		}

	}

}
Misc . URL.