【问题标题】:Proper using of scene2d's Stage in a game with a huge world在大世界的游戏中正确使用scene2d的舞台
【发布时间】:2013-11-11 00:30:23
【问题描述】:

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

【问题讨论】:

    标签: libgdx scene2d


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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


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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-19
        • 2015-10-08
        • 2022-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-07
        相关资源
        最近更新 更多