2013-10-31 13 views
8

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

回答

14

我想你错误地理解了Stage究竟是什么。舞台本身并不具备真正的大小。您不指定宽度或高度或Stage,您只指定视口的宽度和高度。视口就像一个窗口,只显示你的世界的一部分,也就是场景。 A Stage是2D场景图,它会随着您的Actors“增长”。你拥有的演员越多,你的舞台就越大(记忆方面),但它并不取决于你演员的实际演出程度。如果它们的距离非常远,并且只显示整个Stage的很小部分,则处理效率会非常高,因为场景图细分这个巨大空间以便能够快速决定是否忽略某个Actor,或在屏幕上绘制它。

这意味着Stage实际上正是你所需要的这种情况,你应该没有任何问题,FPS和记忆方式。 但是当然,如果您的Stage是您的视口大小的1000倍,并且您自己知道某些演员不会很快显示,那么将其添加到舞台上还是有意义的。

0

阶段只是一个根节点,它将容纳所有参与者。它的作用是为其子女调用方法(如绘制和动作);因此只有演员的数量和复杂性才会影响内存和帧率。


对于你的情况,一个剔除方法肯定是必需的。最简单的方法是检查演员是否在视口中,是否不跳过画他。创建自定义的演员,并添加以下代码: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; 
     } 


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