/* download .pbk and read more on: http://blog.yoz.sk/2010/03/game-of-life/ */ package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Shader; import flash.display.ShaderJob; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.geom.Point; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.text.TextField; import flash.utils.ByteArray; import flash.utils.Timer; import net.hires.debug.Stats; [SWF(width="465", height="465", frameRate="60", backgroundColor="#000000")] public class PBGameOfLife extends Sprite { private static const ZERO_POINT:Point = new Point(); private static const INITIAL_POINTS:Array = [63,99,101,127,128,135,136, 149,150,164,168,173,174,187,188,191,192,201,207,211,212,229,230, 239,243,245,246,251,253,277,283,291,316,320,355,356]; private var bitmap:Bitmap = new Bitmap(); private var bitmapData:BitmapData; private var shaderLoader:URLLoader = new URLLoader(); private var shaderURL:String = "http://blog.yoz.sk/examples/gameOfLife/gameoflife.pbj"; private var shader:Shader; private var pxPerSecond:uint = 0; private var tf:TextField = new TextField(); public function PBGameOfLife() { super(); createBitmap(); addChild(bitmap); shaderLoader.dataFormat = URLLoaderDataFormat.BINARY; shaderLoader.load(new URLRequest(shaderURL)); shaderLoader.addEventListener(Event.COMPLETE, shaderComplete); var stats:Stats = new Stats(); addChild(stats); stats.x = stage.stageWidth - stats.width; var timer:Timer = new Timer(1000); timer.addEventListener(TimerEvent.TIMER, timerHandler); timer.start(); addChild(tf); tf.y = stage.stageHeight - 25; tf.width = stage.stageWidth; tf.selectable = false; tf.textColor = 0xffffff; } private function createBitmap():void { var w:uint = 38; var h:uint = 38; var X:uint, Y:uint; bitmapData = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0); bitmapData.lock(); for(var i:uint = 0; i < w*h; i++) { X = i%w; Y = int(i/w); if(INITIAL_POINTS.indexOf(i) > -1) bitmapData.setPixel32(X, Y, 0xffffffff); } bitmapData.unlock(); bitmap.bitmapData = bitmapData; } private function shaderComplete(event:Event):void { var loader:URLLoader = URLLoader(event.currentTarget); shader = new Shader(loader.data as ByteArray); shader.data.src.input = bitmapData; shader.data.width.value = [bitmapData.width]; shader.data.height.value = [bitmapData.height]; addEventListener(Event.ENTER_FRAME, enterFrame); //stage.addEventListener(MouseEvent.MOUSE_DOWN, enterFrame); } private function timerHandler(event:TimerEvent):void { tf.text = pxPerSecond.toString() + " pixels per second"; pxPerSecond = 0; } private function enterFrame(event:Event):void { pxPerSecond += bitmapData.width * bitmapData.height; new ShaderJob(shader, bitmapData, 4, 4).start(true); } } } Fastest Game Of Life with Pixel Bender