我正在嘗試創建一款適用於Android的2D遊戲,目前我正在努力實現大約30幀/秒的恆定幀數(我認爲30對於手機遊戲足夠了)。我正在使用SurfaceView和一個非常直接的遊戲循環:畫到畫布太慢,我如何達到恆定的30 fps或更多? (Android)
while (isOk==true)
{
if (!holder.getSurface().isValid()) continue;
c = holder.lockCanvas();
update();
draw(c);
holder.unlockCanvasAndPost(c);
t2= System.currentTimeMillis();
all++;
if (mspf /* miliseconds per frame, and it's set to 1000/30 */ -(t2-t1) > 0)
{
try {
t.sleep(mspf-(t2-t1));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
Log.w("Super",String.valueOf(mspf-(t2-t1))+ " o " + String.valueOf(++total)+ "out of " +String.valueOf(all));
t1=Math.max(t1+mspf, t2);
}
這是遊戲循環。正如你可能已經注意到的那樣,我使用Log.w來查看Thread.sleep有多少幀剩餘時間。結果並不是那麼好。我有大約10-25%是exceede 1000年至1030年毫秒的幀的運行:
09-07 00:00:39.069:W /超(28328):○4395out的16353
09 -1 -07 00:00:39.109:W/Super(28328):-1 o 4396out of 16354
09-07 00:00:39.209:W/Super(28328):0 o 4397out of 16357
09-07 00 :00:40.269:W/Super(28328):-4 o 4398 out of 16389
09-07 00:00:40.299:W/Super(28328):-3 o 4399 out of 16390
09-07 00:00 :40.339:W/Super(28328):-4 o 4400out 16391
09-07 00:00:40.379:W/Super(28328):-4 o 4 401out of 16392
09-07 00:00:40.409:W/Super(28328):-5 o 4402out of 16393
09-07 00:00:40.459:W/Super(28328):-8 4403out 16394
09-07 00:00:40.499:W/Super(28328):-7 o 4404out 16395
09-07 00:00:40.529:W/Super(28328):-3 o 4405out 16396
09-07 00:00:40.569:W/Super(28328):-5 o 4406out 16397
09-07 00:00:40.609:W/Super(28328):-5 o 4407out 16398
09 -07 00:00:40.639:W/Super(28328):-3 o 4408out of 16399
09-07 00:00:40.679:W/Super(28328):-3 o 4409out of 16400
09-07 00:00:40.719:W /超(28328):-4Ø4410out的16401
在平局,我沒有那麼多的位圖繪製。 (大約15位圖,包括着色器,一些效果和縮放的透明度蒙版)。所有位圖都從資源(僅限PNG文件)的create方法中加載。
public void draw(Canvas c)
{
c.drawBitmap(background,0,0,null);
c.drawBitmap(m_image.get(m_cn),400 , 100, test);
c.drawBitmap(start_menu,10 ,10 , test);
c.drawBitmap(inventory_menu, 200 , 10, test);
c.drawBitmap(shop_menu,400 , 10, test);
c.drawBitmap(options_menu, 10 , 300, test);
c.drawBitmap(facebook_menu,200 , 300, test);
light.drawColor(Color.TRANSPARENT, Mode.CLEAR);
light_matrix.setScale(scale_factor, scale_factor);
light_matrix.postTranslate(light_x-mask_aux.getWidth()/2*scale_factor, light_y-mask_aux.getHeight()/2*scale_factor);
light.drawBitmap(mask_aux, light_matrix, test);
copy_the_screen.drawBitmap(buffer.get(b_activ),0,0,test);
sh = new BitmapShader(screen_copy,Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
pnt.setShader(sh);
c.drawARGB(200, 0, 0,0);
c.drawBitmap(mask,0,0 ,pnt);
}
update方法沒有任何意義的複雜性,所以有什麼東西在這兩個函數來完成,以達到更好的FPS。幫助我,請原諒我的英語不好。
好的。更新功能是這樣的:
public void update()
{
m_time++;
if (m_time==2)
{
m_time=0;
m_cn++;
if (m_cn==4)m_cn=0;
}
if (touched==true)
{
light_x=t_x;
light_y=t_y;
scale_factor=t_y/150;
}
}
它只修改我從精靈中選擇的位圖。我沒有一個包含角色所有位置的大位圖,但有4個不同的位圖。第二個「if」指的是一個掩模圖像,它在我觸摸的地方創建一個光球。我使用該light_matrix來縮放與Y座標(click事件)成比例的光球。這就是爲什麼我使用着色器來創建燈光效果的原因。在這裏,拿上的onTouchEvent一看:
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
//I put this sleep method here because I noticed it was the lagging the game if i let it run
// without a sleep.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// after sleep , i only check for events.
}
這是模擬器還是設備? – 2014-09-06 21:52:17
我正在使用'SurfaceView',迄今爲止我製作了許多2D遊戲而沒有任何問題,我有一些理論知道爲什麼會發生這種情況,但我不太確定,如果您可以發佈'update()'方法並且還描述了什麼'light'和'light_matrix'是我可以發佈答案 – TomTsagk 2014-09-06 23:53:30
@TomTsagk 我在帖子中添加了你想要的信息。 – 2014-09-07 10:30:33