パーティクルの勉強2
またまた自分なりにコメントをつけた。
beautifl本のおかげで仕組みがわかった。
1粒1粒にblurをかけてるんじゃなくて、
1pxを拡大してぼかしたようにしてるんだ。
チカチカはpixleの欠落をうまく使って
チカチカしているように見せてるっていう。
まさに匠の技だったのね
/**
* 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;
}
}