package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.BlurFilter; import flash.filters.ColorMatrixFilter; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.ui.Keyboard; import flash.events.KeyboardEvent; import flash.display.BlendMode; // Phlashers 2010 AS3 Contest // http://www.phlashers.com // Instructions: Any key to play/stop. Mouse Click to toggle cells public class Main extends Sprite { //the world private var space:Array; //the world buffer private var flipSpace:Array; //double buffering helpers private var buffer:BitmapData; private var _bmpF:Bitmap; private var _bmpB:Bitmap; private var _flipped:Boolean; private var p1:BitmapData; //post processing helper private var fx:BitmapData; private var fxPos:Point; //game state private var pressed:Boolean = false; private var running:Boolean = false; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); buffer = new BitmapData(640, 480); _bmpF = new Bitmap(buffer); _bmpB = new Bitmap(buffer.clone()); p1 = new BitmapData(15, 15, false, 0xffff0000); fx = new BitmapData(300, 300, false, 0xff0000); fxPos = new Point(0, 0); //is there an easier way to make 2d arrays in as3? space = new Array(); flipSpace = new Array(); for (var i:int = 0; i < 20; i++ ) { space[i] = new Array(); flipSpace[i] = new Array(); for (var c:int = 0; c < 20; c++ ) { space[i][c] = (i==8 && c > 3 && c < 14); flipSpace[i][c] = false; } } addChild(_bmpF); addChild(_bmpB); addEventListener(Event.ENTER_FRAME, enterFrame); stage.addEventListener(MouseEvent.MOUSE_DOWN, function():void { pressed = true; } ); stage.addEventListener(MouseEvent.MOUSE_UP, function():void { pressed = false; } ); stage.addEventListener(KeyboardEvent.KEY_UP, function():void { running = !running; } ); } private function enterFrame(evt:Event):void { //Clear video buffer buffer = _flipped ? _bmpF.bitmapData : _bmpB.bitmapData; updateInput(); render(); if(running) postProcess(); //Swap video buffers _bmpB.visible = !(_bmpF.visible = _flipped); _flipped = !_flipped; } private function updateInput():void { var x:int = 0; var y:int = 0; var i:int = 0; var c:int = 0; //input check if (pressed) { x = mouseX / 25; y = mouseY / 25; flipSpace[x][y] = true; } if(running){ for (i = 0; i < 20; i++ ) for (c = 0; c < 20; c++ ) { x = 0; //Stupid boundary checks.. if (c - 1 > 0 && space[i][c - 1]) x++; if(c - 1 > 0 && i - 1 > 0 && space[i-1][c-1]) x++; if (c - 1 > 0 && i + 1 < 20 && space[i + 1][c - 1]) x++; if (i - 1 > 0 && space[i - 1][c]) x++; if (i + 1 < 20 && space[i + 1][c]) x++; if (c + 1 < 20 && space[i][c + 1]) x++; if (c + 1 < 20 && i - 1 > 0 && space[i-1][c+1]) x++; if (c + 1 < 20 && i + 1 < 20 && space[i + 1][c + 1]) x++; //Apply Game of Life rules (check wikipedia just to be sure!): flipSpace[i][c] = space[i][c] ? (x < 2) || (x > 3) : (x == 3); } } //start flippin bits! for (i = 0; i < 20; i++ ) for (c = 0; c < 20; c++ ) { if (flipSpace[i][c]) { flipSpace[i][c] = false; space[i][c] = !space[i][c]; } } } private function render():void { if(!running) buffer.fillRect(buffer.rect, 0xffffffff); for (var i:int = 0; i < 20; i++ ) { for (var c:int = 0; c < 20; c++ ) { if(space[i][c]){ buffer.copyPixels(p1, p1.rect, new Point(i*25+5, c*25+5), null, null, true); } } } } //subpar nextgen fx, i was aiming for the bloom filter private function postProcess():void { var w:uint = buffer.width * 0.8; var h:uint = buffer.height * 0.8; var matrix:Matrix = new Matrix(); fxPos.x = Math.random() * 1 - .5; fxPos.y = Math.random() * 1 - 0.5; matrix.identity(); matrix.scale( .25, .25); matrix.translate(fxPos.x, fxPos.y); var downSampled:BitmapData = new BitmapData(w,h,true,0xffffff); downSampled.draw(buffer,matrix); matrix.invert(); buffer.draw( downSampled, matrix, null, BlendMode.SCREEN, null, true); } } } 5k GoL