2012-11-09 49 views
2

爲了優化我的遊戲,我將其設爲網格。對象鹼液在網格廣場。這樣做使我收集在區域中的所有對象可見的攝像頭,並把它們在列表中的層:Android遊戲中的Stutter(垃圾收集?)

public ArrayList<Entity> queryRect(OBB2D rect) 
{ 
    neighbourQueryObjs.clear(); 
    ArrayList<Region> reg = determineNeighbourRegions(rect); 
    for(int i = 0; i < Entity.MAX_LAYERS; ++i) 
    { 
     for(Region r : reg) 
     { 
      for(Entity e : r.getStatic(i)) 
      { 
       if(!neighbourQueryObjs.contains(e) && e.getRect().overlaps(rect)) 
       { 
        neighbourQueryObjs.add(e); 
       } 
      } 

      for(Entity e : r.getDynamic(i)) 
      { 
       if(!neighbourQueryObjs.contains(e) && e.getRect().overlaps(rect)) 
       { 
        neighbourQueryObjs.add(e); 
       } 
      } 
     } 
    } 

    return neighbourQueryObjs; 

} 

這個偉大的工程。遊戲速度非常快。我稱這個evey幀爲 問題是,每隔1或2秒左右,遊戲就會凍結約2-300毫秒。

我懷疑它是垃圾收集。這可能嗎?

有沒有一種方法我可以預先分配這個東西,所以它永遠不必使用GC?我不介意浪費記憶,記憶沒有問題。

這裏是我的遊戲循環,算得上是它:

public void run() { 
     Canvas canvas; 

     long beginTime;  // the time when the cycle begun 
     long timeDiff;  // the time it took for the cycle to execute 
     int sleepTime;  // ms to sleep (<0 if we're behind) 
     int framesSkipped; // number of frames being skipped 

     sleepTime = 0; 

     while (running) 
     { 
      canvas = null; 
      // try locking the canvas for exclusive pixel editing 
      // in the surface 
      try 
      { 

       // we have to make sure that the surface has been created 
       // if not we wait until it gets created 
       if (!holder.getSurface().isValid()) 
        continue; 
       canvas = this.holder.lockCanvas(); 
      synchronized (holder) 
      { 
        beginTime = System.currentTimeMillis(); 
        framesSkipped = 0; // resetting the frames skipped 
        // update game state 
        update(); 
        // render state to the screen 
        // draws the canvas on the panel 
        display(canvas); 
        // calculate how long did the cycle take 
        timeDiff = System.currentTimeMillis() - beginTime; 
        // calculate sleep time 
        sleepTime = (int)(FRAME_PERIOD - timeDiff); 

        if (sleepTime > 0) 
        { 
         // if sleepTime > 0 we're OK 
         try 
         { 
          // send the thread to sleep for a short period 
          // very useful for battery saving 
          Thread.sleep(sleepTime); 
         } catch (InterruptedException e) {} 
        } 

        while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) 
        { 
         // we need to catch up 
         // update without rendering 
         update(); 
         // add frame period to check if in next frame 
         sleepTime += FRAME_PERIOD; 
         framesSkipped++; 
        } 
       } 
      } 
      finally 
      { 
       // in case of an exception the surface is not left in 
       // an inconsistent state 
       if (canvas != null) 
       { 
        holder.unlockCanvasAndPost(canvas); 
       } 
      } // end finally 
     } 
    } 
    protected void onDrawTransformed(GraphicsContext g) 
    { 
     OBB2D view = g.getCamera().getCamRect(getWidth(), getHeight()); 

     ArrayList<Entity> ents = world.queryRect(view); 
     for(Entity e : ents) 
     { 
      e.draw(g); 
     } 
     //city.draw(g); 
     //vehicle.draw(g); 
    } 

我能做停止口吃?

感謝

+0

您是否嘗試過評論(而不是調用)'更新'? –

+0

@Vladimir Lichonos仍然沒有更新() – jmasterx

+0

你可以在你的計算機上調用adb logcat來觀察是否有關於GC收集/釋放等的日誌。如果你看到它很多,那麼可能是因爲GC和泄漏原因,否則一些東西釋放你的代碼。 –

回答

1

public ArrayList<Entity> queryRect(OBB2D rect)你經常打電話neighbourQueryObjs.clear();neighbourQueryObjs.add(e);,其分配和釋放內存。

要確定這是否真的存在問題,您可以暫時註釋掉clear()/add()零件並返回總是相同的(預計算?)neighbourQueryObjs並查看口吃是否消失。沿線的東西:

if(neighbourQueryObjs.length() == 0) { 
    // calculate the neighbourQueryObjs 
} 
return neighbourQueryObjs;