私は単純な 2D ゲーム エンジンをプログラミングしています。エンジンをどのように機能させるかを決めました。エンジンは、必要に応じてメインのゲーム ループがトリガーする「イベント」を含むオブジェクトで構成されます。
構造についてもう少し: すべてGameObject
にはupdateEvent
メソッドがあります。
objectList
更新イベントを受け取るすべてのオブジェクトのリストです。このリストにあるオブジェクトだけが、ゲーム ループによって updateEvent メソッドが呼び出されます。
このメソッドを GameObject クラスに実装しようとしています (この仕様は、メソッドで達成したいものです) :
/**
* This method removes a GameObject from objectList. The GameObject
* should immediately stop executing code, that is, absolutely no more
* code inside update events will be executed for the removed game object.
* If necessary, control should transfer to the game loop.
* @param go The GameObject to be removed
*/
public void remove(GameObject go)
そのため、オブジェクトが更新イベント内で自身を削除しようとすると、制御がゲーム エンジンに戻されます。
public void updateEvent() {
//object's update event
remove(this);
System.out.println("Should never reach here!");
}
これが私がこれまでに持っているものです。それは機能しますが、フロー制御に例外を使用することについて読めば読むほど気に入らなくなるので、代替手段があるかどうかを確認したいと思います。
メソッドの削除
public void remove(GameObject go) {
//add to removedList
//flag as removed
//throw an exception if removing self from inside an updateEvent
}
ゲームループ
for(GameObject go : objectList) {
try {
if (!go.removed) {
go.updateEvent();
} else {
//object is scheduled to be removed, do nothing
}
} catch(ObjectRemovedException e) {
//control has been transferred back to the game loop
//no need to do anything here
}
}
// now remove the objects that are in removedList from objectList
2 つの質問:
上記の remove メソッドの stop-right-away 部分を実装する唯一の方法は、カスタム例外をスローしてゲーム ループでキャッチすることであると想定するのは正しいですか? (フロー制御に例外を使用するのは goto のようなものですが、これは悪いことです。自分がやりたいことを行う別の方法が思い浮かびません!)
リスト自体からの削除では、1 つのオブジェクトがリストのさらに下にあるオブジェクトを削除することができます。現在、コードを実行する前に削除済みフラグをチェックしており、各パスの最後にオブジェクトを削除して同時変更を回避しています。これを行うためのより良い、できればインスタント/非ポーリングの方法はありますか?
[編集] あなたの回答を読んだ後、メソッドの仕様を変更すると思います。インスタント削除の動作は、私が別のエンジンでの作業に慣れているものですが、その通りです。Java の動作に実際には適合しません。ちょっと違う考え方を頭に入れてみよう!