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

カラーパーティクル

カラーパーティクル

色はパーティクルにかかる力の方向で決定

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

// forked from tkinjo's パーティクルテスト
// forked from tkinjo's パーリンノイズの生成とフレームスキップ
package  
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.utils.*;
    import net.hires.debug.Stats;
    
    [SWF(width="465", height="465", backgroundColor="0x0", frameRate="30")] 
    /**
     * カラーパーティクル
     * 
     * 色はパーティクルにかかる力の方向で決定
     * 
     * @author tkinjo
     */
    public class Main extends Sprite
    {
        // farame skip setting
        private const FRAME_SKIP_MARGIN:uint = 0;
        
        // force map setting
        private const FORCE_MAP_CREATE_BY_ENTER_FRAME:Boolean = true;
        private const FORCE_MAP_SCALE:uint = 3;
        private const OFFSET_SPEED:Number = 1;
        private const NUM_OCTAVES:uint = 4;
        
        // particle setting
        private const PARTICLE_NUM:uint = 1000;
        private const FRAME_SKIP_DRAW_PARTICLE:Boolean = false;
        
        // view setting
        private const FADE_OUT_COLOR_TRANSFORM:ColorTransform = new ColorTransform( 1, 1, 1, 1, -8, -8, -8);
        
        
        
        private var stageWidth:Number  = stage.stageWidth;
        private var stageHeight:Number = stage.stageHeight;
        
        private var frameSkipper:FrameSkipper;
        
        private var forceMapBitmap:Bitmap;
        private var forceMapBitmapData:BitmapData;
        private var offsets:Array;
        private var seed:uint;
        
        private var particles:Particle;
        private var viewBitmapData:BitmapData;
        private var viewBitmap:Bitmap;
        
        
        
        public function Main() 
        {
            frameSkipper = new FrameSkipper( stage.frameRate, FRAME_SKIP_MARGIN );
            
            
            
            forceMapBitmapData = new BitmapData( stageWidth >> FORCE_MAP_SCALE, stageHeight >> FORCE_MAP_SCALE );
            offsets = new Array();
            for ( var i:uint = 0; i < NUM_OCTAVES; i++ )
                offsets.push( new Point() );
            seed = Math.random() * 0xffff;
            
            
            // create particle
            var previousParticle:Particle = particles = new Particle( Math.random() * 465, Math.random() * 465 );
            var particle:Particle;
            for ( i = 0; i < PARTICLE_NUM; i++) {
                previousParticle.next = particle = new Particle( Math.random() * 465, Math.random() * 465 );
                previousParticle = particle;
            }
            
            
            
            // create view bitmap
            viewBitmapData = new BitmapData( stageWidth, stageHeight, false, 0x0 );
            
            viewBitmap = new Bitmap( viewBitmapData );
            addChild( viewBitmap );
            
            
            
            addEventListener( Event.ENTER_FRAME, enterFrameHandler );
            
            
            
            forceMapBitmap = new Bitmap( forceMapBitmapData );
            forceMapBitmap.scaleX = 100 / forceMapBitmap.width
            forceMapBitmap.scaleY = 100 / forceMapBitmap.height;
            forceMapBitmap.x = stageWidth - forceMapBitmap.width;
            addChild( forceMapBitmap );
            
            
            
            var hueCircle:HueCircle = new HueCircle( 50, 30 );
            hueCircle.x = hueCircle.radius + stageWidth - hueCircle.width;
            hueCircle.y = hueCircle.radius + forceMapBitmap.height;
            hueCircle.graphics.beginFill( 0x0 );
            hueCircle.graphics.drawRect( -hueCircle.radius, -hueCircle.radius, hueCircle.width, hueCircle.height );
            hueCircle.graphics.endFill();
            addChild( hueCircle );
            
            
            
            if( !FORCE_MAP_CREATE_BY_ENTER_FRAME )
                forceMapBitmapData.perlinNoise( stageHeight >> ( FORCE_MAP_SCALE + 1 ), stageHeight >> ( FORCE_MAP_SCALE + 1 ), NUM_OCTAVES, seed, true, true, 3, false, offsets );
            
            addChild(new Stats);
        }
        
        private function enterFrameHandler( event:Event ):void {
            
            frameSkipper.update();
            
            if ( FORCE_MAP_CREATE_BY_ENTER_FRAME && !frameSkipper.skip ) {
                
                var offset:Number = ( frameSkipper.skipped + 1 ) * ( OFFSET_SPEED / FORCE_MAP_SCALE );
                
                for ( var i:uint = 0; i < NUM_OCTAVES; i++ ) {
                    
                    switch( i % 4 ) {
                        
                        case 0:
                            offsets[i].x += offset;
                            break;
                            
                        case 1:
                            offsets[i].x -= offset;
                            break;
                            
                        case 2:
                            offsets[i].y += offset;
                            break;
                            
                        case 3:
                            offsets[i].y -= offset;
                            break;
                    }
                }
                
                forceMapBitmapData.lock();
                forceMapBitmapData.perlinNoise( stageHeight >> ( FORCE_MAP_SCALE + 1 ), stageHeight >> ( FORCE_MAP_SCALE + 1 ), NUM_OCTAVES, seed, true, true, 3, false, offsets );
                forceMapBitmapData.unlock();
            }
            
            
            
            var particle:Particle = particles;
            var color:uint;
            var centerPoint:Point = new Point();
            var force:Point = new Point();
            
            viewBitmapData.lock();
            
            if ( !FRAME_SKIP_DRAW_PARTICLE || ( FRAME_SKIP_DRAW_PARTICLE && !frameSkipper.skip ) )
                viewBitmapData.colorTransform( viewBitmapData.rect, FADE_OUT_COLOR_TRANSFORM );
            
            while ( ( particle = particle.next ) != null )
            {
                color = forceMapBitmapData.getPixel( particle.x >> FORCE_MAP_SCALE, particle.y >> FORCE_MAP_SCALE );
                
                particle.x += ( particle.vx = particle.vx * 0.98 + ( ( color >> 16 & 0xff ) - 128 ) * 0.005 );
                particle.y += ( particle.vy = particle.vy * 0.98 + ( ( color >> 8  & 0xff ) - 128 ) * 0.005 ) ;
                
                
                
                if (particle.x < 0) 
                    particle.x += stageWidth;
                    
                else if ( particle.x >= stageWidth ) 
                    particle.x -= stageWidth;
                
                
                
                if ( particle.y < 0 ) 
                    particle.y += stageHeight;
                    
                else if ( particle.y >= stageHeight ) 
                    particle.y -= stageHeight;
                
                
                force.x = ( color >> 16 & 0xff ) - 128;
                force.y = ( color >> 8  & 0xff ) - 128;
                
                if ( !FRAME_SKIP_DRAW_PARTICLE || ( FRAME_SKIP_DRAW_PARTICLE && !frameSkipper.skip ) )
                    viewBitmapData.setPixel( particle.x, particle.y, getHueCircleColor( centerPoint, force ) );
            }
            
            viewBitmapData.unlock();
        }
    }
}



