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

Particle Galaxy

@title Particle space exploration demo
@author Simo Endre (esimov)

Click and drag to explore in depth particle formation
Move the mouse along x and y axes to create some 3D space exploration effect
Hold the mouse steady to entail some floating movement
Get Adobe Flash player
by esimov 09 Apr 2011
/**
 * Copyright esimov ( http://wonderfl.net/user/esimov )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ddQX
 */

/**
 * @title Particle space exploration demo
 * @author Simo Endre (esimov)
 * 
 * Click and drag to explore in depth particle formation
 * Move the mouse along x and y axes to create some 3D space exploration effect
 * Hold the mouse steady to entail some floating movement
 * */

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.events.MouseEvent;
    import flash.filters.BitmapFilterQuality;
    import flash.filters.BlurFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.utils.getTimer;
    
    import net.hires.debug.Stats;
    
    [SWF (backgroundColor = 0x00, width = '465', height = '465')]

    public class ParticleGalaxy extends Sprite
    {
        private const WIDTH:Number = stage.stageWidth;
        private const HEIGHT:Number = stage.stageHeight;
        private static const PHI:Number = 3.14159265;
        
        private var _fl:Number = 250;
        private var _phi:Number;
        private var _theta:Number;
        private var _minDepth:Number;
        private var _maxDepth:Number;
        private var _fadeRate:Number;
        private var _maxLevelInc:Number;
        private var _offset:Number;
        private var _targetPhi:Number;
        private var _targetTheta:Number;
        private var _targetOffset:Number;
        
        private var _projCenterX:Number;
        private var _projCenterY:Number;
        private var _isDragging:Boolean = false;
        private var _firstParticle:Particle3D;
        
        private var _screen:Sprite;
        private var _bmpData:BitmapData;
        private var _bmp:Bitmap;
        private var _ct:ColorTransform;
        private var _blur:BlurFilter;
        private var _particles:TextField;
        
        public function ParticleGalaxy():void
        {
            if (stage) initStage(null);
            else {
                addEventListener(Event.ADDED_TO_STAGE, initStage);
                throw new Error("Stage not initialized");
            }
        }
        
        private function initStage(event:Event):void
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.frameRate = 60;
            stage.quality = "heigh";
            stage.fullScreenSourceRect = new Rectangle(0, 0, WIDTH, HEIGHT);
            
            init();
        }
        
        private function init():void
        {
            _maxLevelInc = 34;
            _minDepth = - 100;
            _maxDepth = 210;
            _theta = PHI;
            _phi = - PHI;
            _offset = 80;
            _targetPhi = _phi;
            _targetTheta = _theta;
            _targetOffset = 129;
            _fadeRate = _maxLevelInc * (_maxDepth - _minDepth);
            
            _screen = new Sprite();
            _screen.x = _screen.y = 0;
            _bmpData = new BitmapData(WIDTH, HEIGHT, false, 0x00);
            _bmp = new Bitmap(_bmpData);
            addChild(_screen);
            _screen.addChild(_bmp);
            
            var tf:TextFormat = new TextFormat("Verdana", 10);
            _particles = new TextField();
            _particles.defaultTextFormat = tf;
            _particles.background = true;
            _particles.backgroundColor = 0x333333;
            _particles.autoSize = "right";
            _particles.textColor = 0xffffff;
            _particles.x = WIDTH - _particles.textWidth - 5;
            _particles.text = "";
            addChild(_particles);
            addChild(new Stats());
            
            _ct = new ColorTransform(0.77, 0.77, 0.77);
            _blur = new BlurFilter(3, 3, BitmapFilterQuality.MEDIUM); 
            
            _projCenterX = _screen.width >> 1;
            _projCenterY = _screen.height >> 1;
            
            createParticles();
            addEventListener(Event.ENTER_FRAME, beginTest);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, beginDrag);
            stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
            
        }
        
        private function beginDrag(event:MouseEvent):void
        {
            _isDragging = true;
        }
        
        private function endDrag(event:MouseEvent):void
        {
            _isDragging = false;
        }
        
        private function beginTest(event:Event):void
        {
            var p:Particle3D = _firstParticle;
            var posY:Number = _screen.height / 2;
            var posX:Number = _screen.width / 2;
            if (_isDragging)
            {
                _targetOffset = _screen.mouseX >> 1;
                _targetTheta = -0.1 * PHI + 1.2 * _screen.mouseX / _screen.width * PHI;
                _targetPhi = -1.2 * _screen.mouseY / _screen.height * PHI;
            }
            
            var rThe:Number = 0.12 * Math.cos(getTimer() * 0.000145);
            var rPhi:Number = 0.15 * Math.sin(getTimer() * 0.000245);
            _phi += 0.1 * (_targetPhi - _phi);
            _theta += 0.1 * (_targetTheta - _theta);
            
            if (!_isDragging)
            {
                _phi = (_phi + rPhi) % PHI << 2;
                _theta = (_theta + rThe) % PHI << 2;
                posY += (_screen.mouseY - posY) * 0.0015;
                posX += (_screen.mouseX - posX) * 0.0015;
            }
        
            _offset += 0.1 * (_targetOffset - _offset);
            
            var cosP:Number = Math.cos(posY) + rPhi;
            var sinP:Number = Math.sin(posY) + rPhi;
            var cosT:Number = Math.cos(posX) + rThe;
            var sinT:Number = Math.sin(posX) + rThe;
            
            var C11:Number = cosT * sinP;
            var C12:Number = sinT * sinP;
            var C21:Number = - cosP * cosT;
            var C22:Number = - sinT * cosP;
            
            _bmpData.lock();
            _bmpData.applyFilter(_bmpData, _bmpData.rect, new Point(), _blur);
            _bmpData.colorTransform(_bmpData.rect, _ct);
            
            do
            {                
                p.u = C11 * p.x + C12 * p.y + cosT * p.z + _offset;
                p.v = - sinP * p.x + cosP * p.y;
                p.w = C21 * p.x + C22 * p.y + sinT * p.z;
                
                var df:Number = _fl / (_fl - p.u);
                p.projX = df * p.v + _projCenterX;
                p.projY = df * p.w + _projCenterY;
                
                if (p.projX < 0 || p.projX > WIDTH || p.projY < 0 || p.projY > HEIGHT)
                {
                    p.onScreen = false;
                } else { p.onScreen = true }
                
                if (p.onScreen)
                {
                    var readLevel:uint = _bmpData.getPixel(p.projX, p.projY) & 0xff;
                    var dimm:Number = _fadeRate * (p.u - _minDepth);
                    dimm = (dimm > _maxLevelInc) ? _maxLevelInc : (dimm < 0 ? 0 : dimm);
                    
                    var level:Number = dimm + readLevel;
                    level = (level > 255) ? 255 : level;
                    
                    var color:uint = level << 16 | level << 8 | level;
                    _bmpData.setPixel(p.projX, p.projY, color);
                }
                
                p= p.next;
                
            } while (p != null);
            
            _bmpData.unlock();
        }
        
        private function createParticles():void
        {
            var prevParticle:Particle3D;
            var minTheta:Number = - 3.14159265;
            var maxTheta:Number = 3.14159265;
            var minPhi:Number = - 3.14159265;
            var maxPhi:Number = 3.14159265;
            
            var numT:Number = 350;
            var numP:Number = 350;
            var count:Number = 0;
            
            var t0:Number = (maxTheta - minTheta) / numT;
            var p0:Number = (maxPhi - minPhi) / numP;
            
            for (var i:int = 0; i < numT; i++)
            {
                var tInc:Number = Math.min(minTheta, t0) + t0 * i;
                for (var j:int = 0; j < numP; j++)
                {
                    var pInc:Number = Math.min(minPhi, p0) + p0 * j;
                    
                    var t:Number = tInc + t0 * (Math.random() * 2 - 1);
                    var p:Number = pInc + p0 * (Math.random() * 2 - 1);
                    
                    //var radT:Number = 100 * (0.5 + 0.5 * Math.cos(t));
                    //var radP:Number = 100 * (0.5 + 0.5 * Math.sin(p));
                    var rot:Number = 100 *(1.2 + Math.cos(6.2*t) * Math.sin(6.5*p));
                    
                    var particle:Particle3D = new Particle3D();
                                    
                    particle.x = rot * Math.cos(t) + rot * Math.cos(p) * Math.sin(t);
                    particle.y = rot * Math.sin(t) + rot * Math.cos(p) * Math.sin(p);
                    particle.z = rot * Math.sin(p) + rot * Math.cos(t);
                    
                    /*particle.x = radT*Math.cos(p)+radP*Math.cos(t+PHI/3*Math.sin(t))*Math.cos(p);
                    particle.y = radT*Math.sin(p)+radP*Math.cos(t-PHI/3*Math.sin(t))*Math.sin(p);
                    particle.z = radP*Math.cos(t);*/
                    
                    particle.next = prevParticle;
                    prevParticle = particle;
                    count ++;
                }
            }
            _firstParticle = particle;
            _particles.text = count + " particles";
        }        
    }
}

class Point3D
{
    public var x:Number;
    public var y:Number;
    public var z:Number;
    
    public function Point3D(x:Number = 0, y:Number = 0, z:Number = 0):void
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

class Particle3D extends Point3D
{
    public var red:uint;
    public var green:uint;
    public var blue:uint;
    public var color:uint;
    
    public var projX:Number;
    public var projY:Number;
    
    public var u:Number;
    public var v:Number;
    public var w:Number;
    
    public var next:Particle3D;
    public var onScreen:Boolean;
    
    public function Particle3D(color:uint = 0xFFFFFF):void
    {
        this.color = color;
        this.red = getRed(color);
        this.green = getGreen(color);
        this.blue = getBlue(color);
    }
    
    public function getRed(c:uint):uint
    {
        return c >> 16 & 0xff;
    }
    
    public function getGreen(c:uint):uint
    {
        return c >> 08 & 0xff;
    }
    
    public function getBlue(c:uint):uint
    {
        return c >> 00 & 0xff;
    }
}