2014-02-10 83 views
0

好吧,爲什麼玩遊戲時我的每秒幀數會隨機下降?我能做些什麼來解決它。下面即將展示我已經建立的引擎的代碼。如何阻止每秒幀數下降?

 public Engine() { 
    Log.d("Engine","Engine constructor"); 
    p_view = null; 
    p_canvas = null; 
    p_thread = null; 
    p_running = false; 
    p_paused = false; 
    p_resume = false; 
    p_paintDraw = null; 
    p_paintFont = null; 
    p_numPoints = 0; 
    p_typeface = null; 
    p_preferredFrameRate = 40; 
    p_sleepTime = 1000/p_preferredFrameRate; 
    p_pauseCount = 0; 
    p_group = new LinkedList<Sprite>(); 
} 

    /** 
* Runnable.run thread method (MAIN LOOP) 
*/ 
@Override 
public void run() { 
    Log.d("Engine","Engine.run start"); 

    ListIterator<Sprite> iter=null, iterA=null, iterB=null;  

    Timer frameTimer = new Timer(); 
    int frameCount=0; 
    int frameRate=0; 
    long startTime=0; 
    long timeDiff=0; 

    while (p_running) { 
     // Process frame only if not paused 
     if (p_paused) continue; 

     // Calculate frame rate 
     frameCount++; 
     startTime = frameTimer.getElapsed(); 
     if (frameTimer.stopwatch(1000)) { 
      frameRate = frameCount; 
      frameCount = 0; 

      //reset touch input count 
      p_numPoints = 0; 
     } 


     // Call abstract update method in sub-class 
     update(); 


     /** 
     * Test for collisions in the sprite group. 
     * Note that this takes place outside of rendering. 
     */ 
     iterA = p_group.listIterator(); 
     while (iterA.hasNext()) { 
      Sprite sprA = (Sprite)iterA.next(); 
      if (!sprA.getAlive()) continue; 
      if (!sprA.getCollidable()) continue; 

      /* 
      * Improvement to prevent double collision testing 
      */ 
      if (sprA.getCollided()) 
       continue; //skip to next iterator 

      //iterate the list again 
      iterB = p_group.listIterator(); 
      while (iterB.hasNext()) { 
       Sprite sprB = (Sprite)iterB.next(); 
       if (!sprB.getAlive()) continue; 
       if (!sprB.getCollidable()) continue; 

       /* 
       * Improvement to prevent double collision testing 
       */ 
       if (sprB.getCollided()) 
        continue; //skip to next iterator 

       //do not collide with itself 
       if (sprA == sprB) continue; 

       /* 
       * Ignore sprites with the same ID? This is an important 
       * consideration. Decide if your game requires it or not. 
       */ 
       if (sprA.getIdentifier() == sprB.getIdentifier()) 
        continue; 

       if (collisionCheck(sprA, sprB)) { 
        sprA.setCollided(true); 
        sprA.setOffender(sprB); 
        sprB.setCollided(true); 
        sprB.setOffender(sprA); 
        break; //exit while 
       } 
      } 
     } 


     // begin drawing 
     if (beginDrawing()) { 

      // Call abstract draw method in sub-class 
      draw(); 


      /** 
      * Draw the group entities with transforms 
      */ 
      iter = p_group.listIterator(); 
      while (iter.hasNext()) { 
       Sprite spr = (Sprite)iter.next(); 
       if (spr.getAlive()) { 
        spr.animate(); 
        spr.draw(); 
       } 
      } 

      /** 
      * Print some engine debug info. 
      */ 
      int x = p_canvas.getWidth()-150; 
      p_canvas.drawText("ENGINE", x, 20, p_paintFont); 
      p_canvas.drawText(toString(frameRate) + " FPS", x, 40, 
       p_paintFont); 
      p_canvas.drawText("Pauses: " + toString(p_pauseCount), 
       x, 60, p_paintFont); 

      // done drawing 
      endDrawing(); 
     } 

     /* 
     * Do some cleanup: collision notification, removing 
     * 'dead' sprites from the list. 
     */ 
     iter = p_group.listIterator(); 
     Sprite spr = null; 
     while (iter.hasNext()) { 
      spr = (Sprite)iter.next(); 

      //remove from list if flagged 
      if (!spr.getAlive()) { 
       iter.remove(); 
       continue; 
      } 

      //is collision enabled for this sprite? 
      if (spr.getCollidable()) { 

       //has this sprite collided with anything? 
       if (spr.getCollided()) { 

        //is the target a valid object? 
        if (spr.getOffender() != null) { 

         /* 
         * External func call: notify game of collision 
         * (with validated offender) 
         */ 
         collision(spr); 

         //reset offender 
         spr.setOffender(null); 
        } 

        //reset collided state 
        spr.setCollided(false); 

       } 
      } 
     } 

     // Calculate frame update time and sleep if necessary 
     timeDiff = frameTimer.getElapsed() - startTime; 
     long updatePeriod = p_sleepTime - timeDiff; 
     if (updatePeriod > 0) { 
      try { 
       Thread.sleep(updatePeriod); // i notice this is called when frames are low 
      } 
      catch(InterruptedException e) {} 
     } 

    }//while 
    Log.d("Engine","Engine.run end"); 
    System.exit(RESULT_OK); 
}  


    public void setFrameRate(int rate) { 
    p_preferredFrameRate = rate; 
    p_sleepTime = 1000/p_preferredFrameRate; 
} 

所以這不是整個引擎,但它是處理幀的一切爲什麼它隨機丟棄?我注意到thread.sleep被調用時框架降到15以下。我使用nexus 5來測試這個在Android 4.4.2上運行,並且我的問題在於如何阻止幀丟失那麼低和讓它在調用重新創建後特別睡覺();你失去了比賽的方法嗎?

回答

2

只要完全取出Thread.Sleep語句。或者只是將「0」傳遞給Sleep調用(如果您試圖將週期交給其他線程和進程)。在run()循環的每個循環中,計算實際經過的時間並根據此值更新仿真。換句話說,不要試圖強制硬編碼幀速率。

設備的幀速率上限(我的設備上爲60fps)。所以無論如何,你在每個循環中都可能會睡一會兒。

+0

因此,刪除tread.sleep語句將停止幀丟棄? –

+1

試試吧,看看...如果沒有,你應該在你的代碼中應用一個分析工具。 – selbie

+0

所以我實際上拿出了睡眠方法,結果它仍然崩潰。現在發生的事情是,當太多圖片加載時它會被凍結。 –