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

パーティクルテスト

パーティクルテスト

--- 参考 ---
ClockMaker Blog - wonderflのパーティクル祭をグラフにしてみたよ
http://clockmaker.jp/blog/2009/04/particle_fes/

beinteractive - forked from: 10万個ぱーてぃくる - 軽く高速化
http://wonderfl.net/code/6efe4c0d9b5e27e91db92b1175409f31e7005dca

@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/xLkX
 */

// 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="60")] 
    /**
     * パーティクルテスト
     * 
     * --- 参考 ---
     * ClockMaker Blog - wonderflのパーティクル祭をグラフにしてみたよ
     * http://clockmaker.jp/blog/2009/04/particle_fes/
     * 
     * beinteractive - forked from: 10万個ぱーてぃくる - 軽く高速化
     * http://wonderfl.net/code/6efe4c0d9b5e27e91db92b1175409f31e7005dca
     * 
     * @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_SEED:uint = 0;
        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, -32, -16, -16);
        
        
        
        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 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() );
            
            
            // 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 );
            
            
            
            // debug
            forceMapBitmap = new Bitmap( forceMapBitmapData );
            forceMapBitmap.scaleX = 0.2 * Math.pow( 2, FORCE_MAP_SCALE );
            forceMapBitmap.scaleY = 0.2 * Math.pow( 2, FORCE_MAP_SCALE );
            forceMapBitmap.x = stageWidth - forceMapBitmap.width;
            addChild( forceMapBitmap );
            
            
            
            if( !FORCE_MAP_CREATE_BY_ENTER_FRAME )
                forceMapBitmapData.perlinNoise( stageHeight >> ( FORCE_MAP_SCALE + 1 ), stageHeight >> ( FORCE_MAP_SCALE + 1 ), NUM_OCTAVES, FORCE_MAP_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, FORCE_MAP_SEED, true, true, 3, false, offsets );
                forceMapBitmapData.unlock();
            }
            
            
            
            var particle:Particle = particles;
            var color:uint;
            
            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;
                
                
                if ( !FRAME_SKIP_DRAW_PARTICLE || ( FRAME_SKIP_DRAW_PARTICLE && !frameSkipper.skip ) )
                    viewBitmapData.setPixel( particle.x, particle.y, 0xffffff );
            }
            
            viewBitmapData.unlock();
        }
    }
}



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


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;
    }
}