パーティクルクラスを作ってみた
勉強用に自作で作ってみたので公開してみる。4月なので桜の花びらをパーティクルで散らしてみた。使い方はドキュメントクラスに下記のように記述する。
Main.as
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import info.five.filters.Particle;
public class Main extends Sprite
{
private var p:Particle;
//------------------------------
// コンストラクタ
//------------------------------
public function Main():void
{
this.stage.addEventListener(MouseEvent.CLICK, onClick);
//-----[パーティクル]
p = new Particle("flower", this);
p.gravity = -0.2;
p.wind = -0.5;
}
private function onClick(e:MouseEvent):void
{
p.click();
}
}
}
まずはパーティクルインスタンスを作る。第1引数はパーティクルの元となるムービークリップのリンケージ名。第2引数はパーティクルを配置する場所。この場合はステージに配置するのでthisとする。インスタンスを作った後は各パラメータを指定する。gravityはマイナス値でパーティクルが上昇。windはマイナス値で左向きにパーティクルが流れる(0だと円状に広がる)。
p.gravity = -0.2;
p.wind = -0.5;
このサンプルではステージにクリックイベントを登録しているので、リスナー関数の中でp.click()を呼び出すことでクリックタイプのパーティクルを発動することができる。これをp.start()にするとパーティクルが生成され続ける。p.stop()で止める事ができる。
パーティクルクラスはこちら
Particle.as
{
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.utils.getDefinitionByName;
import flash.geom.Point;
public class Particle
{
private var container:DisplayObjectContainer;
private var linkage:String;
private var timer:Timer;
private var xVel:Number;
private var yVel:Number;
private var _vol:Number = 5;
private var _drag:Number = 0.99;
private var _shrink:Number = 0.95;
private var _gravity:Number = 0.8;
private var _fade:Number = 0.02;
private var _wind:Number = 0;
//------------------------------
// コンストラクタ
//------------------------------
public function Particle(s:String, targetContainer:DisplayObjectContainer)
{
linkage = s;
container = targetContainer;
}
//------------------------------
// パーティクルの生成
//------------------------------
private function makeParticle(e:Event):void
{
for (var i:uint = 0; i <_vol; i++)
{
var mc:MovieClip = new(getDefinitionByName(linkage));
container.addChild(mc);
var mouseX:int = container.stage.mouseX;
var mouseY:int = container.stage.mouseY;
var mousePt:Point = new Point(mouseX, mouseY);
var pt:Point = getNearPoint(mousePt);
mc.x = pt.x;
mc.y = pt.y;
mc.xVel = getRandRange( -5, 5);
mc.yVel = getRandRange( -5, 5);
mc.rot = getRandRange( -20, 20);
mc.addEventListener(Event.ENTER_FRAME, onRender);
}
}
//------------------------------
// 指定範囲からランダム値の取得
//------------------------------
private function getRandRange(min:Number, max:Number):Number
{
var randomNum:Number = (Math.random() * (max - min )) + min;
return randomNum;
}
//------------------------------
// 近似ポイント座標の取得
//------------------------------
private function getNearPoint(pt1:Point):Point
{
var len:uint = Math.round(Math.random() * 10);
var angle:uint = Math.round(Math.random() * 2 * Math.PI);
var pt2:Point = Point.polar(len, angle);
pt2.offset(pt1.x, pt1.y);
return pt2;
}
//------------------------------
// スタート
//------------------------------
public function start():void
{
container.stage.addEventListener(Event.ENTER_FRAME, makeParticle);
}
//------------------------------
// ストップ
//------------------------------
public function stop():void
{
container.stage.removeEventListener(Event.ENTER_FRAME, makeParticle);
}
//------------------------------
// クリック
//------------------------------
public function click():void
{
container.stage.addEventListener(Event.ENTER_FRAME, makeParticle);
timer = new Timer(300, 1);
timer.addEventListener(TimerEvent.TIMER, onDelay);
timer.start();
}
private function onDelay(e:TimerEvent):void
{
container.stage.removeEventListener(Event.ENTER_FRAME, makeParticle);
timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onDelay);
}
//------------------------------
// レンダー
//------------------------------
private function onRender(e:Event):void
{
var mc:MovieClip = e.target as MovieClip;
if (mc.alpha> 0)
{
mc.x += mc.xVel + _wind * 10;
mc.y += mc.yVel;
mc.xVel *= _drag;
mc.yVel *= _drag;
mc.scaleX *= _shrink;
mc.scaleY *= _shrink;
mc.yVel += _gravity;
mc.alpha -= _fade;
mc.rotation += mc.rot;
}
else
{
mc.removeEventListener(Event.ENTER_FRAME, onRender);
mc.removeChildAt(0);
container.removeChild(mc);
mc = null;
}
}
//------------------------------
// getter setter
//------------------------------
public function get vol():Number { return _vol; }
public function set vol(value:Number):void {
_vol = value;
}
public function get drag():Number { return _drag; }
public function set drag(value:Number):void {
_drag = value;
}
public function get shrink():Number { return _shrink; }
public function set shrink(value:Number):void {
_shrink = value;
}
public function get gravity():Number { return _gravity; }
public function set gravity(value:Number):void {
_gravity = value;
}
public function get fade():Number { return _fade; }
public function set fade(value:Number):void {
_fade = value;
}
public function get wind():Number { return _wind; }
public function set wind(value:Number):void {
_wind = value;
}
}
}
不具合があれば、指摘していただけると嬉しいです。
