Beautifl - Flash Gallery

Thumbnail : 円
enok 2009-08-27 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

//http://linktale.net/

package {

  import flash.display.Sprite; 

  [SWF(backgroundColor="0xffffff", frameRate="24")] 

  public class FlashTest extends Sprite { 
      public function FlashTest() { 
         var _trick:Sprite = new Kyu( this, stage.stageWidth / 2, stage.stageHeight / 2, -10, 3, 0x333333, 1, 3.0);
         addChild( _trick );
     } 

  } 

}

import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;

class Kyu extends Sprite {
    //parent stage
    private var _w:int;
    private var _h:int;
    private var _center_x:Number;
    private var _center_y:Number;
    //main
    private var _nami_color:uint //波の色
    private var _cell_w:int = 1; //波の横幅
    private var _cell_h:int = 1; //波の縦幅
    private var _cell_amout:int; //セルの横幅
    private var _cell_cnt:int; //セルの数
    private var _cell_list:Array = new Array(); //波セルのリスト 
    private var _mouse_area:Number = 20.0;
    //nami
    private var _period:Number = 2.0; //周期T
    private var _a_min:Number = 0.0; //振幅の最小値(まるめ)
    private var _f:Number = 3.0; //振幅数
    private var _t:int = 1; //波時間
    private var _nami_spring:Number = 0.01; //ばね
    private var _nami_friction:Number = 0.8; //跳ね
    private var _up_rate:Number;
    //kyu
    private var _kyu_radius:int = 150; //球の半径
    private var _kyu_line:int //球の長さ
    private var _kyu_def_posi:Array = new Array(); //球のデフォルトポジション
    //nami patter
    private var _motion_y:Number = 0.0;
    private var _motion_vy:Number = 0.0;
    //count
    private var _enter_nami_cnt:int = 0; //Nami EnterFrame回数
    private var _motion_cnt:int = 0; //自動波用カウント
    //mouse
    private var _mousex_now:Number;
    private var _mousey_now:Number;
    private var _mousex_pre:Number;
    private var _mousey_pre:Number;
    
    //const
    private const DEBUG:Boolean = true; //デバッグモード
    private const AROUND_NAMI_A:Number = 0.2;
    private const AROUND_NAMI_POSI:Number = 0.3;
    
    public function Kyu( p_s:DisplayObjectContainer, p_x:int, p_y:int, p_w:int, p_h:int, p_color:uint, p_amount:int, p_up_rate:Number ) {
        //WORLD系
        _w = p_s.stage.stageWidth; _h = p_s.stage.stageHeight; 
        _center_x = p_x; _center_y = p_y;
        //波系
        _nami_color = p_color; 
        _cell_w = p_w;
        _cell_h = p_h; 
        _cell_amout = p_amount;
        _up_rate = p_up_rate;
        //球系
        _kyu_line = 2 * Math.PI * _kyu_radius; 
        //セル系
        _cell_cnt = _kyu_line / _cell_amout;
        //マウス系
        _mousex_now = _center_x;
        _mousey_now = _center_y;
        _mousex_pre = _center_x;
        _mousey_pre = _center_y;
        
        init();
    }
    
    private function init():void {
        setCell();
        addEventListener( Event.ENTER_FRAME, onEnterFrameNami );
    }
    
    //セルをセット
    private function setCell():void {
        var i:uint;
        var cell:Cell;
        var x:Number, y:Number, dx:Number, dy:Number, angle:Number, rotation:Number;
        
        //セルの配置
        for (i = 0; i < _cell_cnt; i++ ) {                
            //セルのデフォルト位置を定義
            /*var red:uint = 255 / _cell_cnt * i;
            var color:uint = i << 16 | 0 << 8 | 0;*/
            cell = new Cell( _cell_w, _cell_h, _nami_color );
            //セルのバーチャル位置セット
            cell._x = i * _cell_amout;
            cell._y = _center_y;
            
            //球のデフォルト位状態をセット
            angle = Math.PI * 2 / _cell_cnt * i - Math.PI / 2;
            x = _kyu_radius * Math.cos(angle) + _center_x;
            y = _kyu_radius * Math.sin(angle) + _center_y;
            dx = x - _center_x;
            dy = y - _center_y;
            angle = Math.atan2(dy, dx);
            rotation = ( angle - Math.PI / 2 ) * 180 / Math.PI;
            _kyu_def_posi.push(new Array(x-cell._x, y-cell._y, x, y, rotation));
            //_kyu_def_posi.push(new Array(0, 0, cell._x, cell._y, 0));
            
            //セル配置
            addChild(cell);
            _cell_list.push(cell);
            
            //if (DEBUG) cell.x = x; cell.y = y; cell.rotation = rotation; //デバッグ表示
        }
    }
    
    private function onEnterFrameNami(e:Event):void {
        mouseSet();
        namiMove(); //描画
        _enter_nami_cnt++;
    }
    
