2012-10-21 128 views
0

我目前正在嘗試爲Android做一個小遊戲。
我嘗試測量遊戲的兩個動作之間的時間,但在我調用gameThread.run()方法(gameThread是可運行的)後嘗試調用currentTimeMillis()方法時,開始時間保持爲0。 當我將它放在run()呼叫之前時,它會提供正確的值。System.currentTimeMillis()返回0(零)

類Gameview:

@Override 
public void surfaceCreated(SurfaceHolder holder) 
{ 
    // at this point the surface is created and we start the gameloop 
    gameThread.setRunning(true); 
    gameThread.run(); 
    begin=System.currentTimeMillis(); 
} 

/** 
* This is the game update method. It iterates through all the objects and 
* calls their update method 
*/ 
public void update() 
{ 
    for (GuiElement element : guiElements) 
    { 
     element.update(); 
    } 
    count++; 
    if (ball.getPosY() >= Statics.DISPLAY_HEIGTH - ball.getRadius()) 
    { 
     Log.d(TAG, "Displayhoehe : " + Statics.DISPLAY_HEIGTH); 
     Log.d(TAG, "DisplayfactorHeight : " + Statics.DISPLAY_FACTOR_HEIGHT); 
     Log.d(TAG, "speedvalue : " + ball.getSpeedY()); 
     Log.d(TAG, "ballradius : " + ball.getRadius()); 
     Log.d(TAG, "am boden mit " + count + " schritten"); 
     gameThread.setRunning(false); 
     end = System.currentTimeMillis(); 
     Log.d(TAG, "begin, end " + begin + " " + end); 
     Log.d(TAG, "time " + (end - begin)); 
    } 
} 

類GameThread(實現Runnable)

public void run() 
{ 
    Canvas canvas; 
    Log.d(TAG, "Starting game loop"); 

    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 

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

      synchronized (surfaceHolder) 
      { 
       beginTime = System.currentTimeMillis(); 
       framesSkipped = 0; // resetting the frames skipped 
       // update game state 
       gameView.update(); 
       // draw state to the screen 
       gameView.draw(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 (skip some draw() calls) 
        this.gameView.update(); // update without rendering 
        sleepTime += FRAME_PERIOD; // add frame period to check 
               // if we catched up 
        framesSkipped++; 
       } 
      } 
     } 
     finally 
     { 
      // in case of an exception the surface is not left in an inconsistent state 
      if (canvas != null) 
      { 
       surfaceHolder.unlockCanvasAndPost(canvas); 
      } 
     } 
    } 
} 

編輯:我想在開始點登錄currentMillis()的返回值,似乎在run()方法完成後,該方法被稱爲。它不應該同步嗎?

@Override 
public void surfaceCreated(SurfaceHolder holder) 
{ 
    // at this point the surface is created and we start the gameloop 
    gameThread.setRunning(true); 
    gameThread.run(); 
    begin=System.currentTimeMillis(); 
    Log.d(TAG, "currentMillis at beginning " + System.currentTimeMillis()); 
} 

登錄:

10-21 19:43:17.480: D/GameView(19767): Displayhoehe : 480 
10-21 19:43:17.480: D/GameView(19767): DisplayfactorHeight : 1.0 
10-21 19:43:17.480: D/GameView(19767): speedvalue : 1.6666666666666667 
10-21 19:43:17.480: D/GameView(19767): ballradius : 20 
10-21 19:43:17.480: D/GameView(19767): am boden mit 133 schritten 
10-21 19:43:17.480: D/GameView(19767): begin, end 0 1350841397483 
10-21 19:43:17.480: D/GameView(19767): time 1350841397483 
10-21 19:43:17.480: D/GameView(19767): currentMillis at beginning 1350841397484 

解決方案:我錯誤地啓動了Runnable。這是一個啓動了Runnable的正確方法:

gameThread.setRunning(true); 
Thread t = new Thread(gameThread); 
t.start(); 
begin=System.currentTimeMillis(); 
+0

System.currentTimeMillis()返回0是不可能的(除非您已將系統時鐘設置爲1970年1月1日)。你在哪裏記錄價值? – asenovm

+0

將它放在'run()'之前有什麼問題? – Eric

+0

這不是真的錯,但我想明白爲什麼會發生這種情況。 – Refrigerator

回答

3

那是因爲你調用的方法run()直接而不是調用線程的start()方法。

+1

他指出,gameThread實際上是一個可運行的(儘管命名不好)。而且,這與System.currentTimeMillis()返回0(如果可能的話)有什麼關係。 – asenovm

+0

謝謝你,我很尷尬起動Runnable不正確... – Refrigerator

+0

如果是這樣的話 - 還有一些其他的事情要提到: *正確提出你的問題 - System.currentTimeMillis從未返回0 *正確命名你的變量 - 即gamerThread不是線程,但是可運行 *使用System.nanoTime()而不是System.currentTimeMillis(),因爲後者取決於可以測量的最小時間量(特定於操作系統) *永遠不會簡單地吞下中斷異常 - 處理這種情況的正確方法是實際停止某些事情/停止線程的執行,或者重置中斷標誌(通過調用Thread.currentThread()。interrupt()'。 – asenovm