Forked from: Aquioux's Hopalong diff:63 Simpley Martin Attractor Aquioux forked:3favorite:11lines:251license : MIT License modified : 2012-01-12 20:39:20 Embed Tweet // forked from Aquioux's Hopalong package { import caurina.transitions.Tweener; import flash.display.Sprite; import flash.events.Event; [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#000000")] /** * Simpley Martin Attractor * @author YOSHIDA, Akio(Aquioux) * @see http://aquioux.net/blog/?p=2174 */ public class Main extends Sprite { private var viewer_:Viewer; // ビューア private var buttons_:Buttons; // ボタン private var sliders_:Sliders; // スライダー public function Main():void { setup(); addEventListener(Event.ENTER_FRAME, update); } // セットアップ private function setup():void { // ステージサイズ var w:int = stage.stageWidth; var h:int = stage.stageHeight; // エンジンの初期化 Engine.setup(); // ビューアの作成 viewer_ = new Viewer(w, h); addChild(viewer_); // ボタンの作成 buttons_ = new Buttons(); buttons_.action = drawByButton; buttons_.y = h - buttons_.height; addChild(buttons_); // スライダーの作成 sliders_ = new Sliders(); sliders_.action = drawBySlider; sliders_.reset(); addChild(sliders_); } // アップデート private function update(e:Event):void { //Engine.update(); viewer_.update(Engine.data); } // ボタンに起因する描画の実行 // エンジンの変数の値をトゥイーン private function drawByButton(values:Vector.<Number>):void { Tweener.addTween(Engine, { "a":values[0], time:1.5, transition:"easeOutCubic", onStart:viewer_.reset, onUpdate:sliders_.reset }); } // スライダーに起因する描画の実行 private function drawBySlider():void { buttons_.reset(); } } } //package { /** * Hopalong エンジン * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class Engine { /** * 計算に使用するパラメータ a */ static public function get a():Number { return _a; } static public function set a(value:Number):void { _a = value; update(); // 再計算 } static private var _a:Number; /** * 計算に使用する各パラメータの最小値、最大値、既定値 */ static public function get A_MIN():Number { return PARAMS[0]; } static public function get A_MAX():Number { return PARAMS[1]; } static public function get A_DEFAULT():Number { return PARAMS[2]; } static private const PARAMS:Vector.<Number> = Vector.<Number>([ 176 * Math.PI / 180, 184 * Math.PI / 180, Math.PI // a ]); /** * 座標データ Vector */ static public function get data():Vector.<Number> { return _data; } static private var _data:Vector.<Number>; /** * パーティクル数 */ static public function get numOfParticle():int { return numOfParticle_; } static private var numOfParticle_:int = 50000; // スケール static private const SCALE:Number = 2; /** * セットアップ */ static public function setup():void { _data = new Vector.<Number>(numOfParticle_ * 2, true); paramRandom(); } /** * 計算 * @return 結果の座標を一次元配列で格納した Vector */ static public function update():void { var x:Number = 0; var y:Number = 0; var len:int = numOfParticle_ * 2; for (var i:int = 0; i < len; i += 2) { var xn:Number = y - Math.sin(x); var yn:Number = _a - x; x = xn; y = yn; _data[i] = x * SCALE; _data[i + 1] = y * SCALE; } } /** * パラメータを既定値に戻す */ static public function paramDefault():void { _a = A_DEFAULT; update(); // 再計算 } /** * パラメータをランダムな値にする */ static public function paramRandom():void { _a = Math.random() * (A_MAX - A_MIN) + A_MIN; update(); // 再計算 } } //} //package { //import aquioux.display.colorUtil.CycleRGB; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.filters.BitmapFilterQuality; import flash.filters.BlurFilter; import flash.geom.ColorTransform; import flash.geom.Point; import flash.geom.Rectangle; /** * ビューア * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class Viewer extends Sprite { /** * ColorTransform によるフェードアウトのための定義 */ public function set fade(value:ColorTransform):void { _fade = value; } private var _fade:ColorTransform = new ColorTransform(0.95, 0.95, 0.95); /** * Blur filter によるフェードアウトのための定義 */ public function set blur(value:BlurFilter):void { _blur = value; } private var _blur:BlurFilter = new BlurFilter(8, 8, BitmapFilterQuality.HIGH); // 描画色用の変数 private var start_:Number; // 開始位置 private var add_:Number; // start_ への増分 private var renge_:Number; // 循環色相の範囲(角度) // BitmapData 関連 private var bmd_:BitmapData; // 表示 BitmapData private var bufferBmd_:BitmapData; // バッファ private var rect_:Rectangle; // ColorTransform, Blur 共用 private const ZERO_POINT:Point = new Point(0, 0); // 表示オフセット private var sw_:int; // ステージ幅 private var sh_:int; // ステージ高 private var offsetX_:Number; // X座標オフセット private var offsetY_:Number; // Y座標オフセット /** * コンストラクタ * @param sw ステージ幅 * @param sh ステージ高 */ public function Viewer(sw:int, sh:int) { // ステージサイズ sw_ = sw; sh_ = sh; // BitmapData 関連 bufferBmd_ = new BitmapData(sw, sh, true, 0xFF000000); bmd_ = bufferBmd_.clone(); rect_ = new Rectangle(0, 0, sw, sh); addChild(new Bitmap(bmd_)); // 各オフセット offsetX_ = sw / 2; offsetY_ = sh / 2; // 描画色関連 CycleRGB.alpha = 0xCC; start_ = Math.random() * 360 >> 0; reset(); } /** * アップデート * @param data 描画座標データ */ public function update(data:Vector.<Number>):void { // bufferBmd_ の更新 bufferBmd_.lock(); bufferBmd_.fillRect(bufferBmd_.rect, 0x00000000); var len:uint = data.length; start_ += add_; for (var i:int = 0; i < len; i += 2) { var px:Number = (data[i] + offsetX_) >> 0; var py:Number = (data[i + 1] + offsetY_) >> 0; bufferBmd_.setPixel32(px, py, CycleRGB.getColor32(i / 500 + start_)); } bufferBmd_.unlock(); // bmd_ の更新 bmd_.lock(); bmd_.colorTransform(rect_, _fade); bmd_.applyFilter(bmd_, rect_, ZERO_POINT, _blur); bmd_.draw(bufferBmd_); bmd_.unlock(); } /** * 描画色用変数の再設定 */ public function reset():void { add_ = ((Math.random() * 50 >> 0) + 50) / 100; } } //} //package { import com.bit101.components.PushButton; import flash.display.Sprite; import flash.events.Event; import flash.utils.Dictionary; /** * コントロール用ボタン * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class Buttons extends Sprite { /** * ボタンアクション(外部で定義した処理) */ public function set action(value:Function):void { _action = value; } private var _action:Function; // エンジンのラベルとプロパティ値のペア private const PAIR:Array = [ ["Min", Vector.<Number>([Engine.A_MIN])], ["Max", Vector.<Number>([Engine.A_MAX])] ]; // ボタンの数 private const NUM_OF_BUTTON_ROW:int = 9; // 1行 private const NUM_OF_BUTTON_LASTROW:int = PAIR.length % NUM_OF_BUTTON_ROW; // 最後の行 private const NUM_OF_BUTTON_COL:int = PAIR.length / NUM_OF_BUTTON_ROW >> 0; // 列数 // 前回押したボタン private var prevButton_:PushButton; // _action への引数を格納する Dictionary private var values:Dictionary; /** * インストラクタ */ public function Buttons() { // ボタンの作成 var buttonWidth:int = 52; var buttonHeight:int = 20; var idx:int = 0; var yLimit:int = (NUM_OF_BUTTON_LASTROW == 0) ? NUM_OF_BUTTON_COL : NUM_OF_BUTTON_COL + 1; var xLimit:int = NUM_OF_BUTTON_ROW; values = new Dictionary(); for (var y:int = 0; y < yLimit; y++) { if ((NUM_OF_BUTTON_LASTROW != 0) && (y == NUM_OF_BUTTON_COL)) xLimit = NUM_OF_BUTTON_LASTROW; for (var x:int = 0; x < xLimit; x++) { var b:PushButton = new PushButton(this, buttonWidth * x, buttonHeight * y, PAIR[idx][0], handler); b.width = buttonWidth; b.height = buttonHeight; values[b] = PAIR[idx][1]; idx++; } } } /** * リセット(前回押されたボタンを有効にする) */ public function reset():void { if (prevButton_) prevButton_.enabled = true; } // ボタンハンドラ private function handler(e:Event):void { // 前回押されたボタンを有効にする reset(); // 今回押されたボタンを無効にする var target:PushButton = PushButton(e.target); target.enabled = false; prevButton_ = target; // ボタンアクション _action(values[target]); } } //} //package { import com.bit101.components.HUISlider; import com.bit101.components.Slider; import flash.display.Sprite; import flash.events.Event; import flash.utils.Dictionary; /** * コントロール用スライダー * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class Sliders extends Sprite { /** * スライダーアクション(外部で定義した処理) */ public function set action(value:Function):void { _action = value; } private var _action:Function; // スライダーの値を小数第何位まで有効にするか private const PRECISION:int = 3; private const TICK:Number = Math.pow(10, -PRECISION); // スライダーに対応させるエンジンのプロパティ private const PROPS:Array = ["a"]; private const DELIMITER:String = ":"; // スライダー格納配列 private var sliders:Dictionary; /** * コンストラクタ */ public function Sliders() { var params:Vector.<Number> = Vector.<Number>([ Engine.A_MIN, Engine.A_MAX, Engine.a ]); var sliderWidth:int = 430; var sliderHeight:int = 15; sliders = new Dictionary(); for (var i:int = 0; i < PROPS.length; i++) { var prop:String = PROPS[i]; var slider:HUISlider = new HUISlider(this, 25, i * sliderHeight, prop + DELIMITER, handler); slider.width = sliderWidth; slider.labelPrecision = PRECISION; slider.tick = TICK; slider.setSliderParams(params[i * 3], params[i * 3 + 1], params[i * 3 + 2]); sliders[prop] = slider; } } /** * リセット(Engine 内の数値に伴ったスライダー値にリセット) */ public function reset():void { for each (var prop:String in PROPS) sliders[prop].value = Engine[prop]; } // スライダーハンドラ private function handler(e:Event):void { var target:HUISlider = HUISlider(e.target); var prop:String = target.label.split(DELIMITER)[0]; Engine[prop] = target.value; _action(); } } //} //package aquioux.display.colorUtil { /** * コサインカーブで色相環的な RGB を計算 * @author Aquioux(YOSHIDA, Akio) */ /*public*/ class CycleRGB { /** * 32bit カラーのためのアルファ値(0~255) */ static public function get alpha():uint { return _alpha; } static public function set alpha(value:uint):void { _alpha = (value > 0xFF) ? 0xFF : value; } private static var _alpha:uint = 0xFF; private static const PI:Number = Math.PI; // 円周率 private static const DEGREE120:Number = PI * 2 / 3; // 120度(弧度法形式) /** * 角度に応じた RGB を得る * @param angle HSV のように角度(度数法)を指定 * @return 色(0xNNNNNN) */ public static function getColor(angle:Number):uint { var radian:Number = angle * PI / 180; var r:uint = (Math.cos(radian) + 1) * 0xFF >> 1; var g:uint = (Math.cos(radian + DEGREE120) + 1) * 0xFF >> 1; var b:uint = (Math.cos(radian - DEGREE120) + 1) * 0xFF >> 1; return r << 16 | g << 8 | b; } /** * 角度に応じた RGB を得る(32bit カラー) * @param angle HSV のように角度(度数法)を指定 * @return 色(0xNNNNNNNN) */ public static function getColor32(angle:Number):uint { return _alpha << 24 | getColor(angle); } } //} Code Fullscreen Preview Fullscreen smallwind191.. skn alexxcz BeloitAve fallen Mingchoi atakanckilic.. ProjectNya gaina korooooon : 光 hidrodixtion.. : awesomefractalmath awesome fractal map math カオス 光 Dictionary target BlurFilter clone addChild split Math.cos Rectangle alpha Vector Tweener.addTween Event width length height Math.pow Math.PI time addEventListener String sort new page view favorite forked pv239 Swastika generator Ludd forked:0 favorite:0lines:251 (diff:1) pv184 forked from: Simpley Martin At.. kojishirai forked:0 favorite:0lines:251 (diff:1) pv179 forked from: Simpley Martin At.. raiongaoo forked:0 favorite:0lines:251 (diff:1)