import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.geom.*;


class Particle {
    
    public var vx:Number = 0;
    public var vy:Number = 0;
    public var x:int;
    public var y:int;
    public var next: Particle;
    
    function Particle( x:int, y:int ) {
        this.x = x;
        this.y = y;
    }
}







class FrameSkipper {
    
    /* ==================================================
     * property
     * ==================================================
     */
    
    /**
     * スキップされたフレーム数
     */
    public function get skipped():uint { return _skipped; }
    private var _skipped:uint = 0;
    
    
    /**
     * スキップするべきときなら true、そうでないなら false
     * 
     * --- 例 ---
     * if( !frameSkipper.skip )
     *     // フレームスキップしない時の処理(描画などの重い処理)
     * else 
     *     // フレームスキップするときの処理(描画をせずにデータ地だけ変更するなどの軽い処理)
     */
    public function get skip():Boolean { return skipCounter >= 0; }
    
    /**
     * 保ちたい fps 値
     */
    public var expectedFPS:uint;
    
    /**
     * 
     */
    public var margin:uint;
    
    
    
    /* ==================================================
     * field
     * ==================================================
     */
    private var previousTime:int = 0;
    private var currentTime:int = 0;
    private var skipCounter:int = 0;
    private var fps:uint;
    
    
    
    /* ==================================================
     * method
     * ==================================================
     */
    public function FrameSkipper( expectedFPS:uint = 60, margin:uint = 0 ):void {
        
        this.expectedFPS = expectedFPS;
        this.margin = margin;
    }
    
