Behavior を作ろう


Behavior の作り方について解説します。

作ろう / 作り方 / 戻る / トップページ


Behavior を作ろう

ここでは視点を自由に動かせる Behavior を作ることで Behavior の作り方を説明しようと思います。
 
まず、これから作る Behavior の使い方について説明します。 名前は FreeViewBehavior でコンストラクタに ViewPlatform オブジェクトの親の TransformGroup オブジェクトを指定します。
	TransformGroup transform=universe.getViewingPlatform().getViewPlatformTransform();
	
	Behavior behavior=new FreeViewBehavior(transform);
あとは、通常の Behavior と同様です。 詳しくは こちら をご覧ください。
	BoundingSphere bounds=new BoundingSphere(
		new Point3d(),Double.POSITIVE_INFINITY);	// 範囲を全体にしたい時はこのようにする
	
	behavior.setSchedulingBounds(bounds);
	root.addChild(behavior);
Canvas3D の右側にマウスカーソルを持っていくと右を向き、 左側にマウスカーソルを持っていくと左を向きます。 同じように上下方向にも向きます。 マウスボタンを押すと現在向いている方向に前進します。 右ボタンで後退です。
 
ソースファイル全体は こちらこちら にあります。 私の好みで回転が速めになっていますので、 それがいやな人は適当に改造して使ってください。 このソースファイルはご自由に使って頂いて結構です。

Behavior の作り方

まず、当然ながら Behavior クラスを継承したクラスを作ります。
	public class FreeViewBehavior extends Behavior
コンストラクタも普通のクラスとして作ります。 ただし、その Behavior が動き出すたびに初期化したい処理は initialize() メソッドを定義して、その中に書きます。 initialize() メソッドは Behavior クラスの抽象メソッドですので、 不要でも定義する必要があります。
 
initialize() メソッドではその最後に自分自身の wakeupOn(WakeupCondition criteria) メソッドを呼び出す必要があります。 このメソッドは次回この Behavior が動き出す条件を指定するものです。 その条件を表す引数 criteria は WakeupCondition オブジェクト (実際はそのサブクラスのオブジェクト) です。 WakeupCondition クラスのサブクラス WakeupCriterion クラスのさらにサブクラスは 条件を表します。
	public void initialize()
	{
		// 初期化コード
		
		wakeupOn(new WakeupOnElapsedFrames(0));	// 今から 0 フレーム後 (今のフレームが終わった後) に動いて欲しい
	}
マウスのクリックなど AWT のイベントを条件としたい時は、 WakeupOnAWTEvent クラスを使います。 そのコンストラクタに java.awt.AWTEvent クラスのサブクラス (java.awt.event パッケージ内のクラス) に定義されている そのイベントを表す定数を指定します。
 
WakeupCondition クラスの直接のサブクラスは 複数の条件を組み合わせる時に使います。
	public void initialize()
	{
		WakeupCriterion[] events=new WakeupCriterion[7];
		events[0]=new WakeupOnElapsedFrames(0);
		events[1]=new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
		events[2]=new WakeupOnAWTEvent(MouseEvent.MOUSE_RELEASED);
		events[3]=new WakeupOnAWTEvent(MouseEvent.MOUSE_MOVED);
		events[4]=new WakeupOnAWTEvent(MouseEvent.MOUSE_DRAGGED);
		events[5]=new WakeupOnAWTEvent(MouseEvent.MOUSE_ENTERED);
		events[6]=new WakeupOnAWTEvent(MouseEvent.MOUSE_EXITED);
		
		WakeupCondition mouseCriterion=new WakeupOr(events);	// 上の 7 つの条件のどれか一つでも満たされたら呼んで欲しい
		
		wakeupOn(mouseCriterion);
	}
次に、Behavior の処理を書きます。 Behavior の処理は processStimulus(Enumeration criteria) メソッドに書きます。 このメソッドも Behavior クラスで抽象メソッドとして宣言されて いますので定義する必要があります。
 
その引数 criteria には今回満たされた条件を示す、 WakeupCriterion オブジェクトが列挙型として入っています。 条件を複数指定した場合には criteria から満たされた条件を調べて、 処理を分岐できます。
	public void processStimulus(Enumeration criteria)
	{
		while (criteria.hasMoreElements())
		{
			WakeupCriterion criterion=(WakeupCriterion)(criteria.nextElement());
			
			if (criterion instanceof WakeupOnElapsedFrames)
			{
				// 条件 WakeupOnElapsedFrames で呼ばれた時の処理
			}
			else if (criterion instanceof WakeupOnAWTEvent)
			{
				// 条件 WakeupOnAWTEvent で呼ばれた時の処理
			}
		}
		
		wakeupOn(mouseCriterion);	// 	もう一度呼ぶ
	}
条件に WakeupOnAWTEvent を指定した場合、もう一段階処理が必要です。 WakeupOnAWTEvent オブジェクトの getAWTEvent() メソッドで そのイベントオブジェクトを取得します。
	// 上の「条件 WakeupOnAWTEvent で呼ばれた時の処理」のところに書く
	AWTEvent[] events=((WakeupOnAWTEvent)(criterion)).getAWTEvent();
	
	for (int i=0;i < events.length;i++)
	{
		if (events[i] instanceof MouseEvent)
		{
			MouseEvent event=(MouseEvent)(events[i]);
			
			if (event.getID()==MouseEvent.MOUSE_PRESSED)
			{
				// マウスが押されたときの処理
				// あとは、Listener を使ったときと同じように書ける
			}
		}
	}
最後に、 processStimulus(Enumeration criteria) メソッドの最後に wakeupOn(WakeupCondition criteria) メソッドを再び呼びます。 呼ばない場合、この Behavior は動作を停止してしまいます。 つまり、wakeupOn(WakeupCondition criteria) メソッド呼び出し一回に対して、 processStimulus(Enumeration criteria) メソッドが最高一回呼ばれます。 このとき、先ほどとは違った条件を指定することも可能です。
 
ちなみに、wakeupOn(WakeupCondition criteria) メソッドは 自分自身の initialize() メソッドまたは processStimulus(Enumeration criteria) メソッドの中からのみ 呼び出し可能です。 それ以外のところから呼ぼうとすると例外が発生します。

戻る