パーティクルテスト
パーティクルテスト
--- 参考 ---
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;
}
}