【发布时间】:2014-02-24 06:05:09
【问题描述】:
去年春天,我在大学学习 Android,最后一项任务是开发游戏。我不会提供有关游戏本身的任何细节,但我使用了一个将 SurfaceView 扩展为游戏面板的类,并将游戏循环放在后台线程中。游戏花了一个月的努力才完成,但结果非常好——太好了,我在安卓市场上推出了它,现在下载量越来越多。但是有一个相当大的缺点,如下所示:
要在这项任务中获得最高速率,必须制作帧速率必须恒定的游戏。因为我获得了最高学位,而且老师对我的源代码非常满意,所以我认为没有错误修复。但是 - 问题是帧速率不是恒定的。更奇怪的是:在屏幕上移动的图形对象 - CPU 越快,移动越慢。
我有三部不同型号的手机,显示三种不同的速度:
- SAMSUNG GALAXY MINI(处理器时钟速度 1 GHz)这里的物体移动得很快
- SAMSUNG GALAXY S3(处理器时钟速度 1.8 GHz)这里的物体以中等速度移动
- SAMSUNG GALAXY S4(处理器时钟速度 2.3 GHz)这里的物体移动缓慢
简而言之 - 智能手机在处理器方面越强大,图形对象在屏幕上移动的速度就越慢 - 人们可能会提出相反的看法 - 更快的智能手机的帧速率更高。
我在下面展示了保存游戏循环的背景线程 - 我看不出我在这段代码中做错了什么 - 也看不到我的老师
public class MainThread extends Thread {
private static final String TAG = MainThread.class.getSimpleName();
private final static int MAX_FPS = 50; // Antal frames per sekund.
private final static int MAX_FRAME_SKIPS = 5; // Antal förlorade frames.
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel) {
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
@Override
public void run() {
Canvas canvas;
Log.d(TAG, "Starting game loop");
long beginTime; // Cykelns starttid
long timeDiff; // Tiden det tar för en cykel
int sleepTime; // Cykel (update + render = timediff) + sleeptime => frameperiod.
int framesSkipped; // Antalet förlorade frames.
sleepTime = 0;
while (running) {
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
beginTime = System.currentTimeMillis();
framesSkipped = 0;
try {
this.gamePanel.update_graphics();
this.gamePanel.render_graphics(canvas);
}
catch (Exception e) {
System.out.println("fel uppstod i bakgrundstråden: " + e);
}
timeDiff = System.currentTimeMillis() - beginTime;
sleepTime = (int)(FRAME_PERIOD - timeDiff);
//System.out.println("sleeptime: " + sleepTime);
if (sleepTime > 0) {
// Sleeptime ska vara positiv, med marginal. (Annars risk för hackig animation)
try {
Thread.sleep(sleepTime); // Tråden sover en stund.
} catch (InterruptedException e) {}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
// Används för att "komma igen/komma ikapp".
try {
this.gamePanel.update_graphics(); // endast updatering.
}
catch (Exception e) {
System.out.println("fel uppstod i bakgrundstråden: " + e);
}
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
if (framesSkipped > 0) {
//Log.d(TAG, "Skipped:" + framesSkipped);
}
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // slut finally
}
}
}
提前致谢
【问题讨论】:
-
我不确定为什么对象移动缓慢,仍在考虑那个...但是提示-您的更新方法应该接受增量时间。这样,您的对象可以在考虑时间的情况下自行更新。
标签: android frame-rate