    private function mouseSet():void {
        _mousex_pre = _mousex_now;
        _mousey_pre = _mousey_now;
        
        _mousex_now = mouseX;
        _mousey_now = mouseY;
    }
    
    //波を動かす処理
    private function namiMove():void {
        var i:uint, x:Number, y:Number, dx:Number, dy:Number, dist:Number ,angle:Number;
        
        for (i = 0; i < _cell_cnt; i++ ) {
            //○目がうまくいっていない
            dx = _cell_list[i].x - _kyu_def_posi[i][2];
            dy = _cell_list[i].y - _kyu_def_posi[i][3];
            dist = Math.sqrt( dx * dx + dy * dy );
                
            if ( Math.abs(_cell_list[i]._a) <= AROUND_NAMI_A && dist <= AROUND_NAMI_POSI) {
                //丸め処理
                _cell_list[i].x = _kyu_def_posi[i][2];
                _cell_list[i].y = _kyu_def_posi[i][3];
                _cell_list[i]._a = 0;
            }else {
                //定常波の方程式
                y = _cell_list[i]._a * Math.sin( _t / _period - i * _cell_amout / _f );
                
                angle = _kyu_def_posi[i][4] * Math.PI / 180 - Math.PI / 2;
                x = Math.cos(angle) * y;
                y = Math.sin(angle) * y;
                
                y += _center_y;
                _cell_list[i]._v_x = _cell_list[i]._x + x;
                _cell_list[i]._v_y = y; //描画
                
                //加速度をばねる
                springA(_cell_list[i]); //振幅を変化

                //一時変換
                var flg:int = 1;
                if (flg == 1) {
                    //ここに処理を追加 CPU減
                    _cell_list[i].x = _cell_list[i]._v_x + _kyu_def_posi[i][0];
                    _cell_list[i].y = _cell_list[i]._v_y + _kyu_def_posi[i][1];
                    _cell_list[i].rotation = _kyu_def_posi[i][4];
                }else if(flg==2){
                    _cell_list[i].x = _cell_list[i]._x;
                    _cell_list[i].y = _cell_list[i]._y;
                }
            }
                            
            //マウスチェック
            //addMouseValue(_cell_list[i]);
            checkWave( i, mouseX, mouseY, _up_rate );
        }
        _t++; //波時間を進める
    }
    
    //波の振幅をばねで計算
    private function springA( p_cell:Cell ):void {
        var dx:Number, ax:Number;
        
        dx = _a_min - p_cell._a;
        ax = dx * _nami_spring;
        p_cell._vx += ax;
        p_cell._vx *= _nami_friction;
        p_cell._a += p_cell._vx;
    }
    
    private function addMouseValue( p_cell:Cell ):void{
        var dx:Number, dy:Number, dist:Number, max:Number, per:Number;
        
        max = _w;
        dx = p_cell.x - _mousex_now;
        dy = p_cell.y - _mousey_now;
        dist = Math.sqrt( dx * dx + dy * dy );
        per = ( max - dist ) / max;
        
        p_cell._a += (_mousex_now - _mousex_pre) * per * 0.1;
    }
    
    //マウスチェック
    private function checkWave(p_i:int, p_target_x:Number, p_target_y:Number, nami_rate:Number ):void {
        var dx:Number = _cell_list[p_i].x - p_target_x;
        var dy:Number = _cell_list[p_i].y - p_target_y;
        var dist:Number = Math.sqrt( dx * dx + dy * dy );
        
        if (dist < _mouse_area) {
            addWave(p_i, nami_rate);
        }
    }
    
    //波追加
    private function addWave(target:int,up_rate:Number):void {
        wavePattern1(target,up_rate);
    }

    //波パターン
    private function wavePattern1(p_i:int, up_rate:Number):void {
        var i:uint, y:Number;
        var start_i:int = p_i - 100; if (start_i < 0) { start_i = 0; }
        var end_i:int =  p_i + 100; if (end_i > _cell_cnt) { end_i = _cell_cnt; }
        var dist:Number;
        
        for (i = start_i; i < end_i; i++) {
            dist = Math.abs((p_i - i)); if (dist == 0) { dist = 1.0; }
            y = 1 / dist * up_rate;
            _cell_list[i]._a += y;
        }
    }
    
}

import flash.display.Sprite;

class Cell extends Sprite {
    public var _x:Number = 0;
    public var _y:Number = 0;
    public var _v_x:Number = 0;
    public var _v_y:Number = 0;
    public var _w:int = 0;
    public var _h:int = 0;
    public var _rotaion:Number = 0;
    public var _color:int = 0;
    public var _a:Number = 0.0; //振幅
    public var _vx:Number = 0.0; //速度
    
    public function Cell( p_w:Number = 1, p_h:Number = 1, p_color:uint = 0xffffff ) {
        _w = p_w;
        _h = p_h;
        _color = p_color;
        
        graphics.beginFill(_color); 
        graphics.drawRect(-_w/2, 0, _w, _h);  
    }        
}