In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: 重力マウス(重力子パーティクル追加してみた)

Status() 追加
fillRect から setPixel へ
三角関数除外(sin, cos, atn2), 平方根除外(sqrt) ・・・ X, Y の差分情報が有るので必要な処理は関数なで対応可能
BitmapData をロックする。
for ループを for each ループに変更 ・・・ パフォーマンスにはあまり影響は無さそう
パーティクルを2万個に変更
計算域を画面境界+100ピクセルに変更してパーティクルが画面の端から端に移動する空間を広げた。(画面の端からはみ出たパーティクルの回帰を遅らせたてみた)
重力子パーティクルを追加・・・相互に影響しあう。
画面をクリックするとマウスの重力を on / off 切り替え(起動時は off )
Get Adobe Flash player
by munku.jp 29 Jan 2011
/**
 * Copyright munku.jp ( http://wonderfl.net/user/munku.jp )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sGWU
 */

// forked from undo's 重力マウス
// Status() 追加
// fillRect から setPixel へ
// 三角関数除外(sin, cos, atn2), 平方根除外(sqrt) ・・・ X, Y の差分情報が有るので必要な処理は関数なで対応可能
// BitmapData をロックする。
// for ループを for each ループに変更 ・・・ パフォーマンスにはあまり影響は無さそう
// パーティクルを2万個に変更
// 計算域を画面境界+100ピクセルに変更してパーティクルが画面の端から端に移動する空間を広げた。(画面の端からはみ出たパーティクルの回帰を遅らせたてみた)
// 重力子パーティクルを追加・・・相互に影響しあう。
// 画面をリックするとマウスの重力を on / off 切り替え(起動時は off )
// (任意の場所でマウスクリックイベントが拾えなかったがその後 stage プロパティからイベント設定することで可能になる事を知った)
package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import net.hires.debug.Stats;
    import flash.events.MouseEvent;

    [SWF(frameRate='60', width='465', height='465', backgroundColor='0x0')]

    public class ParticleTest1 extends Sprite
    {
        private var _bmp:Bitmap;
        private var _bmd:BitmapData;
        private var _bmdRect:Rectangle;
        private var _colorTransform:ColorTransform = new ColorTransform(0.5, 0.9, 0.5, 1);
        private var _redV:int = 1;
        private var _greenV:int = 1;
        private var _blueV:int = 1;

        private var _nodeArray:Array = [];
        private var _maxNum:int = 20000;

        private var _gravitonsArray:Array = [];
        private const _maxGNum:int = 3;

        private const _minBoundary:int = -100;
        private const _maxBoundary:int = 465 + 100;

        private const _gravity:Number = 10;
        private const _gravityMouse:Number = 30;

        private const _dampingRate:Number = 0.98;

        private var _grvMouse:Number = 0;

        public function ParticleTest1()
        {
            this.stage.align = StageAlign.TOP_LEFT;
            this.stage.scaleMode = StageScaleMode.NO_SCALE;

            addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(evt:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            _bmd = new BitmapData(465, 465, false, 0x000000);
            _bmp = new Bitmap(_bmd);
            addChild(_bmp);
            this._bmdRect = new Rectangle(0, 0, 465, 465);

            var i:int;
            var n:Node;

            for ( i = 0; i < this._maxNum ; i++ )
            {
                n = new Node();
                n.pX = Math.random() * 465;
                n.pY = Math.random() * 465;
                this._nodeArray.push(n);
            }

            for ( i = 0 ; i < this._maxGNum ; i++ )
            {
                n = new Node();
                n.pX = Math.random() * 465;
                n.pY = Math.random() * 465;
                this._gravitonsArray.push(n);
            }

            addChild(new Stats());

            addEventListener(Event.ENTER_FRAME, onEnter);
            stage.addEventListener(MouseEvent.CLICK, onClick);
        }

        private function onEnter(evt:Event):void
        {
            this._bmd.lock();

            MoveGravitons();

            MoveParticles();

            if( Math.random() < 0.1 )
                ModifyColor();

            this._bmd.colorTransform(this._bmdRect, this._colorTransform);
            this._bmd.unlock();
        }

        private function onClick(evt:MouseEvent):void
        {
            this._grvMouse = this._grvMouse ? 0 : _gravityMouse;
        }

        private function MoveGravitons():void
        {
            for (var i:int = 0 ; i < this._maxGNum ; i++ )
            {
                var gv1:Node = this._gravitonsArray[i] as Node;

                // 重力マウスの影響を計算
                var diffX:Number = mouseX - gv1.pX;
                var diffY:Number = mouseY - gv1.pY;

                var gravD:Number = this._grvMouse / ( diffX * diffX + diffY * diffY + 0.001 );    // 0割回避のために 0.001 を加算(パフォーマンス低下を避けるため条件回避はしない)

                gv1.vX += diffX * gravD;
                gv1.vY += diffY * gravD;

                for (var j:int = i + 1 ; j < this._maxGNum ; j++ )
                {
                    var gv2:Node = this._gravitonsArray[j] as Node;

                    diffX = gv2.pX - gv1.pX;
                    diffY = gv2.pY - gv1.pY;

                    gravD = _gravity / ( diffX * diffX + diffY * diffY + 0.001 );           // 0割回避のために 0.001 を加算(パフォーマンス低下を避けるため条件回避はしない)

                    var vx:Number = diffX * gravD;
                    var vy:Number = diffY * gravD;

                    gv1.vX += vx;
                    gv1.vY += vy;

                    gv2.vX -= vx;
                    gv2.vY -= vy;
                }

                // 重力子間の相互作用を計算後に移動
                gv1.pX += gv1.vX;
                gv1.pY += gv1.vY;
    
                gv1.vX *= _dampingRate;
                gv1.vY *= _dampingRate;
    
                if ( gv1.pX > _maxBoundary )
                    gv1.pX = _minBoundary;
                else if ( gv1.pX < _minBoundary)
                    gv1.pX = _maxBoundary;
    
                if ( gv1.pY > _maxBoundary)
                    gv1.pY = _minBoundary;
                else if ( gv1.pY < _minBoundary)
                    gv1.pY = _maxBoundary;
    
                this._bmd.fillRect( new Rectangle( gv1.pX - 2, gv1.pY - 2, 5, 5 ), 0xffffff );   // 重力子パーティクルを少し大きめに描画
            }
        }

        private function MoveParticles():void
        {
            for each( var n:Node in this._nodeArray )
            {
                // 重力マウスの影響を計算
                var diffX:Number = mouseX - n.pX;
                var diffY:Number = mouseY - n.pY;

                var gravD:Number = this._grvMouse / ( diffX * diffX + diffY * diffY + 0.001 );    // 0割回避のために 0.001 を加算(パフォーマンス低下を避けるため条件回避はしない)

                n.vX += diffX * gravD;
                n.vY += diffY * gravD;

                // 重力子の影響を計算
                for each( var gv:Node in this._gravitonsArray )
                {
                    diffX = gv.pX - n.pX;
                    diffY = gv.pY - n.pY;

                    gravD = _gravity / ( diffX * diffX + diffY * diffY + 0.001 );           // 0割回避のために 0.001 を加算(パフォーマンス低下を避けるため条件回避はしない)

                    n.vX += diffX * gravD;
                    n.vY += diffY * gravD;
                }

                n.pX += n.vX;
                n.pY += n.vY;

                n.vX *= _dampingRate;
                n.vY *= _dampingRate;

                if ( n.pX > _maxBoundary )
                    n.pX = _minBoundary;
                else if (n.pX < _minBoundary )
                    n.pX = _maxBoundary;
                if ( n.pY > _maxBoundary )
                    n.pY = _minBoundary;
                else if ( n.pY < _minBoundary )
                    n.pY = _maxBoundary;

                this._bmd.setPixel(n.pX, n.pY, 0xffff40 );
            }
        }

        private function ModifyColor():void
        {
            if( Math.random() < 0.03 )
            {
                this._redV = Math.random() * 3 - 1;
                this._greenV = Math.random() * 3 - 1;
                this._blueV = Math.random() * 3 - 1;
            }

            this._colorTransform.redMultiplier += this._redV * 0.01;
            if( this._colorTransform.redMultiplier < 0 || this._colorTransform.redMultiplier > 1.0 )
            {
                this._colorTransform.redMultiplier -= this._redV * 0.01;
                this._redV *= -1;
            }

            this._colorTransform.greenMultiplier += this._greenV * 0.01;
            if( this._colorTransform.greenMultiplier < 0 || this._colorTransform.greenMultiplier > 1.0 )
            {
                this._colorTransform.greenMultiplier -= this._greenV * 0.01;
                this._greenV *= -1;
            }

            this._colorTransform.blueMultiplier += this._blueV * 0.01;
            if( this._colorTransform.blueMultiplier < 0 || this._colorTransform.blueMultiplier > 1.0 )
            {
                this._colorTransform.blueMultiplier -= this._blueV * 0.01;
                this._blueV *= -1;
            }

        }

    }
}

class Node
{
    public var vX:Number;
    public var vY:Number;
    public var pX:Number;
    public var pY:Number;

    public function Node()
    {
        this.vX = this.vY = 0;
    }

}