2012-10-21 146 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