2012-11-09 46 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;