Pixel操作を使ったパーティクルの描画

by hacker_szoe51ih forked from forked from: flash on 2010-5-30 (diff: 94)
♥0 | Line 79 | Modified 2010-05-30 23:21:25 | MIT License
play

ActionScript3 source code

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

// forked from hacker_szoe51ih's flash on 2010-5-30
package {
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.geom.ColorTransform;
	import flash.filters.BlurFilter;
	import flash.events.*;
	[SWF(width = 465,height = 465,backgroundColor = 0,frameRate = 60)]

	public class BitmapDataSample11 extends Sprite {

		private var bmpdata:BitmapData;
		private var colortrans:ColorTransform;
		private var filter:BlurFilter;
		private var vectormap:BitmapData;
		private var particles:Array;
		private var particle_number:uint = 10000;
		private var size:Number = 465;

		public function BitmapDataSample11() {
			//Bitmapを作成して表示リストに追加
			bmpdata = new BitmapData(size,size,false,0);//透明ピクセルはサポートしない
			addChild(new Bitmap(bmpdata));
			//DisplayObjectに設定するためのカラーとフィルターを作成
			colortrans = new ColorTransform(0.50,0.69,0.62);
			filter = new BlurFilter(4,4,1);
			//ベクトルマップとパーティクルの初期化
			vectormap = new BitmapData(size,size,false,0);//透明ピクセルはサポートしない
			reset();
			addEventListener(Event.ENTER_FRAME,onEnterFrame);
			stage.addEventListener(MouseEvent.CLICK,reset);

		}

		//リセット処理
		public function reset(e:MouseEvent=null):void {
			var randomSeed:int = Math.random() * 0xFFFFFFFF;
			var colors:uint = BitmapDataChannel.RED | BitmapDataChannel.GREEN;
			vectormap.perlinNoise(size / 2,size / 2,4,randomSeed,false,true,colors);//numOctavesは4,stitchはtrue,fractalNoiseはfalse
			//パーティクルの初期化
			particles = new Array(particle_number);//25000個のパーティクルを格納する為の配列を作成
			for (var i:int = 0; i < particle_number; i++) {
				//ここでパーティクルクラスを使う
				particles[i] = new Particle(Math.random() * size,Math.random() * size);//ここでの引数が最初の表示位置になる
			}
		}

		//パーティクルを動かす
		public function onEnterFrame(e:Event):void {
			//エフェクト適用(フィルターとカラー)  
			bmpdata.applyFilter(bmpdata,bmpdata.rect,bmpdata.rect.topLeft,filter);
			bmpdata.colorTransform(bmpdata.rect,colortrans);
			//パーティクルの描画
			bmpdata.lock();
			for (var i:int = 0; i < particle_number; i++) {
				var p:Particle = particles[i];//配列に入れておいたパーティクルを一個ずつ取り出し、個別の変数に移す
				//ベクトルマップのPixel値から加速度を算出
				var col:uint = vectormap.getPixel(p.x,p.y);
				p.ax += ((col >> 16 & 0xff) - 128 ) * 0.0005;
				p.ay += ((col >> 16 & 0xff) -  128) * 0.0005;
				//加速度から速度と位置を算出
				p.x += p.vx += p.ax;
				p.y += p.vy += p.ay;
				//stageの外に出ないようにする
				if (p.x>size) {
					p.x-=size;
				} else if (p.x<0) {
					p.x+=size;
				}
				if (p.y>size) {
					p.y-=size;
				} else if (p.y<0) {
					p.y+=size;
				}
				
				//Pixelへ描画
				bmpdata.setPixel(p.x,p.y,0x3323ff);
				
				//加速度と速度の減衰
				p.ax*=0.36;
				p.ay*=0.36;
				p.vx*=0.92;
				p.vy*=1.02;
			}
			bmpdata.unlock();
		}
	}
}

//パーティクルクラス
class Particle {
	//初期位置
	public var x:Number;
	public var y:Number;
	//加速度
	public var ax:Number=0;
	public var ay:Number=0;
	//速度
	public var vx:Number=0;
	public var vy:Number=0;

	function Particle(px:Number,py:Number):void {
		x=px;
		y=py;
	}
}

Forked