我正在编写一个简单的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,这很糟糕。我只是想不出另一种方法来做我想做的事!)
对于从列表本身中删除, 可能是一个对象删除列表中较远的一个对象。目前我在执行任何代码之前检查已删除的标志,并在每次传递结束时删除对象以避免并发修改。是否有更好的,最好是即时/非轮询的方式来做到这一点?
[编辑] 的 在阅读完答案后,我想我会改变方法规范。我已经习惯在不同的引擎中使用即时删除行为,但你是对的,它并不真正适合Java的工作方式。是时候试着用一种略微不同的思维方式包围我的脑袋了!
答案 0 :(得分:2)
我同意异常方法是根据您的规范实现remove方法的最佳方法。
但是,也许您应该重新考虑规范。我会留下updateEvent何时终止到实现者的决定。使用remove()调用终止会令人困惑,并且需要使用流控制的异常。我相信对remove()的调用应该只改变标志状态。我发现循环遍历所有对象并没有真正的问题,检查每个对象的删除标志。
答案 1 :(得分:1)
为什么不简单地返回,即
public void updateEvent() {
//object's update event
remove(this);
return;
//obviously unreachable
System.out.println("Should never reach here!"); }
答案 2 :(得分:1)
你为什么不:
答案 3 :(得分:1)
@ jball的答案很棒 - +1。
我使用的另一种方法效果很好,可能稍微清晰一点就是让你的updateEvent()方法返回一个布尔值。每当从updateEvent返回True时,就删除()对象。
这允许您的事件循环可以更好地控制循环本身的执行方式,并删除类之间的一些不必要的绑定。