精确FPS

来源:互联网 发布:程序员逻辑思维训练 编辑:程序博客网 时间:2024/03/29 22:54

      先看看这段代码,Draw()方法绘制结束让线程等待100毫秒在进入下一次循环。其实这样更新游戏循环是很不科学的,原因是Draw()方法每一次更新所耗费的时间是不确定的。举个例子比如第一次循环Draw() 耗费了1000毫秒 加上线程等待100毫秒 整个循环耗时1100毫秒,第二次循环Draw()耗时2000毫秒 加上线程等待时间100毫秒整个循环时间就是2100毫秒。很明显这样就会造成游戏运行刷新时间时快时慢,所以说它是很不科学的。

ublic void run() {      while (mIsRunning) {      //在这里加上线程安全锁      synchronized (mSurfaceHolder) {                    mCanvas =mSurfaceHolder.lockCanvas();            Draw();                    mSurfaceHolder.unlockCanvasAndPost(mCanvas);      }      try {          Thread.sleep(100);      } catch (InterruptedException e) {          e.printStackTrace();      }      }  }  

      在贴一段科学的控游戏制循环代码,每次循环游戏主线程在Draw()方法前后计算出Draw()方法所消耗的时间,然后在判断是否达到我们规定的刷新屏幕时间,下例是以30帧刷新一次屏幕,如果满足则继续下次循环如果不满足使用Thread.yield();让游戏主线程去等待并计算当前等待时间直到等待时间满足30帧为止在继续下一次循环刷新游戏屏幕。


这里说一下Thread.yield(): 与Thread.sleep(longmillis):的区别,Thread.yield(): 是暂停当前正在执行的线程对象 ,并去执行其他线程。Thread.sleep(longmillis):则是使当前线程暂停参数中所指定的毫秒数然后在继续执行线程。

public static final int TIME_IN_FRAME = 30;  @Override  public void run() {      while (mIsRunning) {      <span style="white-space:pre"></span>long startTime = System.currentTimeMillis();        <span style="white-space:pre"></span>synchronized (mSurfaceHolder) {      <span style="white-space:pre"></span>mCanvas =mSurfaceHolder.lockCanvas();        <span style="white-space:pre"></span>Draw();      <span style="white-space:pre"></span>mSurfaceHolder.unlockCanvasAndPost(mCanvas);      }     <span style="white-space:pre"></span>long endTime = System.currentTimeMillis();      <span style="white-space:pre"></span>int diffTime  = (int)(endTime - startTime);     <span style="white-space:pre"></span>while(diffTime <=TIME_IN_FRAME) {    <span style="white-space:pre"></span>diffTime = (int)(System.currentTimeMillis() - startTime);    <span style="white-space:pre"></span>Thread.yield();      }       }  } 


0 0