如果整个“游戏世界”比视口宽数千倍,并且如果我想使用 scene2d 将游戏对象作为Actor
s 来管理,我应该创建与整个世界一样宽的 Stage 对象,还是应该Stage
是当前周围的某个区域视口而不是整个世界?
换句话说,Stage
具有更大宽度和高度的 a 本身是否会消耗更多内存,即使我仅在其一小部分视口大小的部分上渲染对象?
2 回答
我想你误解了 a 到底Stage
是什么。舞台本身并没有真正的尺寸。您不指定宽度或高度或Stage
,您只指定视口的宽度和高度。视口就像一个窗口,它只显示你世界的一部分,也就是场景。AStage
是一个 2D 场景图,它随着您的Actors
. 您拥有的 Actor 越多,您的 Stage 就越大(在内存方面),但这并不取决于您的 Actor 的实际分布范围。如果它们分布得很远,而你只显示整体的一小部分Stage
,那么处理起来会非常高效,因为场景图细分了这个巨大的空间,以便能够很快决定是否忽略某个 Actor,或者将其绘制在屏幕上。
这意味着 aStage
实际上正是您在这种情况下所需要的,并且您可能不应该有任何问题,FPS 和内存方面。但是当然,如果您Stage
的视口大小是视口大小的 1000 倍,并且您自己知道某些 Actor 不会很快显示,那么暂时不要将它们添加到舞台上可能是有意义的。
舞台只是一个根节点,它将容纳所有演员。它的作用是为它的孩子调用方法(比如draw和act);因此只有actor的数量和复杂度对内存和帧率有影响。
对于您的情况,当然需要剔除方法。最简单的方法是检查一个演员是否在视口中,如果没有则跳过绘制他。创建一个自定义actor并添加以下代码:source
public void draw (SpriteBatch batch, float parentAlpha) {
// if this actor is not within the view of the camera we don't draw it.
if (isCulled()) return;
// otherwise we draw via the super class method
super.draw(batch, parentAlpha);
}
Rectangle actorRect = new Rectangle();
Rectangle camRect = new Rectangle();
boolean visible;
private boolean isCulled() {
// we start by setting the stage coordinates to this
// actors coordinates which are relative to its parent
// Group.
float stageX = getX();
float stageY = getY();
// now we go up the hierarchy and add all the parents'
// coordinates to this actors coordinates. Note that
// this assumes that neither this actor nor any of its
// parents are rotated or scaled!
Actor parent = this.getParent();
while (parent != null) {
stageX += parent.getX();
stageY += parent.getY();
parent = parent.getParent();
}
// now we check if the rectangle of this actor in screen
// coordinates is in the rectangle spanned by the camera's
// view. This assumes that the camera has no zoom and is
// not rotated!
actorRect.set(stageX, stageY, getWidth(), getHeight());
camRect.set(camera.position.x - camera.viewportWidth / 2.0f,
camera.position.y - camera.viewportHeight / 2.0f,
camera.viewportWidth, camera.viewportHeight);
visible = (camRect.overlaps(actorRect));
return !visible;
}
如果您需要进一步提高性能,您可以切换到手动决定什么是可见的,什么是不可见的(例如在移动相机时)。这会更快,因为所有这些剔除计算都是在每一帧执行的,对于每个演员。因此,尽管做一些数学运算而不是绘图要快得多,但大量演员会发出大量不需要的电话。