package { import flash.display.Bitmap; import flash.display.Sprite; import flash.display.Shader; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.geom.Point; import flash.geom.Rectangle; import flash.utils.ByteArray; import flash.display.BitmapData; /** * ... * @author Ian Reichert-Watts * blog.shadowhelm.com * www.shadowhelm.com */ public class Cell1DAS3 extends Sprite { private var _rule:Vector. = new Vector.; private var _buffer:Vector. = new Vector.; private var _fullBuffer:Vector. = new Vector.; private var _canvas:BitmapData; private var _canvasBMP:Bitmap; private var _edge:int; private var _state1:Sprite = new Sprite(); private var _state2:Sprite = new Sprite(); private var _state3:Sprite = new Sprite(); private var _state4:Sprite = new Sprite(); private var _state5:Sprite = new Sprite(); private var _state6:Sprite = new Sprite(); private var _state7:Sprite = new Sprite(); private var _state8:Sprite = new Sprite(); private var _states:Sprite = new Sprite(); private var _iteration:int; public function Cell1DAS3() { stage.scaleMode = "noScale"; stage.align = "TL"; //prepare canvas to draw results on _canvas = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xFFFFFF); _canvasBMP = new Bitmap(_canvas); addChild(_canvasBMP); _edge = stage.stageWidth-1; reset(); //draw and position rule state blocks for rule 89 //drawState(state:Sprite, index:int, fill:int); drawState(_state1, 1, 1); drawState(_state2, 2, 0); drawState(_state3, 3, 1); drawState(_state4, 4, 0); drawState(_state5, 5, 0); drawState(_state6, 6, 1); drawState(_state7, 7, 1); drawState(_state8, 8, 0); _states.addChild(_state1); _states.addChild(_state2); _states.addChild(_state3); _states.addChild(_state4); _states.addChild(_state5); _states.addChild(_state6); _states.addChild(_state7); _states.addChild(_state8); addChild(_states); _states.graphics.beginFill(0xFFFFFF); _states.graphics.drawRect( -2, -2, 314, 22); _state1.x = 0; _state2.x = 40; _state3.x = 80; _state4.x = 120; _state5.x = 160; _state6.x = 200; _state7.x = 240; _state8.x = 280; _states.y = stage.stageHeight - 20; _states.x = stage.stageWidth / 2 - _states.width / 2; _state1.buttonMode = true; _state2.buttonMode = true; _state3.buttonMode = true; _state4.buttonMode = true; _state5.buttonMode = true; _state6.buttonMode = true; _state7.buttonMode = true; _state8.buttonMode = true; //set shader to rule 89 _rule.push(false); _rule.push(true); _rule.push(false); _rule.push(true); _rule.push(true); _rule.push(false); _rule.push(false); _rule.push(true); render(); stage.addEventListener(MouseEvent.CLICK, onClick, false, 0, true); } private function drawState(state:Sprite, index:int, fill:int):void { state.graphics.lineStyle(1, 0); switch(index) { case 1: state.graphics.beginFill(0); break; case 2: state.graphics.beginFill(0); break; case 3: state.graphics.beginFill(0); break; case 4: state.graphics.beginFill(0); break; case 5: state.graphics.beginFill(0xFFFFFF); break; case 6: state.graphics.beginFill(0xFFFFFF); break; case 7: state.graphics.beginFill(0xFFFFFF); break; case 8: state.graphics.beginFill(0xFFFFFF); break; } state.graphics.drawRect(0, 0, 10, 10); switch(index) { case 1: state.graphics.beginFill(0); break; case 2: state.graphics.beginFill(0); break; case 3: state.graphics.beginFill(0xFFFFFF); break; case 4: state.graphics.beginFill(0xFFFFFF); break; case 5: state.graphics.beginFill(0); break; case 6: state.graphics.beginFill(0); break; case 7: state.graphics.beginFill(0xFFFFFF); break; case 8: state.graphics.beginFill(0xFFFFFF); break; } state.graphics.drawRect(10, 0, 10, 10); switch(index) { case 1: state.graphics.beginFill(0); break; case 2: state.graphics.beginFill(0xFFFFFF); break; case 3: state.graphics.beginFill(0); break; case 4: state.graphics.beginFill(0xFFFFFF); break; case 5: state.graphics.beginFill(0); break; case 6: state.graphics.beginFill(0xFFFFFF); break; case 7: state.graphics.beginFill(0); break; case 8: state.graphics.beginFill(0xFFFFFF); break; } state.graphics.drawRect(20, 0, 10, 10); state.graphics.beginFill(0xFFFFFF*fill); state.graphics.drawRect(10, 10, 10, 10); } private function onClick(e:MouseEvent):void { //toggle rule states switch(e.target) { case _state1: if (_rule[0] == false) { _rule[0] = true; _state1.graphics.beginFill(0); _state1.graphics.drawRect(10, 10, 10, 10); }else { _rule[0] = false; _state1.graphics.beginFill(0xFFFFFF); _state1.graphics.drawRect(10, 10, 10, 10); } break; case _state2: if (_rule[1] == false) { _rule[1] = true; _state2.graphics.beginFill(0); _state2.graphics.drawRect(10, 10, 10, 10); }else { _rule[1] = false; _state2.graphics.beginFill(0xFFFFFF); _state2.graphics.drawRect(10, 10, 10, 10); } break; case _state3: if (_rule[2] == false) { _rule[2] = true; _state3.graphics.beginFill(0); _state3.graphics.drawRect(10, 10, 10, 10); }else { _rule[2] = false; _state3.graphics.beginFill(0xFFFFFF); _state3.graphics.drawRect(10, 10, 10, 10); } break; case _state4: if (_rule[3] == false) { _rule[3] = true; _state4.graphics.beginFill(0); _state4.graphics.drawRect(10, 10, 10, 10); }else { _rule[3] = false; _state4.graphics.beginFill(0xFFFFFF); _state4.graphics.drawRect(10, 10, 10, 10); } break; case _state5: if (_rule[4] == false) { _rule[4] = true; _state5.graphics.beginFill(0); _state5.graphics.drawRect(10, 10, 10, 10); }else { _rule[4] = false; _state5.graphics.beginFill(0xFFFFFF); _state5.graphics.drawRect(10, 10, 10, 10); } break; case _state6: if (_rule[5] == false) { _rule[5] = true; _state6.graphics.beginFill(0); _state6.graphics.drawRect(10, 10, 10, 10); }else { _rule[5] = false; _state6.graphics.beginFill(0xFFFFFF); _state6.graphics.drawRect(10, 10, 10, 10); } break; case _state7: if (_rule[6] == false) { _rule[6] = true; _state7.graphics.beginFill(0); _state7.graphics.drawRect(10, 10, 10, 10); }else { _rule[6] = false; _state7.graphics.beginFill(0xFFFFFF); _state7.graphics.drawRect(10, 10, 10, 10); } break; case _state8: if (_rule[7] == false) { _rule[7] = true; _state8.graphics.beginFill(0); _state8.graphics.drawRect(10, 10, 10, 10); }else { _rule[7] = false; _state8.graphics.beginFill(0xFFFFFF); _state8.graphics.drawRect(10, 10, 10, 10); } break; } reset(); render(); } private function reset():void { //clear canvas _canvas.fillRect(_canvas.rect, 0xFFFFFF); //reset buffer _fullBuffer = new Vector.; for (var i:int = 0; i < stage.stageWidth; i++) { _buffer[i] = false; _fullBuffer[i] = 0xFFFFFF; } //seed starting point _buffer[int(stage.stageWidth / 2 + 1)] = true; _fullBuffer[int(stage.stageWidth / 2 + 1)] = 0x000000; _canvas.setPixel(int(stage.stageWidth / 2 + 1), 0, 0x000000); //set iterations; _iteration = stage.stageHeight; } private function solve(l:Boolean, m:Boolean, r:Boolean):Boolean { //compare buffer to rules if (l == true && m == true && r == true) { return _rule[0]; } if (l == true && m == true && r == false) { return _rule[1]; } if (l == true && m == false && r == true) { return _rule[2]; } if (l == true && m == false && r == false) { return _rule[3]; } if (l == false && m == true && r == true) { return _rule[4]; } if (l == false && m == true && r == false) { return _rule[5]; } if (l == false && m == false && r == true) { return _rule[6]; } if (l == false && m == false && r == false) { return _rule[7]; } return false; } private function render():void { //start render var i:int = 0; while (i++ < _iteration) { //solve buffer //left edge if(solve(_buffer[_edge], _buffer[0], _buffer[1]) == true){ _fullBuffer.push(0x000000); }else _fullBuffer.push(0xFFFFFF); //mid for (var x:int = 1; x < _edge; x++){ if(solve(_buffer[x - 1], _buffer[x], _buffer[x + 1]) == true){ _fullBuffer.push(0x000000); }else _fullBuffer.push(0xFFFFFF); } //right edge if(solve(_buffer[_edge-1], _buffer[_edge], _buffer[0]) == true){ _fullBuffer.push(0x000000); }else _fullBuffer.push(0xFFFFFF); //rasterize buffer for (var k:int = 0; k < stage.stageWidth; k++) { //grab solved buffer _buffer[k] = _fullBuffer[_fullBuffer.length - stage.stageWidth + k] == 0x000000 ? true : false; //draw buffer to canvas _canvas.lock(); _canvas.setPixel(k,i, _buffer[k] ? 0x000000 : 0xFFFFFF); //_canvas.setVector(_canvas.rect, _fullBuffer); _canvas.unlock(_canvas.rect); } } } } }