2012-08-12 76 views
0

我正在使用SurfaceView,我必須儘快更新它。由於onDraw方法不會自動調用,我必須顯式調用。所以我的第一次嘗試是在線程上,但我有一些滯後。有更好的方法來做到這一點?如果有更好的解決方案,請你解釋一下嗎?我是Android World的新手!多次更新SurfaceView的更好方法?


我有什麼到目前爲止

public void run() { 
    while(running){ 
     Canvas c = null; 
     try { 
      c = view.getHolder().lockCanvas(); 
      synchronized (view.getHolder()) { 
       view.onDraw(c); 
      } 
     } finally { 
      if (c != null) { 
       view.getHolder().unlockCanvasAndPost(c); 
      } 
     } 
    } 
} 

回答

0

這裏是我的代碼,我作爲渲染線程中使用。 fps更新取決於幀。我通常以30 fps的速度運行我的遊戲。 (這裏也有一些代碼,您將不再需要,但我陛下,你就可以找到你正在尋找的作品。)

public class RenderView extends SurfaceView implements Runnable { 


    Game game; 
    Bitmap gameScreen; 
    Thread gameloop; 
    SurfaceHolder holder; 
    boolean running; 

    int sleepTime; 
    int numberOfFramesSkipped; 
    int maxFrameSkips; 
    long beginTime; 
    long endTime; 
    long lastTime; 
    int differenceTime; 
    int framePeriod; 
    Canvas frameBuffer; 
    int frameCount; 

    public RenderView(int fps, int maxFrameSkips) { 
     super(game); 
     this.gameScreen = gameScreen; 
     this.holder = getHolder(); 
     this.framePeriod = 1000/fps; 
     this.maxFrameSkips = maxFrameSkips; 
     lastTime = System.currentTimeMillis(); 
     beginTime = System.currentTimeMillis(); 
    } 

    @Override 
    public void run() { 

     while(running == true) { 
      if(holder.getSurface().isValid()) { 

       beginTime = System.currentTimeMillis(); 

        // call your update method here 
       // render here 
        frameBuffer = holder.lockCanvas(); 
        this.onDraw(); 
        holder.unlockCanvasAndPost(frameBuffer); 

       // Frame Per Second Count 
       frameCount++; 

       if(lastTime + 1000 < System.currentTimeMillis()) { 
        lastTime = System.currentTimeMillis(); 
        frameCount = 0; 
       } 

       endTime = System.currentTimeMillis();; 
       differenceTime = (int) (endTime - beginTime); 
       sleepTime = (int) (framePeriod - differenceTime); 

       if(sleepTime > 0) { 
        try { 
         Thread.sleep(sleepTime); 
        } catch (InterruptedException exception) { 
         exception.printStackTrace(); 
        } 
       } 
       else { 
        while(sleepTime < 0 && numberOfFramesSkipped < this.maxFrameSkips) { 
         // Call your update method here 
         sleepTime += framePeriod; 
         numberOfFramesSkipped++; 
        } 
       } 


      } 


     } 

    } 

    private void renderFrameBuffer() { 
     // Update the current virtual screen image 
     game.getCurrentScreen().render(); 
     // Render the current virtual screen to the real phone screen 
     frameBuffer = holder.lockCanvas(); 
     if(frameBuffer != null) { // Fix for mysterious bug (FATAL EXCEPTION: Thread) 
      // The viewing area of our virtual screen on our real screen 
      // Composition 
      // First layer (bottom) 
       frameBuffer.drawBitmap(this.gameScreen, null, game.getWSScreen().getGameScreendst(), null); 
      // Second layer (top) 
       frameBuffer.drawBitmap(this.gameScreenExtended, null, game.getWSScreen().getGameScreenextendeddst(), null); 

      holder.unlockCanvasAndPost(frameBuffer); 
     } 
     else { 
      gameEngineLog.e(classTAG, "Surface has not been created or otherwise cannot be edited"); 
     } 
    } 

    public void resume() { 
     this.running = true; 
     gameloop = new Thread(this); 
     gameloop.start();   
    } 

    public void pause() { 
     this.running = false; 
     running = false;       
     while(true) { 
      try { 
       gameloop.join(); 
       break; 
      } catch (InterruptedException e) { 
       // retry 
      } 
     } 
    } 

} 

public void onDraw() { 

} 

我建議你先看看這個鏈接,或有看看 http://code.google.com/p/beginning-android-games/http://www.edu4java.com/en/androidgame/androidgame3.html

+0

有一些重複的LOC,它很複雜。你能簡化它嗎? – 2012-08-12 18:54:24

+0

更新後的代碼(試圖減少它)並添加了一些有用的鏈接。 – 2012-08-12 20:04:41