    public function update():void {
        
        currentTime = getTimer();
        
        
        
        fps = 1000 / ( currentTime - previousTime );
        
        if ( !skip && fps < expectedFPS ) {
            
            _skipped = expectedFPS / fps + margin;
            skipCounter = skipped;
            
        } else 
            skipCounter--;
        
        
        
        previousTime = currentTime;
    }
}




class HueCircle extends Sprite {
    
    public function get radius():Number { return _radius; }
    public function set radius(value:Number):void 
    {
        _radius = value;
        draw();
    }
    private var _radius:Number;
    
    
    
    public function get innerRadius():Number { return _innerRadius; }
    public function set innerRadius(value:Number):void 
    {
        _innerRadius = value;
        draw();
    }
    private var _innerRadius:Number;
    
    
    
    private var bitmap:Bitmap;
    private var circleMask:Sprite;
    
    
    
    public function HueCircle( radius:Number, innerRadius:Number = 0 ) {
        
        _radius = radius;
        _innerRadius = innerRadius;
        
        var diameter:Number = radius * 2;
        
        
        
        if ( hueCircleBitmapData == null )
            resizeHueCircleBitmapData( diameter );
        
        
        
        bitmap = new Bitmap( hueCircleBitmapData );
        bitmap.cacheAsBitmap = true;
        addChild( bitmap );
        
        
        
        circleMask = new Sprite();
        circleMask.cacheAsBitmap = true;
        addChild( circleMask );
        
        
        
        bitmap.mask = circleMask;
        
        draw();
    }
    
    private function draw():void {
        
        circleMask.graphics.clear();
        circleMask.graphics.beginFill( 0xffffff );
        circleMask.graphics.drawCircle( radius, radius, radius);
        if( innerRadius != 0 ) circleMask.graphics.drawCircle( radius, radius, innerRadius );
        circleMask.graphics.endFill();
        
        
        var largeRadius:Number = ( ( radius > innerRadius ) ? radius : innerRadius );
        bitmap.x = -largeRadius;
        bitmap.y = -largeRadius;
        bitmap.scaleX = largeRadius / ( hueCircleBitmapData.width / 2 );
        bitmap.scaleY = largeRadius / ( hueCircleBitmapData.width / 2 );
        
        circleMask.x = -radius;
        circleMask.y = -radius;
    }
    
    
    
    
    
    
    private static var hueCircleBitmapData:BitmapData;
    
    public static function resizeHueCircleBitmapData( width:Number ):void {
        
        var centerPoint:Point = new Point( width / 2, width / 2 );
        var tempPoint:Point = new Point();
        
        hueCircleBitmapData = new BitmapData( width, width, false );
        
        hueCircleBitmapData.lock();
        
        for ( var i:int = 0; i < width; i++ ) {
            
            for ( var j:int = 0; j < width; j++ ) {
                
                tempPoint.x = i;
                tempPoint.y = j;
                hueCircleBitmapData.setPixel( i, j, getHueCircleColor( centerPoint, tempPoint ) );
            }
        }
        
        hueCircleBitmapData.unlock();
    }
}


function getHueCircleColor( centerPoint:Point, point:Point ):uint {
    
    var pointFromCenterPoint:Point = point.subtract( centerPoint );
    var pointBearingFromCenterPoint:Number = Math.atan2( pointFromCenterPoint.y, pointFromCenterPoint.x ) * 180 / Math.PI;
    
    if ( pointBearingFromCenterPoint < 0 )
    pointBearingFromCenterPoint = pointBearingFromCenterPoint + 360;
    
    return HSVtoRGB( pointBearingFromCenterPoint, 1, 1 );
}

function HSVtoRGB( h:Number, s:Number, v:Number ):uint {
    
    var Hi:uint = ( h / 60 ) % 6;
    
    var f:Number = h / 60 - Hi;
    
    var p:Number = v * ( 1 - s );
    
    var q:Number = v * ( 1 - f * s );
    
    var t:Number = v * ( 1 - ( 1 - f ) * s );
    
    switch( Hi ) {
        
        case 0:
            return toRGB255( v, t, p );
        
        case 1:
            return toRGB255( q, v, p );
        
        case 2:
            return toRGB255( p, v, t );
        
        case 3:
            return toRGB255( p, q, v );
        
        case 4:
            return toRGB255( t, p, v );
        
        case 5:
            return toRGB255( v, p, q );
    }
    
    return 0;
}


function toRGB255( r:Number, g:Number, b:Number ):uint {
    
    return ( r * 255 << 16 ) + ( g * 255 << 8 ) + b * 255;
}