forked from: with EFLA

by monodreamer forked from with EFLA (diff: 132)
♥2 | Line 267 | Modified 2011-09-08 23:59:52 | MIT License
play

ActionScript3 source code

/**
 * Copyright monodreamer ( http://wonderfl.net/user/monodreamer )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/uPlb
 */

// forked from Blue_fox_and_red_grape's with EFLA
// forked from codeonwort's transition 3D rotatable
// forked from codeonwort's transition 3D
// forked from codeonwort's forked from: transition
// forked from Nyarineko's transition
package {
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import flash.geom.ColorTransform;
    import flash.display.Shape;
    
    import flash.geom.Vector3D
    import flash.geom.Point;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.display.Graphics;
    import flash.filters.BlurFilter
    
    import net.hires.debug.Stats;
    
    [SWF(width = "465", height = "465", backgroundColor = "0xffffff", frameRate = "60")]
    
    public class Main extends Sprite {
        
        private const M_WIDTH:Number = 465;
        private const M_HEIGH:Number = 465;
        private const OX:Number = 465 / 2;
        private const OY:Number = 465 / 2;
        private const V:Number = 2
        private const VR:Number = V * Math.PI/180;
        private const OBJ_MAX:Number = 15;
        private var max:uint = 5;
        private var amax:uint = 0;
        private var _canvas:BitmapData
        private var _bmp:Bitmap;
        private var first:Particle;
        private var _tmp:BitmapData;
        //------------------------------------------------------
        //コンストラクタ
        //------------------------------------------------------
        public function Main() {
           
            graphics.beginFill(0)
            graphics.drawRect(0, 0, M_WIDTH, M_HEIGH)
            graphics.endFill()
            
            _canvas = new BitmapData(M_WIDTH, M_HEIGH, true, 0 );
            _tmp = _canvas.clone();
            _bmp = new Bitmap(_canvas);
            addChild(_bmp)
            addChild(new Stats());

           // Particle.originX = OX, Particle.originY = OY
            init();
            stage.addEventListener(MouseEvent.CLICK,onClick);
            stage.addEventListener(Event.ENTER_FRAME,enterframeHandler);
        }
        
        //------------------------------------------------------
        //初期化
        //------------------------------------------------------
        private function init():void {
            first = new Particle
            var p:Particle = first;
            for(var i:uint = 0;i < max;i++){
                p.phi = Math.PI * 2 * i / max; //360 * i / max
                p.theta = Math.random() * Math.PI //180 * i / max
                p.phiVel = VR
                p.radius = 1
                p.thetaVel = 0
                p.color = Math.random() * 0x404040 + 0xC0C0C0;
                if(i != max - 1){
                    p.next = new Particle
                    p = p.next;
                }
            }
        }
        
        private var zero:Point = new Point
        private var blur:BlurFilter = new BlurFilter(8, 8)
        private function enterframeHandler(e:Event):void {
            //_canvas.fillRect(_canvas.rect, 0x0 );
            update();
        }
        
        private function onClick(e:MouseEvent):void {
            _canvas.lock();
            _canvas.fillRect(_canvas.rect, 0x0);
            _canvas.unlock();
            init();
        }
  

        // Extremely Fast Line Algorithm : http://wonderfl.net/c/A69m
        private function efla(bmd:BitmapData, x:int, y:int, x2:int, y2:int, color:uint):void {
            var shortLen:int = y2 - y;
            var longLen:int = x2 - x;
            if (!longLen) if (!shortLen) return;
            var i:int, id:int, inc:int;
            var multDiff:Number;

           // bmd.lock();

            // TODO: check for this above, swap x/y/len and optimize loops to ++ and -- (operators twice as fast, still only 2 loops)
            if ((shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31)) {
                if (shortLen < 0) {
                    inc = -1;
                    id = -shortLen & 3;
                } else {
                    inc = 1;
                    id = shortLen & 3;
                }
                multDiff = !shortLen ? longLen : longLen / shortLen;

                if (id) {
                    bmd.setPixel32(x, y, color);
                    i += inc;
                    if (--id) {
                        bmd.setPixel32(x + i * multDiff, y + i, color);
                        i += inc;
                        if (--id) {
                            bmd.setPixel32(x + i * multDiff, y + i, color);
                            i += inc;
                        }
                    }
                }
                while (i != shortLen) {
                    bmd.setPixel32(x + i * multDiff, y + i, color);
                    i += inc;
                    bmd.setPixel32(x + i * multDiff, y + i, color);
                    i += inc;
                    bmd.setPixel32(x + i * multDiff, y + i, color);
                    i += inc;
                    bmd.setPixel32(x + i * multDiff, y + i, color);
                    i += inc;
                }
            } else {
                if (longLen < 0) {
                    inc = -1;
                    id = -longLen & 3;
                } else {
                    inc = 1;
                    id = longLen & 3;
                }
                multDiff = !longLen ? shortLen : shortLen / longLen;

                if (id) {
                    bmd.setPixel32(x, y, color);
                    i += inc;
                    if (--id) {
                        bmd.setPixel32(x + i, y + i * multDiff, color);
                        i += inc;
                        if (--id) {
                            bmd.setPixel32(x + i, y + i * multDiff, color);
                            i += inc;
                        }
                    }
                }
                while (i != longLen) {
                    bmd.setPixel32(x + i, y + i * multDiff, color);
                    i += inc;
                    bmd.setPixel32(x + i, y + i * multDiff, color);
                    i += inc;
                    bmd.setPixel32(x + i, y + i * multDiff, color);
                    i += inc;
                    bmd.setPixel32(x + i, y + i * multDiff, color);
                    i += inc;
                }
            }

            //bmd.unlock();
        }
        
        /////////////////////////////////////////
        private var ran:Number
        private var p:Particle
        private var cnt:uint
        private var zRate:Number, pos:Pos, track:Array;
        private var i:int, len:int
        
        private var prevX:int, prevY:int;
        private var b:uint;
       // private var sh:Shape = new Shape;
       // private var g:Graphics = sh.graphics;
       private var _ct:ColorTransform = new ColorTransform(1,1,1,.5);
        private function update():void {
            p = first
            cnt = 0
            
            // rotate
           // Particle.theta0 += (mouseX-OX)/OX*2
           // Particle.phi0 += (mouseY-OY)/OY*2
            
           _rx += (mouseX-OX) / OX * VR;
           _ry += (mouseY-OY) / OY * VR;
           
            _canvas.lock();
            _canvas.colorTransform(_canvas.rect, _ct);
            while(p){
                cnt++;
                if(p.radius > 400){
                    p.reset();
                   // p = p.next;
                    continue;
                }
                
                ran =  Math.random();
                if(ran < 0.1){
                    p.phiVel = p.thetaVel = 0;
                    p.radVel = V;
                }else if(ran < 0.2){
                    p.phiVel = -VR;
                    p.radVel = p.thetaVel = 0;
                }else if(ran < 0.3){
                    p.phiVel = VR;
                    p.radVel = p.thetaVel = 0;
                }else if(ran < 0.4){
                    p.thetaVel = VR
                    p.phiVel = p.radVel = 0
                }else if(ran < 0.5){
                    p.thetaVel = -VR
                    p.phiVel = p.radVel = 0
                }else if(ran < 0.504 && amax < OBJ_MAX){
                    var newP:Particle = new Particle();
                    newP.phi = p.phi
                    newP.theta = p.theta
                    newP.radius = p.radius
                    newP.color = Math.random() * 0x404040 + 0xC0C0C0;
                    if(p.phiVel == 0){
                        newP.phiVel = 0
                        newP.radVel = 1
                    }else{
                        newP.phiVel = Math.random() < 0.5 ? -VR : VR
                        newP.radVel = 0
                    }
                    newP.next = p.next;
                    p.next = newP;
                }
                p.radius += p.radVel
                p.phi += p.phiVel
                p.theta += p.thetaVel
                p.saveCurrentCoord()
                
                
                track = p.track;
                var pr:Number, pc:uint = p.color, rp:Number, rt:Number, nx:Number, ny:Number;
                //g.moveTo(track[0].x, track[0].y)
                pos = track[0];
                pr = pos.r;
                rp = pos.phi + _ry;
                rt = pos.theta + _rx;
                prevX = pr * Math.sin(rp) * Math.sin(rt) + OX;
                prevY = pr * Math.cos(rp) + OY;
                //g.moveTo(prevX, prevY);
                len = track.length
                _tmp.fillRect(_tmp.rect, 0);
                        
                for(i=1; i<len; i++){
                    pos = track[i];
                    
                    pr = pos.r;
                    rp = pos.phi + _ry;
                    rt = pos.theta + _rx;
                    
                    zRate = -(pr*Math.sin(rp)*Math.cos(rt))/800 + .6;
                    
                    nx = pr * Math.sin(rp) * Math.sin(rt) + OX;
                    ny = pr * Math.cos(rp) + OY;
                    
                    //g.lineStyle(1+zRate*0.5, p.color, zRate)
                    //g.lineTo(pos.x, pos.y)
                    
                    efla( _tmp, prevX, prevY, nx, ny, (zRate*0xFF)<<24 | pc);
                    prevX = nx;
                    prevY = ny;
                }
                _canvas.draw(_tmp, null, null, 'add');
                p = p.next;
            }

            _canvas.unlock();
            amax = cnt;
        }
        
        private var _rx:Number = 0;
        private var _ry:Number = 0;
    }
    
}

