Haxe + CreateJs で ParticleEmitterJS を試してみました


ちょっと前に話題になってた ParticleEmitterJS を Haxe + CreateJs + Sublime Text2 で試してみました。
ParticleEmitterJS については、Clockmaker さんの記事にゃあプロジェクトさんの記事 で紹介されています。

で、これを Haxe でやろうとしたところ…
Haxe で ParticleEmitterJS をどうやって使うのかがわからないじゃないですかw

リファレンスをみてみると「extern クラス」を使えと書いてあったので、こりゃめんどいなーと思いながらも extern クラスを作ろうとしたのですが、もうちょっとググってみると…

クラスメソッドのブログで Taiga さんの記事 を見つけました。

こちらに ParticleEmitterJS の extern クラスが用意されていたので、これを参考にしてやってみると…

こんなのができました。

particle test

画像クリックで別ウィンドウが開きます

これ、基本的には参考記事に記載されていたコードとそれほど変わらないんですが、今回のテストでは Haxe 3.0 を使用しているため、Haxe の js の API が多少変更になっています。 http://haxe.org/manual/haxe3/migration

今回のサンプルに影響した API の変更は、js.Lib にあった window が js.Browser へ変更、js.Dom にあった Image が js.html へ変更でした。

記事中のサンプルから上記 API を変更してパーティクルの設定を変えてみた下記のコードが今回のサンプルのコードになります。

package;
 
import createjs.easeljs.Stage;
import createjs.easeljs.Point;
import createjs.easeljs.Ticker;
import createjs.ParticleEmitterType;
import createjs.ParticleEmitter;
import createjs.ParticleEmitterState;
import js.Browser;
import js.html.Image;

class Main {
 
    private var stage:Stage;
 
    private var particleImage:Image;
 
    private var emitter:ParticleEmitter;
 
    private var rad:Float = 0;
 
    public static function main():Void 
    {
        new Main();
    }
 
    public function new() 
    {
        Browser.window.onload = initHandler;
    }
 
    private function initHandler(_):Void 
    {
        particleImage = untyped __js__("new Image()");
        particleImage.onload = initCanvas;
        particleImage.src = "images/particle_base.png";
    }
 
    private function initCanvas(_):Void 
    {
        stage = new Stage(cast Browser.document.getElementById("canvas"));
        stage.compositeOperation = "lighter";
 
        handleResize(null);
        Browser.window.onresize = handleResize;
 
        Ticker.setFPS(60);
        Ticker.useRAF = true;
        Ticker.addListener(update);
 
        var canvas:Dynamic = stage.canvas;
        addParticleEmitter(canvas.width * 0.5, canvas.height * 0.5);
    }
 
    
    private function addParticleEmitter( x, y ):Void 
    {
        emitter = new ParticleEmitter( particleImage );
        emitter.position = new Point( x, y );
        emitter.emitterType = createjs.ParticleEmitterType.Emit;
        emitter.emissionRate = 100;
        emitter.maxParticles = 150;
        emitter.life = 600;
        emitter.lifeVar = 0;
        emitter.speed = 80;
        emitter.speedVar = 0;
        emitter.positionVarX = 0;
        emitter.positionVarY = 0;
        emitter.accelerationX = 0;
        emitter.accelerationY = 0;
        emitter.radialAcceleration = 0;
        emitter.radialAccelerationVar = 0;
        emitter.tangentalAcceleration = 0;
        emitter.tangentalAccelerationVar = 0;
        emitter.angle = 0;
        emitter.angleVar = 90;
        emitter.startSpin = 0;
        emitter.startSpinVar = 0;
        emitter.endSpin = null;
        emitter.endSpinVar = null;
        emitter.startColor = [127, 255, 255];
        emitter.startColorVar = [127, 127, 127];
        emitter.startOpacity = 1;
        emitter.endColor = null;
        emitter.endColorVar = null;
        emitter.endOpacity = null;
        emitter.startSize = 75;
        emitter.startSizeVar = 0;
        emitter.endSize = 20;
        emitter.endSizeVar = 0;
        stage.addChild( emitter );
    }
 
    private var r:Float = 0;
    private var n:Int = 1;
    private function update():Void 
    {
        stage.update();
        var window:Dynamic = Browser.window;
        var cx:Float = window.innerWidth * 0.5;
        var cy:Float = window.innerHeight * 0.5;
        
        var dx:Float = Math.sin(rad) * r + cx;
        var dy:Float = Math.cos(rad) * r + cy;

        if( emitter != null ) {
            emitter.position = new Point( dx, dy );
        }

        rad += 0.05;
        
        if( r < 10 )
        {
            if( n < 0 ) n = 1;
        }

        if( r > 300 )
        {
            if( n > 0 ) n = -1;
        }

        r += n * ( 1 - r * 0.001 );

    }
 
    private function handleResize(_):Void 
    {
        var canvas:Dynamic = stage.canvas;
        var window:Dynamic = Browser.window;
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        if(emitter != null) 
        {
            emitter.position = new Point(canvas.width * 0.5, canvas.height * 0.5);
        }
    }
}

というわけで…
今回学んだことは「js の外部ライブラリを使いたい場合、extern クラスをつくらないといけないってのがちょっとめんどくさそう」でしたw