我有一个ArrayList
,可以将40,000个单独的对象绘制到屏幕上。现在我必须遍历所有这些,并在我用Graphics2D
对象绘制之前执行计算,如果它们在屏幕上显示。
for (GameObject object : gameObjects) {
if (insideScreenView(object)) {
object.draw(g2d);
}
}
这不会花费太长时间,但确实需要大约2-5毫秒。在任何给定时间,屏幕上只显示大约100个这些对象。这意味着我正在运行39,900次迭代,这些迭代并非必要。有没有更好的方法来做到这一点,因为我知道大多数迭代都不必发生。
修改
根据对象的边界矩形是否通过Rectangle
intersects()
方法与屏幕相交,选择对象在屏幕上。
答案 0 :(得分:1)
不应迭代所有游戏对象,而应仅迭代viewable objects
。
那么,该怎么做?
- >> 方法1 (缓慢但简单)<< -
首先,将您的游戏逻辑分为两部分:updateView()
和draw()
。
的UpdateView():
在这里,您calculate
屏幕内有哪些对象,并将它们添加到简单List
(您可以选择ArrayList
或LinkedList
,每个对象都会产生不同的性能影响,所以,对它们进行基准测试!)。
拉伸():
在这里,您遍历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);
}
}
希望我帮助过你。见啊!