2012-08-12 75 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