papervision3dのParticleFieldをアニメーションさせる。(BetweenAS3.bezierを使ってゆらゆら動かす)

そろそろこのサンプルも終わりにしようかと思うんで、ゆらゆら動く部分の実装を解説しましょうかね。

動作サンプル(重いかもしれないんで別窓で)

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

最終的には上のようなものを作ります。
サンプルファイルは、きちんとクラス作ってますが、一応ココでの解説では、タイムラインコードで示します。
多分コピペすれば動くはず。

んで、このゆらゆら動くアニメーションには、BetweenAS3.bezierというメソッドを使います。
bezierといえば、こんな感じ。あとはここもいい感じの解説があります。

ただし、全てのパーティクルに対して個々にベジェ曲線を設定するわけにもいかんので、ベジェ曲線のコントロールポイントの数とか位置はランダムに取得するようにしたいのです。

//パーティクルのベジェの直径
var dist:int = 500;
//コントロールポイントの最大値、この変数に1を足した数が最大値になる。
var bezierMax:int = 10;
for (var i:int = 0 ; i < len ; i++) {
    //-----------
    //xzの基準位置を取得
    var centerX:int = particleArray[i].x;
    var centerZ:int = particleArray[i].z;
   
    //Tweenの最小値を計算
    var minX:int = centerX - dist / 2;
    var minZ:int = centerZ - dist / 2;
   
    //ベジェのコントロールポイントの数
    var countX:int = (Math.random() * bezierMax) + 2;
    var countZ:int = (Math.random() * bezierMax) + 2;
   
    //ベジェのコントロールポイントを格納する。
    var pointArrayX:Array = new Array();
    var pointArrayZ:Array = new Array();
    //ベジェを格納するオブジェクト
    var pointObj:Object = new Object();
   
    //ベジェのコントロールポイントを算出
    for (var forX:int = 0 ; forX < countX ; forX++) {
        pointArrayX.push( int(Math.random() * dist) + minX );
    }
    for (var forZ:int = 0 ; forZ < countZ ; forZ++) {
        pointArrayZ.push( int(Math.random() * dist) + minZ );
    }
   
    //Tweenの引数用のオブジェクト
    pointObj.x = pointArrayX;
    pointObj.z = pointArrayZ;

    var tweenXZ:IObjectTween = BetweenAS3.bezier(particleArray[i] , { x:centerX , z:centerZ } , null , pointObj , tweenTime , Linear.linear);
}

こんな感じで、bezierメソッドの第4引数にベジェのコントロールポイントを渡すのですが、ここの値はオブジェクト型を渡せばいいので、予めランダムな値の[x , y]というプロパティを持ったオブジェクトを作って、そいつを渡せば、ランダムなベジェ曲線のアニメーションを作ることができます。

その際に

//xzの基準位置を取得
var centerX:int = particleArray[i].x;
var centerZ:int = particleArray[i].z;
   
//Tweenの最小値を計算
var minX:int = centerX - dist / 2;
var minZ:int = centerZ - dist / 2;

こんな感じで、それぞれのプロパティの値を中心にして、コントロールポイントの範囲を決めてやります。

あとは、この処理を前回のエントリーのコードに移植してあげればOK。
てなわけで、タイムラインで動かす場合は下のコードををコピペしてみてくれ。

 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;

//--------------
//パーティクルのベジェの直径
var dist:int = 500;
//コントロールポイントの最大値、この変数に1を足した数が最大値になる。
var bezierMax:int = 10;
//--------------

var delay:Number = 0;
for (var i:int = 0 ; i < len ; i++) {
    particleArray[i].y = 0;
    
    //-----------
    //xzの基準位置を取得
    var centerX:int = particleArray[i].x;
    var centerZ:int = particleArray[i].z;
    
    //Tweenの最小値を計算
    var minX:int = centerX - dist / 2;
    var minZ:int = centerZ - dist / 2;
    
    //ベジェのコントロールポイントの数
    var countX:int = (Math.random() * bezierMax) + 2;
    var countZ:int = (Math.random() * bezierMax) + 2;
    
    //ベジェのコントロールポイントを格納する。
    var pointArrayX:Array = new Array();
    var pointArrayZ:Array = new Array();
    var pointObj:Object = new Object();
    
    //ベジェのコントロールポイントを算出
    for (var forX:int = 0 ; forX < countX ; forX++) {
        pointArrayX.push( int(Math.random() * dist) + minX );
    }
    for (var forZ:int = 0 ; forZ < countZ ; forZ++) {
        pointArrayZ.push( int(Math.random() * dist) + minZ );
    }
    
    //Tweenの引数用のオブジェクト
    pointObj.x = pointArrayX;
    pointObj.z = pointArrayZ;
    //-----------
    
    var tweenY:IObjectTween = BetweenAS3.tween(particleArray[i] , { y:2000} , null , tweenTime , Linear.linear);
    
    //-----------
    var tweenXZ:IObjectTween = BetweenAS3.bezier(particleArray[i] , { x:centerX , z:centerZ } , null , pointObj , tweenTime , Linear.linear);
    //-----------
    
    var tweenXYZ:ITween = BetweenAS3.parallel(tweenY , tweenXZ);
    tweenY.stopOnComplete = false;
 
    delay += 0.5;
   
    var delayTween:ITween = BetweenAS3.delay(tweenXYZ , delay);
    delayTween.play();
   
    particleTweenArray.push(tweenXYZ);
    delayTween.addEventListener(TweenEvent.COMPLETE , tweenCompFunc(i));
}
function tweenCompFunc(index:int):Function {
    return function(e:TweenEvent):void {
        particleTweenArray[index].play();
    }
}

コメントする

トラックバック(0)

このブログ記事を参照しているブログ一覧: papervision3dのParticleFieldをアニメーションさせる。(BetweenAS3.bezierを使ってゆらゆら動かす)

このブログ記事に対するトラックバックURL: http://studio-ensyu.sakura.ne.jp/mt/mt-tb.cgi/31