この記事は半年以上前の情報なので、古い可能性があります
→第6回:何か作りたい(1):よくあるきらきらしたやつ(ソースあり)
→第5回:Classの中身(2):Emitter2Dクラス(調査中)
→第4回:Classの中身(1):Clockクラス(調査中)
→第3回:お勉強(3):パーティクルがよける…Deflectorクラスで障害物
→第2回:お勉強(2):マウスで作る、やめる…Emitter.active
→第1回:お勉強(1):とりあえず何か出来た
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()を関連づけて表示を更新
となっている。
吹雪改。(→前回)
さっきやってみて出来なかった「クリックで生成、再度クリックで停止」ですが、
このやり方が正しいのかはともかく、一応出来た。
※きっともっといい方法があると思います。
追記(1/17)→ありました。emitter.activeでON/OFF簡単にできた。。
//MouseEvent.CLICKに関連づけ
if( !clickflag ){
emitter.active = true;
}else{
emitter.active = false;
}
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);
}
と言う風に数を変えてみた。
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?)→まあ出来た
・