→第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()を関連づけて表示を更新
となっている。
Deflector(障害物)を設定すると、パーティクルの流れを邪魔できる。
Deflectorクラスは、この順番で登録する。
//読み込むクラス(円形の障害物) import idv.cjcat.stardust.twoD.deflectors.CircleDeflector; //…(略)… //半径50の障害物(円)作成 private var circleDeflector:CircleDeflector = new CircleDeflector(0, 0, 50); //…(略)… //デフレクター(障害物)の設定 circleDeflector.bounce = 0;//障害物に当たった時のはねかえり係数 var deflect:Deflect = new Deflect(); deflect.addDeflector( circleDeflector);//デフレクターに円を追加 emitter.addAction(deflect);//エミッターに追加
もちろん、この障害物には色や形がついているわけではないので、
傘のシンボルをfla側で作成し、Umbrellaクラスにしておいた。

あとは、マウスの動きに合わせて、デフレクターと傘を同じ動きにしただけ。
//マウスを動かした時の処理(deflector)
stage.addEventListener(MouseEvent.MOUSE_MOVE, follow);
//マウスを追いかける
protected function follow(e:MouseEvent):void {
circleDeflector.x = umbrella.x = root.mouseX;
circleDeflector.y = umbrella.y = root.mouseY;
if (e) e.updateAfterEvent();
}
しかし動き重い。core2duo/E6600で52/60FPSくらい。これじゃちょっときつい。
//Raindrop3.as(snowじゃないじゃんってつっこまんといて)
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.*;
import idv.cjcat.stardust.twoD.deflectors.CircleDeflector;
public class Raindrops3 extends Sprite {
private var emitter:Emitter2D;
private var renderer:Renderer;
private var clock:SteadyClock =new SteadyClock(5);
private var clickflag:Boolean = false;
private var circleDeflector:CircleDeflector = new CircleDeflector(0, 0, 50);//半径50の障害物(円)作成
private var umbrella:Umbrella = new Umbrella();//flaのライブラリの中のシンボル
private var mc:MovieClip = new MovieClip();
public function Raindrops3() {
mc.x=mc.y=0;
addChild(mc);
addChild( umbrella );
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);
//デフレクター(障害物)の設定
circleDeflector.bounce = 0;//障害物に当たった時のはねかえり係数
var deflect:Deflect = new Deflect();
deflect.addDeflector( circleDeflector);//デフレクターに円を追加
emitter.addAction(deflect);//エミッターに追加
stage.addEventListener(MouseEvent.CLICK, startParticle);
//マウスを動かした時の処理(deflector)
stage.addEventListener(MouseEvent.MOUSE_MOVE, follow);
}
private function startParticle( e:MouseEvent ):void {
if( !clickflag ){
clock.ticksPerCall = 8;
clickflag = true;
}else{
clock.ticksPerCall = 0;
clickflag =false;
}
addEventListener(Event.ENTER_FRAME, loop);
}
private function loop(e:Event):void {
emitter.step();
}
//マウスを追いかける
protected function follow(e:MouseEvent):void {
circleDeflector.x = umbrella.x = root.mouseX;
circleDeflector.y = umbrella.y = root.mouseY;
if (e) e.updateAfterEvent();
}
}
}
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?)→とりあえず出来た
・表示が重いのでもっと軽く。