2013-10-31 16 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。所以雖然做數學而不是繪畫要快很多,但大量的演員會給大量的不需要的電話。