迭代很多对象

时间:2014-05-24 18:19:06

标签: java performance

我有一个ArrayList,可以将40,000个单独的对象绘制到屏幕上。现在我必须遍历所有这些,并在我用Graphics2D对象绘制之前执行计算,如果它们在屏幕上显示。

for (GameObject object : gameObjects) {
        if (insideScreenView(object)) {
            object.draw(g2d);
        }
    }

这不会花费太长时间,但确实需要大约2-5毫秒。在任何给定时间,屏幕上只显示大约100个这些对象。这意味着我正在运行39,900次迭代,这些迭代并非必要。有没有更好的方法来做到这一点,因为我知道大多数迭代都不必发生。

修改 根据对象的边界矩形是否通过Rectangle intersects()方法与屏幕相交,选择对象在屏幕上。

1 个答案:

答案 0 :(得分:1)

不应迭代所有游戏对象,而应仅迭代viewable objects

那么,该怎么做?

- >> 方法1 (缓慢但简单)<< -

首先,将您的游戏逻辑分为两部分:updateView()draw()

  • 的UpdateView(): 在这里,您calculate屏幕内有哪些对象,并将它们添加到简单List(您可以选择ArrayListLinkedList,每个对象都会产生不同的性能影响,所以,对它们进行基准测试!)。

  • 拉伸(): 在这里,您遍历List之前创建的updateView上的所有对象,以及draw它们。

- >> 方法2 (快速但复杂)<< -

基本逻辑有点像方法1:你在List中有可视对象,并在draw()方法上绘制它们。但是这些方法之间的区别在于,在这种方法中,您可以check when the objects move而不是每个刻度来验证哪些对象是可见的。

取决于管理游戏对象的方式,Method 1 can be faster(如果您的游戏对象每次都在移动,例如particles),但出于一般目的,this method is faster

因此,在Game Object中,添加一个名为addedToViewList的布尔值。这个布尔值表示对象是否is added to the viewable objects list,因此我们不需要使用list.contains(object)并迭代它。然后,每次勾选,检查对象是否已经在列表中。如果是,则检查他是否可见:如果不可见,则从列表中remove他。如果他不在名单上,但他是可见的,那么你add他要列出。

示例:

public void onMove() {
  if (addedToViewList && !insideScreenView()) {
    this.addedToViewList = false;
    (view list).remove(this);
  }
  else if (!addedToViewList && insideScreenView()) {
    this.addedToViewList = true;
    (view list).add(this);
  }
}
希望我帮助过你。见啊!