« インスタンス名を上から連番でつけるJSFL | メイン | 株式会社リンクシンクがFlashでゲーム作れる人募集中 »

WCAN mini AS vol.10 TweensyのEmitter使ってみたよ

del.icio.us it!   hatena bookmark
やりましたよー。

今回はホワイトデーだったのでテーマは白でした。

季節外れぎみだけどなんとなくパーティクルにはまってたので、パーティクルで雪を降らせるような発表をしました。

ただ内容的にはTweensyの使い方でしたけどw

実はシンプルなパーティクルエンジンを作ってて、それを完成させて雪を降らせる予定だったんだけど、全然まったく1ミクロンも間に合わなかったので結局Tweensyに入ってたEmitterってクラスを使ってパーティクルやってみました。

直前にWonderflでプレゼンしたら面白いかなと思って、さくっとプレゼンツールをWonderflで適当にでっち上げてプレゼンしました。実装がひどくてエラーが出てたりしますが。。。



資料は全然中身が無いので、当日の話をここに書きます。

まずはTweensyの使い方。
TweensyってのはTweenerみたいなものです。でもTweenerよりも動作が軽めです。まだ新しいライブラリなのですが、私も1件仕事で使ってみました。



まず簡単なトゥイーン
Tweensy.to - 目的地までのトゥイーン
現在位置からxが200のとこまで1秒かけて、Linear.easeInで移動
Tweensy.to(_c, {x:200}, 1, Linear.easeIn);

Tweensy.from - 現在地までのトゥイーン
xが0の所から、現在位置まで1秒かけて、Linear.easeInで移動
Tweensy.from(_c, {x:0}, 1, Linear.easeIn);

TweensyGroup - トゥイーンのグループ化 (パラレル実行的)
_cを1秒かけてxが100のとこまでと、_bを2秒かけてxが200のとこまで移動して、全部終わったらremoveChild
var tg:TweensyGroup = new TweensyGroup();
tg.to(_c, { x:100}, 1);
tg.to(_b, { x:200}, 2);
tg.onComplete = function():void {
    removeChild(_c);
    removeChild(_b);
}

TweensySequence - トゥイーンを順番に実行(シリアル実行的)
_cを1秒かけてxが100のとこまで移動してから、1秒かけてyが100のとこまで移動する。pushの時の後ろ2つの引数は、それぞれ、実行前の待ち時間(delayStart)と、実行後の待ち時間(delayEnd)
var ts:TweensySequence = new TweensySequence();
ts.push(_c, {x:100}, 1, Cubic.easeIn, 0, 0);
ts.push(_c, {y:100}, 1, Cubic.easeIn, 0, 1);

フィルタのトゥイーン
var gf:GlowFilter = new GlowFilter();
gf.color = 0xFFFFFF;
gf.alpha = 1;

var ts:TweensySequence = new TweensySequence();
ts.push(gf, {blurX:20, blurY:20}, 1, null, 0, 0, _c);
ts.push(gf, {strength:0}, 1, null, 0, 0, _c);
ts.start();

フレームのトゥイーン
hogeのタイムラインを1秒かけて60まで進める。
Tweensy.to(hoge, {currentFrame:60}, 1);


Tweensyにはトゥイーンの他に、いろんなエフェクトが使えるクラスがいろいろあります。その中にEmitterというクラスがあります。Emitterとは出すとか放つ的な意味で、特定のクラスを設定に従って放出することができます。よく言うパーティクルってやつの単純な物です。
クラスのコンストラクタはこんな感じ
Emitter(Particle:Class,
            target:Object = null,
            frequency :int = 5, 1フレームにに出る量
            random:Number = 1, 1だと毎フレーム放出 0.5だと1/2の確率で放出
            angle:Number = 0,360, 出す方向の範囲
            distance:String = "20", 距離 カンマ区切りで範囲指定
            speed:* = 1,早さというか目的地までの秒数
            blendMode:* = normal ブレンドモード
)

使い方はEmitterと描画用のLayer作るだけ

var bmpLayer:BitmapLayer = new BitmapLayer();
// フィルタとか
bmpLayer.add(new FilterEffect(new BlurFilter(5,5)));
bmpLayer.add(new ColorEffect(new ColorTransform(1,1,1,0.9)));

// ParticleはSpriteを継承してdrawRectしてるだけのクラス
var emitter:Emitter = new Emitter(Particle, {alpha:0,scaleX:2, scaleY:2}
,10,0.5, "-180, 180", 200, 2, "add");

bmpLayer.draw(emitter.holder);
//bmpLayer.clearOnRender = true; // 毎フレームクリア フィルタのときは外してる
addChild(bmpLayer);

addEventListener(Event.ENTER_FRAME, function(e:Event):void {
    emitter.x = mouseX;
    emitter.y = mouseY;
});

このコンテンツには最新のFlashPlayerが必要です


雪はこんな感じ。適当でごめんなさい><
このコンテンツには最新のFlashPlayerが必要です
package
{

    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.filters.*;
    import com.flashdynamix.motion.*;
    import com.flashdynamix.motion.effects.core.*;
    import com.flashdynamix.motion.extras.Emitter;
    import com.flashdynamix.motion.layers.BitmapLayer;
    import com.flashdynamix.utils.SWFProfiler;
    import fl.motion.easing.*;

    [SWF(backgroundColor="#000000", frameRage="30")]
    public class TweensyTest2 extends Sprite
    {

        
        public function TweensyTest2()
        {
            addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            SWFProfiler.init(this);

            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.LOW;
            
            var bmpLayer:BitmapLayer = new BitmapLayer();

            var emitter:Emitter = new Emitter(Particle, {scaleX:1, scaleY:1}
                                              ,1,0.5, "90", 1000, 30, "normal");

            bmpLayer.draw(emitter.holder);
            bmpLayer.clearOnRender = true; // 毎フレームクリア
            addChild(bmpLayer);

            var f:Boolean = false;

            addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                emitter.speed =  rangeRandom(10, 25);
                emitter.x = rangeRandom(0, bmpLayer.width);
            });
        }
        public function rangeRandom(max:Number, min:Number):Number {
            return Math.floor(Math.random()*(max-min+1))+min;
        }
        
    }
}


import flash.display.*;

class Particle extends Sprite
{

    public function Particle()
    {
        var g:Graphics = graphics;
        //beginFill(0x0077FF);
        g.beginGradientFill(GradientType.RADIAL,
                          [0xFFFFFF, 0xFFFFFF],
                          [1,0],
                          [0x00, 0x09]
        );
        g.drawCircle(0,0,10);
        g.endFill();

    }
}


Emitterは簡単に使えてよいのだけど、Tweensy自体はパーティクルの為のライブラリではないので、やっぱりちゃんと自分のライブラリを完成させてみよう。
ライブラリの名前は何がいいかな。


Flash Math & Physics Design:ActionScript 3.0による数学・物理学表現[入門編] 集合知プログラミング ビジュアライジング・データ —Processingによる情報視覚化手法 御岳百草丸 1200T

トラックバック

このエントリーのトラックバックURL:
http://un-q.net/mt-tb.cgi/390

コメントを投稿

書いたよ!