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

パーティクルの勉強2

またまた自分なりにコメントをつけた。

beautifl本のおかげで仕組みがわかった。
1粒1粒にblurをかけてるんじゃなくて、
1pxを拡大してぼかしたようにしてるんだ。

チカチカはpixleの欠落をうまく使って
チカチカしているように見せてるっていう。

まさに匠の技だったのね
Get Adobe Flash player
by umi_kappa 13 Jun 2011
/**
 * Copyright umi_kappa ( http://wonderfl.net/user/umi_kappa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sK6n
 */

// forked from Saqoosha's Snow
package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.MovieClip;
	import flash.display.PixelSnapping;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	public class Main extends MovieClip
	{
		//重力
		private static const GRAVITY:Number = 20;
		
		//一番遅いときのスピード
		private static const DRAG:Number = 0.3;
		
		//パーティクルを描画する
		private var _canvas:BitmapData;
		
		//きらきらを描画する
		private var _glow:BitmapData;
		
		//きらきらをdrawするときに使う
		private var _glowMtx:Matrix;
		
		//フォーカスマップ パーティクルの速度関係
		private var _forceMap:BitmapData;
		
		//パーティクルが入る配列
		private var _snow:Array;
		
		//--------------------------------------------------------------------------
		//
		//  コンストラクタ
		//
		//--------------------------------------------------------------------------
		public function Main() 
		{
                        //フレームレートの設定
                        stage.frameRate = 60;
                        
			// カンバスをつくる。ここに 1 pixel ずつ描いていくよ
			_canvas = new BitmapData(465, 465, false, 0x0);
			addChild(new Bitmap(_canvas));
			
			// キラキラを描く用のん。カンバスの 4 分の 1 のサイズ
			_glow = new BitmapData(465 / 4, 465 / 4, false, 0x0);
			var _bm:Bitmap = new Bitmap(_glow, PixelSnapping.NEVER, true);
			addChild(_bm);
			// 4 倍にする。
			_bm.scaleX = _bm.scaleY = 4;
			// 加算モードで合成
			_bm.blendMode = BlendMode.ADD;
			_glowMtx = new Matrix(0.25, 0, 0, 0.25);
			
			
			// 雪を積もらせるかたちを BitmapData に描く。
			var _tf:TextField = new TextField();
			_tf.defaultTextFormat = new TextFormat("Verdana", 64, 0xffffff, true);
			_tf.autoSize = TextFieldAutoSize.LEFT;
			_tf.text = "umi_kappa";
			_tf.x = (465 - _tf.width) / 2;
			_tf.y = (465 - _tf.height) / 2;
			
			//フォーカスマップ パーティクルの速度関係
			_forceMap = new BitmapData(465, 465, false, 0x0);
			_forceMap.draw(_tf, _tf.transform.matrix);
			_forceMap.applyFilter(_forceMap, _forceMap.rect, new Point(0, 0), new BlurFilter(8, 8));
			
			// 雪パーティクルはここにいれておくよ。
			_snow = [];
			
			addEventListener(Event.ENTER_FRAME, update);
		}
		
		
		//----------------------------------
		//  ENTER_FRAME
		//----------------------------------
		private function update(e:Event):void 
		{
			// いっぱい setPixel するときは必ず lock しよう
			_canvas.lock();
			// カンバスをクリア
			_canvas.fillRect(_canvas.rect, 0x0);
			
			//パーティクルの数
			var n:int = _snow.length;
			//落ちるスピード
			var d:Number;
			// あらかじめ重力を計算しとく
			var gravity:Number = GRAVITY / 1000;
			
			while (n--)
			{
				var p:SnowParticle = _snow[n];
				// まず重力を加える
				p.vy += gravity * p.s;
				// 空気抵抗
				p.vy *= 0.99;
				// forceMap にもとづいて抵抗値を計算。黒→速い、白→遅い。
				d = 1 - (_forceMap.getPixel(p.x, p.y) / 0xffffff) * DRAG;
				// forceMap から得た抵抗値を適用
				p.vy *= d;
				// 動かす
				p.y += p.vy;
				// 雪 1 粒描く
				_canvas.setPixel(p.x, p.y, p.c);
				
				// もし画面外にでちゃったら
				if (p.y > stage.stageHeight) {
					// とりのぞく
					_snow.splice(n, 1);
				}
			}
			
			// lock したやつは必ず unlock
			_canvas.unlock();
			
			// キラキラを描く _glowMtxできらきらの移動量を1/4にしている
			_glow.draw(_canvas, _glowMtx);
			
			// 新規で雪を発生させますよ
			n = 10;
			while (n--) {
				emitParticle(Math.random() * stage.stageWidth, 0, Math.random() + 0.5);
			}
		}
		
		//----------------------------------
		//  雪を 1 粒発生させる関数
		//----------------------------------
		public function emitParticle(ex:Number, ey:Number, s:Number = 1, c:int = 0xffffff, vx:Number = 0, vy:Number = 0):void {
			// 作って
			var p:SnowParticle = new SnowParticle();
			
			// パラメータ設定して
			p.x = ex;
			p.y = ey;
			p.vx = vx;
			p.vy = vy;
			p.s = s;
			p.c = c;
			
			// 保存
			_snow.push(p); 
		}
	}
}

//----------------------------------
//  パーティクル
//----------------------------------
class SnowParticle {
	
	//現在のパーティクルの座標
	public var x:Number;
	public var y:Number;
	
	//毎フレームのパーティクルの移動量
	public var vx:Number;
	public var vy:Number;
	
	//毎フレームのパーティクルが落ちる長さ率
	public var s:Number;
	
	//色
	public var c:int;
	
	public function SnowParticle() {
		this.x = 0;
		this.y = 0;
		this.vx = 0;
		this.vy = 0;
		this.s = 1;
		this.c = 0xffffff;
	}
}