AS3のオープンソースライブラリ「stardust」でパーティクルをお勉強(2)

2010年01月15日  投稿者:ハセガワ
クリックでパーティクル生成を止める、がやっと出来た。
ブックマークする:

進行状況

→第6回:何か作りたい(1):よくあるきらきらしたやつ(ソースあり)
→第5回:Classの中身(2):Emitter2Dクラス(調査中)
→第4回:Classの中身(1):Clockクラス(調査中)
→第3回:お勉強(3):パーティクルがよける…Deflectorクラスで障害物
→第2回:お勉強(2):マウスで作る、やめる…Emitter.active
→第1回:お勉強(1):とりあえず何か出来た

パーティクルを生成する手順(2D)

stardustを使ってパーティクルを作るための基本的な順番は、公式マニュアルによると

(1)Clockを作る…パーティクル発生の頻度
(2)Emitterを作ってclockをセット…エミッターって発生装置みたいなもの(?)
(3)Rendererを作る…画面表示用オブジェクト(?)
(4)Renderer.addEmitter( Emitter )でエミッターをレンダラーにセット
(5)Emitter.addInitializer( 発生場所とか発生させるspiteとか )でエミッターを初期設定
(6)Emitter.addAction( 寿命の長さとか重力とか )で実際の動きを設定
(7)Event.ENTER_FRAMEやTimerEvent.TIMERに、Emitter.step()を関連づけて表示を更新

となっている。

クリックで生成と停止を切り替える

吹雪改。(→前回

FlashPlayerをインストールするか、JavaScriptをONにしてください。

さっきやってみて出来なかった「クリックで生成、再度クリックで停止」ですが、
このやり方が正しいのかはともかく、一応出来た。
※きっともっといい方法があると思います。 

追記(1/17)→ありましたemitter.activeでON/OFF簡単にできた。。

//MouseEvent.CLICKに関連づけ
if( !clickflag ){
				emitter.active = true;
			}else{
				emitter.active = false;
			}

パーティクルの生成数を決めるインスタンス<SteadyClock>

SteadyClockクラスは、発生ステップ(emitter.step())ごとに決まった数のパーティクルを生成する。

var clock:SteadyClock =new SteadyClock(5);
…
emitter=new Emitter2D(clock);

で、
step()がEvent.ENTER_FRAMEに関連付いているなら、1frameごとに5個のパーティクルを発生させる。
ということはこれが0なら発生しない。
SteadyClockにはticksPerCallというプロパティが用意されているので、

var clock:SteadyClock =new SteadyClock(5);
private function startParticle( e:MouseEvent ):void {
			if( !clickflag ){// falseなら
				clock.ticksPerCall = 5;//パーティクルを1フレごとに5個作る
				clickflag = true;
			}else{//trueなら
				clock.ticksPerCall = 0;//パーティクルは0;
				clickflag =false;
			}
			addEventListener(Event.ENTER_FRAME, loop);
		}
と言う風に数を変えてみた。
なんかこう、「stop」とかあるんじゃないかと探してるんだけどないのでこうしてみた。

サンプルソース
 
package {
	import flash.display.*;
	import flash.events.*;
	import idv.cjcat.stardust.common.actions.*;
	import idv.cjcat.stardust.common.clocks.*;
	import idv.cjcat.stardust.common.emitters.*;
	import idv.cjcat.stardust.common.renderers.*;
	import idv.cjcat.stardust.common.initializers.*;
	import idv.cjcat.stardust.common.math.*;
	import idv.cjcat.stardust.twoD.actions.*;
	import idv.cjcat.stardust.twoD.fields.*;
	import idv.cjcat.stardust.twoD.emitters.*;
	import idv.cjcat.stardust.twoD.initializers.*;
	import idv.cjcat.stardust.twoD.zones.*;
	import idv.cjcat.stardust.twoD.renderers.*;

	public class Raindrops extends Sprite {
		private var emitter:Emitter2D;
		private var renderer:Renderer;
		public var clock:SteadyClock =new SteadyClock(5);
		public var clickflag:Boolean = false;//パーティクル生成状態判定用

		public function Raindrops() {
			var mc:MovieClip = new MovieClip();
			mc.x=mc.y=0;

			addChild(mc);

			emitter=new Emitter2D(clock);
			renderer=new DisplayObjectRenderer(mc);
			renderer.addEmitter(emitter);
			emitter.addInitializer(new DisplayObjectClass(MyCircle));
			emitter.addInitializer(new Velocity(new LazySectorZone(0.01, 0)));
			emitter.addInitializer(new Life(new UniformRandom(100, 5)));
			emitter.addInitializer(new Position(new Line( -100, 600, 0, 0 )));
			emitter.addAction(new Age());
			emitter.addAction(new DeathLife());
			emitter.addAction(new Accelerate(0.2));
			emitter.addAction(new Move());
			emitter.addAction(new ScaleCurve(1,7));

			var bmpField :BitmapField = new BitmapField();
			bmpField.max=0.1;
			bmpField.massless=false;
			bmpField.scaleX=bmpField.scaleY=10;

			var gravity:Gravity = new Gravity();
			gravity.addField(bmpField);
			gravity.addField(new UniformField( 0.2, 0.1));

			emitter.addAction(gravity);

			stage.addEventListener(MouseEvent.CLICK, startParticle);

		}
		// clickflagによって処理を振り分け
		private function startParticle( e:MouseEvent ):void {
			if( !clickflag ){// falseなら
				clock.ticksPerCall = 5;//パーティクルを1フレごとに5個作る
				clickflag = true;
			}else{//trueなら
				clock.ticksPerCall = 0;//パーティクルは0;
				clickflag =false;
			}
			addEventListener(Event.ENTER_FRAME, loop);
		}
		// エンターフレームイベント
		private function loop(e:Event):void {
			emitter.step();
		}
	}
}
import flash.display.*;
class MyCircle extends Sprite {
	public function MyCircle() {
		var colorType:uint=0xffffff;
		var snowSize:int=Math.random()*2+1;
		graphics.beginFill( colorType , 1 );
		graphics.drawCircle(snowSize,snowSize,snowSize);
	}
}
できなかったこと、やりたいこと。

・パーティクル生成中にステージクリックでパーティクル生成ストップ(stopとかあるかと思ってたけどなかった)引き続きもっとスマートなやり方を探索中
傘を表示させて、それにあたると雪が跳ね返る(deflect?)→まあ出来た

僕が買った、もしくは買う予定の参考書
ブックマークする
FlaTech+を購読する
  • 全記事を含むRSSfeed
  • このページをブックマーク: