我试图创建一个弹壳游戏,我遇到了一些麻烦。在大约500发子弹之后我不能超过17 fps。所有更新逻辑代码大约需要1-4ms,而渲染代码需要大约40ms
现在我的代码是
private void drawEntities(Canvas canvas) {
for (HashMap<UUID, Spatial> h: spatialList) {
for (Spatial spatial: h.values()) {
spatial.render(canvas);
if(spatial.life > 0)
spatial.life--;
else if (spatial.life == 0)
engine.deleteEntity(spatial.owner);
}
}
}
spatialList是一个arrayList,其中每个索引都是zLevel
显示实际子弹的空间是
public void render(Canvas canvas) {
float angle = (float) (vel.getAngle() * (180 / Math.PI));
matrix.reset();
matrix.setTranslate(pos.x - bullet.getWidth() / 2, pos.y - bullet.getHeight() / 2);
matrix.postRotate(angle + 90, pos.x, pos.y);
canvas.drawBitmap(bullet, matrix, paint);
canvas.drawCircle(pos.x, pos.y, col.getRadius(), paint);
}
我可以提供更多代码,但这些似乎是主要问题。我已经尝试了所有我能想到的东西,并且无法在线找到其他东西。我唯一能想到解决这个问题的方法就是从surfaceview切换到GLSurfaceview,但我真的认为有一种更好的方法,我只是使用不好的代码。
编辑:我注意到我的计时器已关闭并移除了drawcircle并且在再次运行之后我得到40ms~大约500,这对于合理的性能来说仍然有点太低。
TLDR; 500个实体= 17 fps。
答案 0 :(得分:5)
您可能受到像素填充率的限制。测试设备上的显示器有多大(以像素为单位)?
一个简单的方法是使用setFixedSize()
来减小SurfaceView的Surface的大小。这样可以减少您触摸的像素数量。示例here,视频here,博文here。
这样做通常是一个好主意,因为较新的设备似乎正在向荒谬的像素计数竞争。在软件中执行所有渲染的全屏游戏将在2560x1440显示器上挣扎,并且在4K时非常眩晕。 &#34;限制&#34;将游戏改为1080p并让显示缩放器完成重任应该有所帮助。根据游戏的性质,您可以将分辨率设置得更低,而不会明显降低质量。
要尝试的另一件事是取消drawBitmap()
来电,检查您的时间,然后将其恢复并消除drawCircle()
来电,看看是否有一个或另一个在大部分时间咀嚼
您可能会发现切换到OpenGL ES并不是那么糟糕。 &#34;硬件缩放器训练器&#34; Grafika中的活动(来自上面链接的视频)显示了一些简单的位图渲染。将drawCircle()
替换为缩放位图,您可能已完成大部分工作。 (注意它在该活动中使用SurfaceView而不是GLSurfaceView用于GLES。)
答案 1 :(得分:2)
我有同样的问题。如果您在位图帧缓冲区上执行所有绘制,然后将帧缓冲区绘制到画布,则问题将在很大程度上得到解决。如果你直接在画布上绘图,那么有几个开销。我环顾四周,发现了这个教程 &#34; http://www.kilobolt.com/day-6-the-android-game-framework-part-ii.html&#34;
查看AndroidGraphics和AndroidFastRenderView的实现,看看他如何使用AndroidGraphics在缓冲区中进行所有实际绘制,并在AndroidFastRenderView中绘制缓冲到画布。
答案 2 :(得分:0)
从render()方法中删除rotate和/或drawCircle部分时尝试演奏。它们都可能非常耗时,因为它们可能包含sin()/ cos()计算。
如果这有帮助,你必须弄清楚如何用更快的东西替换它们,如果没有,那么......