我曾经看到Airplane Madness游戏在我的HTC Wildfire S手机上以恒定平均60 FPS的速度渲染屏幕。我一直在尝试在同一部手机上模仿这个结果,但我就是不明白为什么我的程序平均只有15 FPS?
你可能会问我如何查看Airplane Madness的帧率?在设置中有一个开关FPS计数器的选项。我将其设置为启用。
这是我的代码。这是我的游戏循环。从中可以得出一些有趣的结果:
你可能会问我如何查看Airplane Madness的帧率?在设置中有一个开关FPS计数器的选项。我将其设置为启用。
这是我的代码。这是我的游戏循环。从中可以得出一些有趣的结果:
public void run() {
// Average FPS for Android is 15 on Test Phone is 13 through 15.
// Max FPS is 20.
// Occasional bursts of FPS60 may occur.
long now, lastTime = System.nanoTime();
double process = 0.0;
final double NSperTick = 1000000000.0 / 60.0;
while (running) {
now = System.nanoTime();
process += (now - lastTime) / NSperTick;
lastTime = now;
boolean ticked = false;
while (process >= 1) {
process -= 1;
tick();
ticked = true;
}
if (ticked) {
render();
}
swap();
try {
Thread.sleep(2);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
有人能告诉我哪里做错了,需要改进什么,以便我可以获得平均60 FPS吗?这个游戏循环在Java中运行时(不是Android),它的运行非常好,所以我不确定哪些逻辑部分影响了我的智能手机的帧率。
提前感谢您。
编辑:看起来我需要让所有函数为人所知。
private void render() {
synchronized (holder) {
if (holder.getSurface().isValid()) {
Canvas c = holder.lockCanvas();
c.drawRGB(0x44, 0x55, 0xff);
ball.render(c);
holder.unlockCanvasAndPost(c);
}
}
}
private void swap() {
}
private void tick() {
float[] values = {meter.X, meter.Y, meter.Z};
ball.tick(values);
handler.tick(ball);
}
以下是我检查游戏平均FPS的方法:
public void run() {
// Average FPS for Android is 15 on Test Phone is 13 through 15.
// Max FPS is 20.
// Occasional bursts of FPS60 may occur.
long now, lastTime = System.nanoTime();
int frames = 0;
double process = 0.0;
long frameTime = System.currentTimeMillis();
final double NSperTick = 1000000000.0 / 60.0;
while (running) {
now = System.nanoTime();
process += (now - lastTime) / NSperTick;
lastTime = now;
boolean ticked = false;
while (process >= 1) {
process -= 1;
tick();
ticked = true;
}
if (ticked) {
//render();
frames++;
}
swap();
try {
Thread.sleep(2);
}
catch (InterruptedException e) {
e.printStackTrace();
}
if (frameTime <= System.currentTimeMillis() - 1000)
{
Log.d("FrameRate", Integer.toString(frames));
frameTime += 1000;
frames = 0;
}
}
}
以下是DDMS的结果:
03-12 14:29:21.008: D/FrameRate(3533): 14
03-12 14:29:22.061: D/FrameRate(3533): 15
03-12 14:29:23.048: D/FrameRate(3533): 14
03-12 14:29:24.033: D/FrameRate(3533): 14
03-12 14:29:25.018: D/FrameRate(3533): 14
03-12 14:29:26.000: D/FrameRate(3533): 14
03-12 14:29:27.056: D/FrameRate(3533): 15
03-12 14:29:28.047: D/FrameRate(3533): 14
03-12 14:29:29.026: D/FrameRate(3533): 14
03-12 14:29:29.995: D/FrameRate(3533): 14
03-12 14:29:31.037: D/FrameRate(3533): 15
03-12 14:29:32.015: D/FrameRate(3533): 14
编辑2:这里有更多的信息:
我已经在render()函数中注释掉了这段代码:
synchronized (holder)
但我只能达到14至15 FPS。这是我无法突破的限制吗?
render()
,它会如何表现?这是您似乎忽略的明显问题,也许您的渲染需要比您拥有的时间更长。 - unwindsleep()
。游戏循环是一个需要实际使用忙等待的情况,因为sleep()
无法保证在唤醒之前睡眠的最长时间。 - TaZ