游戏渲染很慢
game rendering is very slow
我几乎完成了 Android 上的第一场比赛。我只是有一个我自己无法理解的问题。我使用一个基本的游戏循环线程来更新和调用我创建的游戏引擎的绘制方法。我注意到 FPS 非常低,所以我测量了渲染时间,我看到绘图花了 50 毫秒(所以我有大约 20 FPS,这对眼睛来说不舒服)。
但是,我只画了几个位图,应该不会那么长......
这是我的绘制方法:
public void Draw(Canvas canvas){
width = canvas.getWidth();
height = canvas.getHeight();
character_rect.set(character.x, (int)(height*80.0/100), character.x+bmp_character.getWidth(), (int)(height*80.0/100)+bmp_character.getHeight());
background_rect.set(0, 0, width, height);
canvas.drawBitmap(bmp_background, null, background_rect, _paint);
drawCops(canvas);
drawGangsters(canvas);
drawTrees(canvas);
drawButtons(canvas);
drawCharacter(canvas);
_paint.setTextSize(45);
_paint.setColor(Color.WHITE);
canvas.drawText("Score: "+score, (float)(width*3.0/100), (float)(height*3.0/100), _paint);
canvas.drawText("Money: "+money, (float)(width*3.0/100), (float)(height*6.0/100), _paint);
_paint.setColor(Color.RED);
canvas.drawRect((float)(width*3.0/100),(float)(height*8.0/100), (float)(width*3.0/100 + (current_hp*width*1.0/100)), (float)(height*10.0/100), _paint);
if(game_over){
gameover_rect = new Rect(0, 0, width, height);
canvas.drawBitmap(gameover_background, null, gameover_rect, _paint);
_paint.setColor(Color.WHITE);
_paint.setTextSize(60);
canvas.drawText("GAME OVER!", (int)(width*20.0/100), (int)(height*45.0/100), _paint);
canvas.drawText("Score: "+score, (int)(width*20.0/100), (int)(height*50.0/100), _paint);
canvas.drawText("Best score: "+character.bestScore, (int)(width*20.0/100), (int)(height*55.0/100), _paint);
canvas.drawText("Money earned: "+money+" $", (int)(width*20.0/100), (int)(height*60.0/100), _paint);
canvas.drawBitmap(replay_button_image, null, replay_button_rect, _paint);
}
}
不同的绘制方法非常简单,例如drawCops():
public void drawCops(Canvas canvas) {
for(int i=0; i<cops.length; i++) {
if(cops[i].active) {
canvas.drawBitmap(cops[i].image, null, cops[i].box, _paint);
}
}
}
这是我的游戏循环,和我在网上找到的其他游戏循环基本相同:
@Override
public void run() {
long FPS = 40;
long ticksPS = (long) (1000.0 / FPS);
long startTime;
long sleepTime;
while (_isOnRun) {
Canvas c = null;
startTime = System.currentTimeMillis();
engine.Update();
try {
c = _surfaceHolder.lockCanvas();
synchronized (_surfaceHolder) {
engine.Draw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
Log.e("tag", "render time: " + (ticksPS-sleepTime));
try {
if (sleepTime > 0) {
sleep(sleepTime);
}
else{
sleep(4);
}
} catch (Exception e) {}
}
}
抱歉英语不好,这不是我的母语。
抱歉,我通过测量每行花费的时间终于找到了问题,我们可以关闭线程。
如果有人看到这个话题并想知道答案,我的问题是这一行:
canvas.drawBitmap(bmp_background, null, background_rect, _paint);
bmp_background 和 background_rect 的大小不一样,所以每次调用 Draw() 时都会对位图进行缩放。
我通过调用 Bitmap.createScaledBitmap(...) 在宽度或高度变化时创建缩放位图解决了这个问题,然后绘制缩放位图。
我几乎完成了 Android 上的第一场比赛。我只是有一个我自己无法理解的问题。我使用一个基本的游戏循环线程来更新和调用我创建的游戏引擎的绘制方法。我注意到 FPS 非常低,所以我测量了渲染时间,我看到绘图花了 50 毫秒(所以我有大约 20 FPS,这对眼睛来说不舒服)。 但是,我只画了几个位图,应该不会那么长...... 这是我的绘制方法:
public void Draw(Canvas canvas){
width = canvas.getWidth();
height = canvas.getHeight();
character_rect.set(character.x, (int)(height*80.0/100), character.x+bmp_character.getWidth(), (int)(height*80.0/100)+bmp_character.getHeight());
background_rect.set(0, 0, width, height);
canvas.drawBitmap(bmp_background, null, background_rect, _paint);
drawCops(canvas);
drawGangsters(canvas);
drawTrees(canvas);
drawButtons(canvas);
drawCharacter(canvas);
_paint.setTextSize(45);
_paint.setColor(Color.WHITE);
canvas.drawText("Score: "+score, (float)(width*3.0/100), (float)(height*3.0/100), _paint);
canvas.drawText("Money: "+money, (float)(width*3.0/100), (float)(height*6.0/100), _paint);
_paint.setColor(Color.RED);
canvas.drawRect((float)(width*3.0/100),(float)(height*8.0/100), (float)(width*3.0/100 + (current_hp*width*1.0/100)), (float)(height*10.0/100), _paint);
if(game_over){
gameover_rect = new Rect(0, 0, width, height);
canvas.drawBitmap(gameover_background, null, gameover_rect, _paint);
_paint.setColor(Color.WHITE);
_paint.setTextSize(60);
canvas.drawText("GAME OVER!", (int)(width*20.0/100), (int)(height*45.0/100), _paint);
canvas.drawText("Score: "+score, (int)(width*20.0/100), (int)(height*50.0/100), _paint);
canvas.drawText("Best score: "+character.bestScore, (int)(width*20.0/100), (int)(height*55.0/100), _paint);
canvas.drawText("Money earned: "+money+" $", (int)(width*20.0/100), (int)(height*60.0/100), _paint);
canvas.drawBitmap(replay_button_image, null, replay_button_rect, _paint);
}
}
不同的绘制方法非常简单,例如drawCops():
public void drawCops(Canvas canvas) {
for(int i=0; i<cops.length; i++) {
if(cops[i].active) {
canvas.drawBitmap(cops[i].image, null, cops[i].box, _paint);
}
}
}
这是我的游戏循环,和我在网上找到的其他游戏循环基本相同:
@Override
public void run() {
long FPS = 40;
long ticksPS = (long) (1000.0 / FPS);
long startTime;
long sleepTime;
while (_isOnRun) {
Canvas c = null;
startTime = System.currentTimeMillis();
engine.Update();
try {
c = _surfaceHolder.lockCanvas();
synchronized (_surfaceHolder) {
engine.Draw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
Log.e("tag", "render time: " + (ticksPS-sleepTime));
try {
if (sleepTime > 0) {
sleep(sleepTime);
}
else{
sleep(4);
}
} catch (Exception e) {}
}
}
抱歉英语不好,这不是我的母语。
抱歉,我通过测量每行花费的时间终于找到了问题,我们可以关闭线程。
如果有人看到这个话题并想知道答案,我的问题是这一行:
canvas.drawBitmap(bmp_background, null, background_rect, _paint);
bmp_background 和 background_rect 的大小不一样,所以每次调用 Draw() 时都会对位图进行缩放。 我通过调用 Bitmap.createScaledBitmap(...) 在宽度或高度变化时创建缩放位图解决了这个问题,然后绘制缩放位图。