forked from: Snow
forked from Snow (diff: 15)
http://wonderfl.net/code/71344f9a655053d9f793a32c68f00921c67f1977 からお勉強。 理解したところにコメント付け加え。 文字の部分に吸着された訳じゃなくて文字の部分はすごい抵抗を受けてるから落下速度が遅くなって留まるように見えるのね。 フレームレート高いなぁ。
ActionScript3 source code
/**
* Copyright k2syndrome_g ( http://wonderfl.net/user/k2syndrome_g )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5TOB
*/
// forked from Saqoosha's Snow
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.PixelSnapping;
import flash.display.Sprite;
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;
import net.hires.debug.Stats;
[SWF(width=465, height=465, backgroundColor=0x0, frameRate=120)]
public class Saq001 extends Sprite {
private static const GRAVITY:Number = 20;//重力
private static const DRAG:Number = 0.3;//粘度のようなものか
private var _canvas:BitmapData;
private var _glow:BitmapData;
private var _glowMtx:Matrix;
private var _forceMap:BitmapData;
private var _snow:Array;
public function Saq001() {
this._canvas = new BitmapData(465, 465, false, 0x0); // カンバスをつくる。ここに 1 pixel ずつ描いていくよ
this.addChild(new Bitmap(this._canvas)) as Bitmap; // stage に配置
this._glow = new BitmapData(465 / 4, 465 / 4, false, 0x0); // キラキラを描く用のん。カンバスの 4 分の 1 のサイズ
var bm:Bitmap = this.addChild(new Bitmap(this._glow, PixelSnapping.NEVER,true)) as Bitmap; // smoothing を true にして配置
bm.scaleX = bm.scaleY = 4; // 4 倍にする。
bm.blendMode = BlendMode.ADD; // 加算モードで合成
this._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 = 'BRAND\nNEW\nWORLD';
tf.x = (465 - tf.width) / 2;
tf.y = (465 - tf.height) / 2;
this._forceMap = new BitmapData(465, 465, false, 0x0);//つもらせる型のBitmapData。サイズはカンバスと一緒
this._forceMap.draw(tf, tf.transform.matrix);//drawしたときにtfのtransform情報も適用するためにmatrixも指定する
this._forceMap.applyFilter(this._forceMap, this._forceMap.rect, new Point(0, 0), new BlurFilter(8,8));//文字につもった感を見せるために文字をブラーして幅を広げとく
this._snow = []; // 雪パーティクルはここにいれておくよ。
this.addChild(new Stats());//使用メモリ表示のStats
this.addEventListener(Event.ENTER_FRAME, this.update); // 毎フレーム update を呼ぶよ
}
// 雪を 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;
this._snow.push(p); // 保存
}
// 雪を動かすよーー
public function update(e:Event):void {
this._canvas.lock(); // いっぱい setPixel するときは必ず lock しよう
this._canvas.fillRect(this._canvas.rect, 0x0); // カンバスをクリア(黒で塗りつぶす)
var n:int = this._snow.length;//制御しなきゃならない雪の数
var d:Number;//文字の方の部分で受ける抵抗
var gravity:Number = GRAVITY / 1000; // あらかじめ計算しとく
while (n--) {
var p:SnowParticle = this._snow[n];
p.vy += gravity * p.s; // まず重力を加える
p.vx *= 0.99; // 空気抵抗
p.vy *= 0.99; // y 方向にも
d = 1 - (this._forceMap.getPixel(p.x, p.y) / 0xffffff) * DRAG; // forceMap にもとづいて抵抗値を計算。黒→速い、白→遅い。
p.vx *= d; // forceMap から得た抵抗値を適用
p.vy *= d; // y 方向にも
p.x += p.vx; // 動かす
p.y += p.vy;
this._canvas.setPixel(p.x, p.y, p.c); // 雪 1 粒描く
if (p.y > this.stage.stageHeight) { // もし画面外にでちゃったら
this._snow.splice(n, 1); // とりのぞく
}
}
this._canvas.unlock(); // lock したやつは必ず unlock
this._glow.draw(this._canvas, this._glowMtx); // キラキラを描く
// 雪を発生させますよ
n = 10;//10個分
while (n--) {
this.emitParticle(Math.random() * this.stage.stageWidth, 0, Math.random() + 0.5,0xffffff,2*(Math.random()-0.5));//x=ランダム、y=0、s=0.5〜1.5
}
}
}
}
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;
}
}