代码之家  ›  专栏  ›  技术社区  ›  KyleSolo

Java流量控制问题

  •  0
  • KyleSolo  · 技术社区  · 16 年前

    我正在编程一个简单的二维游戏引擎。我已经决定了我希望引擎如何工作:它将由包含“事件”的对象组成,我的主游戏循环将在适当的时候触发这些对象。

    关于结构的更多信息: 每个 GameObject 有一个 updateEvent 方法。 objectList 是将接收更新事件的所有对象的列表。只有此列表中的对象具有由游戏循环调用的UpdateEvent方法。

    i_m尝试在GameObject类中实现此方法(此规范是i_d 喜欢 实现方法:

    /**
    * 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个问题:

    1. 假设实现上述remove方法的stop-right-a way部分的唯一方法是抛出一个自定义异常并在游戏循环中捕获它,这是正确的吗?(我知道,为流控制使用异常就像goto,这很糟糕。我就是想不出另一种方法来做我想做的事!)

    2. 如果要从列表本身中删除,则 一个对象可以删除列表中更靠下的对象。目前,我在执行任何代码之前检查删除的标志,并在每次传递结束时删除对象以避免并发修改。有没有更好的,最好是即时/非轮询方式来实现这一点?

    [编辑] 读完你的答案后,我想我会改变方法规格。即时删除行为是我已经习惯于在不同的引擎中使用的东西,但是你是正确的,它并不真正适合Java的工作原理。该走了,试着用一种稍有不同的思维方式来盘绕我的头了!

    4 回复  |  直到 16 年前
        1
  •  1
  •   jball    16 年前

    为什么不干脆回来,也就是说,

    public void updateEvent() { 
        //object's update event 
        remove(this); 
        return;   
        //obviously unreachable 
        System.out.println("Should never reach here!");     }
    
        2
  •  2
  •   Eyal Schneider    16 年前

    我同意异常方法是根据您的规范实现remove方法的最佳方法。

    但是,也许您应该重新考虑规范。我将把updateEvent何时终止的决定留给实现者。使用remove()调用终止是令人困惑的,需要为流控制使用异常。我相信调用remove()只应该更改标志状态。我认为循环遍历所有对象没有真正的问题,检查每个对象删除的标志。

        3
  •  1
  •   Reinderien    16 年前

    你为什么不:

    • 在运行循环的对象中维护对象列表
    • 不要让游戏对象访问列表(为什么要这样做?)
    • 让updateEvent函数返回一个布尔值。如果返回值为假,则父对象将从事件列表中删除该对象。RETURN语句还用于终止事件函数的执行。
        4
  •  1
  •   Bill K    16 年前

    @jball的答案很好--+1。

    我使用的另一个方法工作得很好,可能稍微干净一点,就是让updateEvent()方法返回一个布尔值。无论何时从updateEvent返回true,都要删除对象()。

    这允许事件循环对循环本身的执行方式有更多的控制,并删除类之间一些不必要的绑定。