internal class Particle {
    
   // public static var originX:Number, originY:Number
   //public static var t0:Number = 0 // theta0
  // public static var p0:Number = 0 // phi0
   // public static function get theta0():Number { return t0 * Kinv }
   // public static function set theta0(v:Number):void { t0 = v * K }
  //  public static function get phi0():Number { return p0 * Kinv }
   // public static function set phi0(v:Number):void { p0 = v * K }
    
   // private static const K:Number = Math.PI / 180
   // private static const Kinv:Number = 180 / Math.PI
    
   private static const GO_FORWARD:uint = 0
   private static const ROTATE:uint = 1
    
    public var theta:Number = 0
    public var phi:Number = 0
    public var radius:Number = 0
    public var thetaVel:Number = 0, phiVel:Number = 0, radVel:Number = 0
    
    public var track:Array = [];
    public var next:Particle
    public var color:uint;
    private var state:uint = GO_FORWARD
    
    public function saveCurrentCoord():void {
        var newState:uint = radVel ? GO_FORWARD : ROTATE
        var pos:Pos = new Pos;
        pos.r = radius;
        pos.phi = phi;
        pos.theta = theta;
        //pos.x = radius * Math.cos(c.phi) * Math.cos(c.theta);
        //pos.y = radius * Math.sin(c.phi);
        //pos.z = radius * Math.cos(c.phi) * Math.sin(c.theta);
        
        if(state == GO_FORWARD && newState == state){
            track.pop()
        }
        track.push(pos);
        
        state = newState
    }
    
    public function reset():void
    {
        track = [];
        phi = Math.PI * 2 * Math.random(); //360 * i / max
        theta = Math.random() * Math.PI //180 * i / max
        phiVel = 2 * Math.PI/180;
        radius = 1
        thetaVel = 0
        color = Math.random() * 0x404040 + 0xC0C0C0;
    }
    
   // public function get phi():Number { return _phi * Kinv }
   // public function set phi(v:Number):void { _phi = v * K }
    
   // public function get theta():Number { return _theta * Kinv }
   // public function set theta(v:Number):void { _theta = v * K }

}

//internal class Coord {
 //   public var r:Number, phi:Number, theta:Number    
//}

internal class Pos {
    public var r:Number, phi:Number, theta:Number;
}