Question

If the whole "game world" is thousands of times wider than a viewport, and if I want to use scene2d to manage game objects as Actors, should I create Stage object as wide as the whole world, or should the Stage be some area around current viewport but not the whole world?
In other words, does a Stage with greater width and height consume more memory itself, even if I render objects only on a small viewport-sized part of it?

Was it helpful?

Solution

I think you misunderstood what exactly a Stage is. A Stage doesn't really have a size itself. You don't specify a width or height or the Stage, you only specify the width and height of the viewport. The viewport is like a window, which shows only a part of your world, aka scene. A Stage is a 2D scene graph and it "grows" with your Actors. The more Actors you have, the bigger (memory wise) your Stage is, but it doesn't depend on how far spreaded your Actors actually are. If they are very far spreaded and you only display a very small part of your whole Stage, it will be handled very efficient, because a scene graph sub-divides this huge space to be able to very quickly decide whether to ignore a certain Actor, or draw it on the Screen.

That means a Stage is actually exactly what you need for this kind of situation and you should probably not have any problems, FPS and memory wise. But of course if your Stage is 1000s of times the size of your viewport and you know yourself that certain Actors aren't displayed soon, then it might make sense to not add them to the Stage yet.

OTHER TIPS

A stage is only a root node that will hold all the actors. It's role is to call methods for its children (like draw and act); thus only the number and complexity of actor have an impact on memory and frame rate.


For your situation a culling method is certainly required. The simplest one would be to check if an actor is in the viewport and if not skip drawing him. Create a custom actor and add this code: 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;
        }


If you need to improve performance even further you can switch to manually deciding what is visible and what not (ex when moving the camera). This would be faster because all those culling calculations are executed at EVERY frame, for EVERY actor. So although it's a lot faster to do some math instead of drawing, a big number of actors would give a huge amount of unwanted calls.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top