3

嘿,我正处于我一直在开发的应用程序的十字路口。

这是一款游戏和“街机/动作”游戏,但我使用 Surfaceview 而不是 Open GL 对其进行了编码(结果就是这样,因为游戏与原始设计发生了巨大变化)。

我发现自己受到性能问题的困扰,甚至在游戏中也没有,而只是在第一个活动中,这是一个动画菜单(全屏背景,大约 8 个精灵漂浮在屏幕上)。

即使有这么少量的精灵,我也无法获得完美平滑的运动。他们平稳地移动了一段时间,然后瞬间变得“波涛汹涌”或“生涩”。

我注意到(据我所知)背景(预先缩放的图像)大约需要 7 到 8 毫秒来绘制。这合理吗?我尝试了不同的绘画方式,例如:

    canvas.drawBitmap(scaledBackground, 0, 0, null);

上面的代码产生大致相同的结果:

    canvas.drawBitmap(scaledBackground, null, screen, null);

但是,如果我将持有人更改为:

    getHolder().setFormat(PixelFormat.RGBA_8888);

位图的绘图最高可达 13 毫秒(我假设是因为它必须转换为 RGB_8888 格式。

奇怪的是,渲染和逻辑以非常稳定的 30fps 移动,它不会丢帧,运行时也不会发生垃圾收集。

我已经尝试了几乎所有我能想到的让我的精灵顺利移动的方法

我最近在我的游戏循环中加入了插值:

    float interpolation = (float)(System.nanoTime() + skipTicks - nextGameTick)
              / (float)(skipTicks);

然后我将它传递给我的 draw() 方法:

    onDraw(interpolate)

我在这方面取得了一些成功,它确实帮助解决了问题,但我仍然对结果不满意。

任何人都可以给我任何最终提示,可能会减少绘制位图所需的时间或任何其他可能导致此问题的提示,或者您是否认为这只是 Surfaceview 无法完成任务的情况,因此,我应该报废吗应用程序并从 Open GL 重新开始?

这是我的主要游戏循环:

int TICKS_PER_SECOND = 30;
int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
int MAX_FRAMESKIP = 10;

long next_game_tick = GetTickCount();
int loops;

bool game_is_running = true;
while( game_is_running ) {

    loops = 0;
    while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
        update_game();

        next_game_tick += SKIP_TICKS;
        loops++;
    }
    interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
                    / float( SKIP_TICKS );
    display_game( interpolation );
}

谢谢

4

1 回答 1

2

您不应该使用 Canvas 来绘制快速精灵,尤其是在绘制全屏图像时。时间太长了,我从经验告诉你。我相信 Canvas 不是硬件加速的,这是您永远无法从中获得良好性能的主要原因。当屏幕上有大约 15 个时,即使是简单的精灵也会开始缓慢移动。切换到 OpenGL,进行正交投影,并为每个 Sprite 制作一个带纹理的四边形。相信我,我做到了,而且值得付出努力。

编辑:实际上,OpenGL 方法不是使用 SurfaceView,而是使用 GLSurfaceView。您创建自己的类,从它派生,实现surfaceCreated、surfaceDestroyed 和surfaceChanged,然后您也从Renderer 派生并连接两者。Renderer 处理一个 onDraw() 函数,该函数将渲染什么,GLSurfaceView 管理您将如何渲染(位深度、渲染模式等)

于 2013-02-26T09:03:55.910 回答