8

如果整个“游戏世界”比视口宽数千倍,并且如果我想使用 scene2d 将游戏对象作为Actors 来管理,我应该创建与整个世界一样宽的 Stage 对象,还是应该Stage是当前周围的某个区域视口而不是整个世界?
换句话说,Stage具有更大宽度和高度的 a 本身是否会消耗更多内存,即使我仅在其一小部分视口大小的部分上渲染对象?

4

2 回答 2

14

我想你误解了 a 到底Stage是什么。舞台本身并没有真正的尺寸。您不指定宽度或高度或Stage,您只指定视口的宽度和高度。视口就像一个窗口,它只显示你世界的一部分,也就是场景。AStage是一个 2D 场景图,它随着您的Actors. 您拥有的 Actor 越多,您的 Stage 就越大(在内存方面),但这并不取决于您的 Actor 的实际分布范围。如果它们分布得很远,而你只显示整体的一小部分Stage,那么处理起来会非常高效,因为场景图细分了这个巨大的空间,以便能够很快决定是否忽略某个 Actor,或者将其绘制在屏幕上。

这意味着 aStage实际上正是您在这种情况下所需要的,并且您可能不应该有任何问题,FPS 和内存方面。但是当然,如​​果您Stage的视口大小是视口大小的 1000 倍,并且您自己知道某些 Actor 不会很快显示,那么暂时不要将它们添加到舞台上可能是有意义的。

于 2013-10-31T06:30:26.393 回答
0

舞台只是一个根节点,它将容纳所有演员。它的作用是为它的孩子调用方法(比如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;
        }


如果您需要进一步提高性能,您可以切换到手动决定什么是可见的,什么是不可见的(例如在移动相机时)。这会更快,因为所有这些剔除计算都是在每一帧执行的,对于每个演员。因此,尽管做一些数学运算而不是绘图要快得多,但大量演员会发出大量不需要的电话。

于 2013-11-18T10:27:56.517 回答