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: 紙ふぶき

------------------------------------------------------------------------
2010年4月9日
なんちゃって紙ふぶき
実はそれぞれの紙切れは, 一定の回転軸のまわりを, 一定の速さで回転しながら, 
一定の移動速度で落下しているのだけど, 移動方向がフラフラ変わとと, 
数多く同時に散らしていることで, なんとなく紙吹雪らしく見えている.
... しかし、これまた重くなった (^^;
------------------------------------------------------------------------

import flash.text.*;
Get Adobe Flash player
by tonka 02 Feb 2015
/**
 * Copyright tonka ( http://wonderfl.net/user/tonka )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ovTO
 */

// forked from tenasaku's 紙ふぶき
/*    ------------------------------------------------------------------------
    2010年4月9日
    なんちゃって紙ふぶき
    実はそれぞれの紙切れは, 一定の回転軸のまわりを, 一定の速さで回転しながら, 
    一定の移動速度で落下しているのだけど, 移動方向がフラフラ変わとと, 
    数多く同時に散らしていることで, なんとなく紙吹雪らしく見えている.
    ... しかし、これまた重くなった (^^;
    ------------------------------------------------------------------------
*/
package {

    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
//    import flash.text.*;

    public class Main extends Sprite {

        private const NUM_KAMIKIRE:int = 400;
        private var kamiFubuki:Array;
        private var frameCount:uint;

        private function drawBackGround():void {
            var mat:Matrix = new Matrix();
            mat.createGradientBox(stage.stageWidth,stage.stageHeight,Math.PI/2,0,0);
            this.graphics.clear();
            this.graphics.beginGradientFill(
                GradientType.LINEAR,
                [,0x0000ff,0x000099],[1,1],[0,200,255],
                mat,
                SpreadMethod.PAD);
            this.graphics.drawRect(0,0,stage.stageWidth, stage.stageHeight);
            this.graphics.endFill();
        }

        private function atEveryFrame(e:Event):void {
            var i:int;
            // 最初の一秒ほどで撒き散らす
            if ( (frameCount+1)*25 < kamiFubuki.length ) {
                for ( i = frameCount*25 ; i < (frameCount+1)*25 ; ++i ) {
                    if ( i >= kamiFubuki.length ) break;
                    kamiFubuki[i].x 
                        = Kamikire.SIZE/Math.SQRT2 
                            + (stage.stageWidth-Kamikire.SIZE*Math.SQRT2)*(i/kamiFubuki.length);
                    kamiFubuki[i].y = 30;
                    kamiFubuki[i].visible = true;
                }
                frameCount++;
            }
            // 紙切れを落とす.  画面の外に出たら反対側から入ってくる(トーラス空間)
            for ( i = 0 ; i < kamiFubuki.length ; ++i ) {
                kamiFubuki[i].fall();
                if (kamiFubuki[i].x - Kamikire.SIZE/Math.SQRT2 > stage.stageWidth) {
                    kamiFubuki[i].x -= stage.stageWidth;
                }
                if (kamiFubuki[i].x + Kamikire.SIZE/Math.SQRT2 < 0 ) {
                    kamiFubuki[i].x += stage.stageWidth;
                }
                if (kamiFubuki[i].y - Kamikire.SIZE/Math.SQRT2 > stage.stageHeight) {
                    kamiFubuki[i].y -= stage.stageHeight;
                }
            }
        }
        
        private function onResize(e:Event):void {
            drawBackGround();
            var i:int;
            for ( i = 0 ; i < kamiFubuki.length ; ++i ) {
                    kamiFubuki[i].visible = false;
            }
            frameCount = 0;
        }

        private function initialize(e:Event):void {
            this.removeEventListener(Event.ADDED_TO_STAGE, initialize);
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            drawBackGround();
            kamiFubuki = new Array();
            while ( kamiFubuki.length < NUM_KAMIKIRE ) {
                kamiFubuki.unshift(new Kamikire());
                kamiFubuki[0].visible = false; // 出し方をヒネったので最初は見えなくする
                this.addChild(kamiFubuki[0]);
            }
            stage.frameRate = 24;
            frameCount = 0;
            stage.addEventListener(Event.RESIZE, onResize);
            stage.addEventListener(Event.ENTER_FRAME, atEveryFrame);
        }
        // The Main constructor simply calles initialize() function.

        public function Main():void {
            if ( stage != null ) {
                initialize(null);
            } else {
                this.addEventListener(Event.ADDED_TO_STAGE, initialize);
            }
        }

    } // end of class Main
} // end of package


// 固有の軸のまわりを固有の角速度で3D回転しながらフラフラと落下する正方形の紙切れ
import flash.display.*;
class Kamikire extends Shape {
    public static const SIZE:Number = 10;
    private var _faceColor:uint;
    private var _backColor:uint;
    private var _theta:Number; // amount of rotation along the axis
    private var _omega:Number; // angular velocity
    private var _fallTheta:Number;
    private var _fallSpeed:Number;
    private var _Ax:Number,_Ay:Number,_Az:Number; // axis of rotation
    private var _Bx:Number,_By:Number,_Bz:Number; // a unit vector perp to A
    private var _Cx:Number,_Cy:Number,_Cz:Number; // a unit vector perp to A and B
    public function Kamikire() {
        var t:Number = Math.random()*Math.PI*2;
        var r:int = Math.floor((1+Math.cos(t))*127.9999);
        var g:int = Math.floor((1+Math.cos(t+Math.PI*2/3))*127.9999);
        var b:int = Math.floor((1+Math.cos(t-Math.PI*2/3))*127.9999);
        _faceColor = (r<<16)|(g<<8)|b;
        _backColor = 0x010101*Math.floor(127+Math.random()*64);
        _omega = (Math.random()*2-1)*Math.PI/4;
        _fallTheta = 0;
        _fallSpeed = 3+Math.random()*2;
        _theta = Math.random()*Math.PI*2;
        _Ax = 1;
        _Ay = Math.random();
        _Az = Math.random()*2-1;
        var _l:Number = Math.sqrt(_Ax*_Ax+_Ay*_Ay+_Az*_Az);
        _Ax /= _l;
        _Ay /= _l;
        _Az /= _l;
        var _s:Number = Math.sqrt(_Ax*_Ax+_Ay*_Ay);
        if ( _s == 0 ) { // then A == ( 0, 0, -1 );
            _Bx = 1.0; _By = 0.0; _Bz = 0.0;
            _Cx = 0.0; _Cy = 1.0; _Cz = 0.0;
        } else {
            _Bx = _Ay; _By = -_Ax; _Bz = 0;
            _Cx = _Ax*_Az; _Cy = _Ay*_Az; _Cz = -(_s*_s);
            _Bx /= _s; _By /= _s;
            _Cx /= _s*_l; _Cy /= _s*_l; _Cz /= _s*_l;
        }
        this.graphics.beginFill(_faceColor);
        this.graphics.drawRect(-SIZE/2,-SIZE/2,SIZE,SIZE);
        this.graphics.endFill();
    }
    // rotate along the axis (_Ax,_Ay,_Az)...
    public function set rotation3D(theta:Number):void {
        _theta = theta - (Math.PI*2)*Math.floor(theta/(Math.PI*2));
        var _cos:Number = Math.cos(_theta);
        var _sin:Number = Math.sin(_theta);
        // vector F is the rotated image of (1,0,0);
        var _Fx:Number = _Ax*_Ax+(_Bx*_Bx+_Cx*_Cx)*_cos;
        var _Fy:Number = _Ax*_Ay+(_Bx*_By+_Cx*_Cy)*_cos+(_Bx*_Cy-_Cx*_By)*_sin;
        var _Fz:Number = _Ax*_Az+(_Bx*_Bz+_Cx*_Cz)*_cos-(_Bx*_Cz-_Cx*_Bz)*_sin;
        // vector G is the rotated image of (0,1,0);
        var _Gx:Number = _Ax*_Ay+(_By*_Bx+_Cy*_Cz)*_cos+(_By*_Cx-_Cy*_Bx)*_sin;
        var _Gy:Number = _Ay*_Ay+(_By*_By+_Cy*_Cy)*_cos;
        var _Gz:Number = _Ay*_Az+(_By*_Bz+_Cy*_Cz)*_cos+(_By*_Cz-_Cy*_Bz)*_sin;
        // let's see whether the piece shows its face or its back...
        var cc:uint = ( (_Az*_Az+(_Bz*_Bz+_Cz*_Cz)*_cos) >= 0 )?_faceColor:_backColor;
        // We can draw the image now...
        this.graphics.clear();
        this.graphics.beginFill(cc);
        this.graphics.moveTo(_Fx*SIZE/2+_Gx*SIZE/2,_Fy*SIZE/2+_Gy*SIZE/2);
        this.graphics.lineTo(-_Fx*SIZE/2+_Gx*SIZE/2,-_Fy*SIZE/2+_Gy*SIZE/2);
        this.graphics.lineTo(-_Fx*SIZE/2-_Gx*SIZE/2,-_Fy*SIZE/2-_Gy*SIZE/2);
        this.graphics.lineTo(_Fx*SIZE/2-_Gx*SIZE/2,_Fy*SIZE/2-_Gy*SIZE/2);
        this.graphics.lineTo(_Fx*SIZE/2+_Gx*SIZE/2,_Fy*SIZE/2+_Gy*SIZE/2);
        this.graphics.endFill();
    }
    public function get rotation3D():Number {
        return _theta - (Math.PI*2)*Math.floor(_theta/(Math.PI*2));
    }
    public function fall():void {
        this.rotation3D += this._omega;
        this.x += _fallSpeed*Math.sin(_fallTheta);
        this.y += _fallSpeed*Math.cos(_fallTheta);
        _fallTheta += (Math.random()*2-1)*Math.PI/12;
        if ( _fallTheta < -Math.PI/2 ) {
            _fallTheta = -Math.PI - _fallTheta;
        }
        if ( _fallTheta > Math.PI/2 ) {
            _fallTheta = Math.PI - _fallTheta;
        }
    }
} // end of class Kamikire