beTweenAS3: 2009年11月アーカイブ

似たような事をやってる人が見当たんなかったんで(wonderflをくまなく探せばそういう人もいるかもしれませんが・・・)。
まぁでもなんとかなるだろうということで、オフシャルのドキュメントと、ソースコードを読みながらやってみました。

そしてできたものがこれです。(重いかもしれないんで別窓で)

サンプルファイル一式(Flash CS4形式)

それにしても、こうしてAdobe公式のリファレンスと体裁を同じくしてくれると楽でいいですね。
英語ほとんど分りませんが、こういう形式にしてもらえると、変数・戻り値・引数の型を見ればなんとなくわかりますからね。

ちなみに、Papervision3Dの使い方に関しては、こちらのブログが詳しいです。
今回Papervision3Dのバージョンは2.1 rev920を使います。
また、アニメーション時のTweenライブラリに、BetweenAS3を利用します。使用するバージョンはAlpha r3022です。
それぞれダウンロードしてクラスパスを通すか、Flaファイルと同一階層に[org]以下を入れて作業してください。

そんなこんなで本題に入ります。

ParticleFieldに関してはいろんなところで紹介されているので詳細は省きますが、指定した数分だけ、パーティクルをランダムに指定したエリアに配置してくれるという便利なクラスです。

使い方はこのサイトがわりとシンプルに解説してくれていますね。

要は、[ParticleFieldクラス]のインスタンスを、Papervision3DのsceneにaddChildしてあげればいいわけですね。

ちなみに、こんな風になります。

ParticleFieldは、第一引数に、パーティクルのマテリアルを受け取りますが、たいていのチュートリアルでは[ParticleMaterialクラス]のインスタンスを渡しています。
このクラスは、指定された色とサイズの正方形をパーティクルの素材にするようです。

ただ、できれば自分で作った素材を使いたいものです。
そうしてドキュメントをたぐっていったら、[ParticleMaterialクラス]のサブクラスに[BitmapParticleMaterial][MovieAssetParticleMaterial]というのがあるじゃないですか。

[BitmapParticleMaterialクラス]はパーティクルマテリアルのソースにBitmapDataを、[MovieAssetParticleMaterialクラス]は、リンケージさせたインスタンスをそれぞれ指定できるようです。
しかもインスタンスを指定する場合、アニメーションさせることも可能らしい。

てな訳で、ちょいと光ってるグラフィックを作って"test"という名前でリンケージさせて

var mf:MovieAssetParticleMaterial = new MovieAssetParticleMaterial("test");
var fld:ParticleField = new ParticleField(mf , 200 , 1);

 こうします。
すると指定したグラフィックで、200個のパーティクルを、指定した大きさでランダムに配置します。
ちなみに、サイズの部分に引数を渡さない場合、幅、高さ、奥行きはデフォルト値の2000になります。

さて、問題はここからです。

ここまでできれば、後はこれらのパーティクル一個一個をbeTweenAS3でTweenさせてやればいい。
beTweenAS3のパフォーマンスならば、200個程度きっと軽々さ!?

でもどうやってパーティクル一個一個を取得するんだろう?

そうしてまた、ドキュメントをたぐって[particles]というパラメータを発見、さすがにドキュメントだけでは分らなかったので、幾つかのサイトを見たら、どうやら画面に配置したパーティクルを格納した配列らしい。

[ParticleFieldクラスの]親クラスである[Particlesクラス]を見てみると[addParticle(particle:Particle):void]なんてのがあって、最終的には[particles]には[Particleクラス]のインスタンスの配列になるっぽい。

てことで、「particles[i].x」とか書けば、見事パーティクル一個一個の座標を操作できる。

var tweenTime:int = 10;
var particleArray:Array = fld.particles;
var len:int = particleArray.length;
for (var i:int = 0 ; i < len ; i++) {
    //パーティクルの位置を一番下に
    particleArray[i].y = 0;
    var tweenY:IObjectTween = BetweenAS3.tween(particleArray[i] , { y:fld.fieldHeight} , null , tweenTime , Linear.linear);
    tweenY.stopOnComplete = false;
    tweenY.play();
}

で、各パーティクルは、下から上までアニメーションします。
beTweenAS3に関してはコチラとかが分りやすいです。
あとは、にゃあプロジェクトさんが、色々とやってるようです。

ちなみに上記コードは、particleArray[i]のyに0を入れた後、beTweenAS3で0~fld.fieldHeight「フィールドの高さ、つまり一番上」まで、等速で10秒のアニメーションをさせます。

tweenY.stopOnComplete = false;

[stopOnComplete]はその名の通り、アニメーションが終了したらstopするか?
の設定なので、trueで一回きり、falseでリピートになります。これで、個々のパーティクルを下から上にリピート再生させることができました。

ただし、このままだと全てのパーティクルが、一斉に動き出した上に動きも全く一緒です。
なので、アニメーションの開始をずらして、さらには、もっとランダムっぽい曲線的な動きとかを入れたいし、あとは開始点と終了点で違和感なく消えてもらいたいですね。

もういい加減眠いので、アニメーションのブラッシュアップ部分は次回に回します。

ちなみに、今回の全コード

import org.papervision3d.view.BasicView;
import org.papervision3d.materials.special.MovieAssetParticleMaterial;
import org.papervision3d.objects.special.ParticleField;
import org.papervision3d.cameras.CameraType;

import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.Linear;
import org.libspark.betweenas3.events.TweenEvent;
import org.libspark.betweenas3.tweens.IObjectTween;
import org.libspark.betweenas3.tweens.ITween;


var world:BasicView = new BasicView(640 , 320 , true , false , CameraType.DEBUG);
var particleTweenArray:Array = new Array();

var mf:MovieAssetParticleMaterial = new MovieAssetParticleMaterial("test");
mf.smooth = true;

var fld:ParticleField = new ParticleField(mf , 200 , 1);

stage.addChild(world);
world.scene.addChild(fld);

world.startRendering();

fld.y = -500
world.camera.zoom = 50;

var tweenTime:int = 10;
var particleArray:Array = fld.particles;
var len:int = particleArray.length;
for (var i:int = 0 ; i < len ; i++) {
    //パーティクルの位置を一番下に
    particleArray[i].y = 0;
    var tweenY:IObjectTween = BetweenAS3.tween(particleArray[i] , { y:2000} , null , tweenTime , Linear.linear);
    tweenY.stopOnComplete = false;
    tweenY.play();
}

プロフィール

HN.NoBody

NoBody

市ヶ谷のとあるオフィスでFlashクリエイターとして労役中。
なんとなくチーフ。

twitterでつぶやき中