游戏开发中出现Bitmap大小超过VM内存限制的问题

6

我正在开发一款Android游戏,类似于塔防游戏。

我正在使用SurfaceView。我使用一些图像作为位图(精灵表、瓷砖集、按钮、背景、效果等)。

现在这些图像将近有5-6 MB。当我运行我的游戏时,我会遇到以下错误:

Bitmap size exceeds VM budget

19464192字节的外部分配对于此进程过大。

我是这样调用这些图像的:

BitmapFactory.decodeResource(res, id)

我把它放到了数组中。我无法对图片进行缩放,因为我正在使用它们。我尝试过那种方法。

options.inPurgeable=true;  

我的程序可以工作,但是图片加载非常缓慢。我使用了一个精灵表,并且当它在加载时,帧率非常低。

我该怎么办?

2个回答

2
我也曾遇到这个问题;除了降低一次加载的位图数量/大小,真的没有其他解决方法。一些旧版的Android设备只为整个应用程序分配16MB的堆空间,加载位图后它们将以未压缩的形式存储在内存中,因此通过加载大型背景等很容易超出16MB。(一个854x480的32位位图在未压缩时约为1.6MB。)
在我的游戏中,我通过仅加载当前关卡中使用的位图来规避这个问题(例如,我只维护一个位图对象用于背景,并每次更改时从资源重新加载,而不是在内存中维护多个位图。我只维护一个跟踪我当前加载哪个资源的int变量。)
你的精灵表非常庞大,所以我认为你需要缩小动画的大小。或者,从资源加载速度相当快,因此你可以尝试仅加载角色当前方向的动画条纹,并在他转弯时稍作停顿,然后用新的动画条纹替换它。但这可能会变得复杂。
另外,我强烈建议在模拟器上测试你的应用程序,VM堆大小设置为16MB,以确保你已为所有设备解决了问题。(模拟器通常默认为24MB,因此很容易未经测试就发布,然后产生一些1星评论。)

0

虽然我不是游戏开发者,但我认为我已经足够了解Android了。

加载大小的图像几乎肯定会引发错误。为什么这些图片这么大?

http://p-xr.com/android-tutorial-how-to-paint-animate-loop-and-remove-a-sprite/有一个例子。如果你注意到,他有一个只有约200Kb的爆炸精灵。即使是更详细的图像也不会占用更多的文件空间。

好的,一些建议:

  • 你是否将所有的精灵表加载到一个单独的表中,还是每个精灵表都在单独的文件中?如果它们都在一个文件中,我会把它们分开。

  • 降低图像的分辨率,Android设备是便携的,并且一些只有低分辨率屏幕。例如HTC Wildfire具有240x320(LDPI设备)的分辨率,是相当常见的设备。您没有说明图像尺寸,因此我们无法确定是否可行。

最后;虽然我不是游戏程序员,但我发现这个教程(系列的一部分)非常有启发性 - http://p-xr.com/android-tutorial-2d-canvas-graphics/。我想知道你是否应用了一个对Android来说不合适的模式,但是没有代码我无法确定。

稍微离题但值得注意的一点...

人们低估了View的力量。虽然使用SurfaceView有一定的逻辑,但是标准的View本身就可以做很多事情。SurfaceView通常需要一个底层线程来运行(你需要自己设置),才能使其工作。而View则调用onDraw()方法,可以以各种方式利用,包括postInvalidate()方法(参见What does postInvalidate() do?)。

无论如何,值得一提的是,可以查看这个教程http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/。对我来说,它是一个关于自定义视图以及你可以用它们做什么的绝佳示例。我重写了几个部分并制作了一个怀表应用程序。

感谢您的帮助,但我无法解决。 由于动画太多,我使用了大型精灵表。例如,这是我的游戏中某个生物的精灵图: http://nafiz.in/bigeye.png 我使用Galaxy S,并且正在使用此精灵表的全尺寸。首先,我必须在我的设备上进行操作。 位图可能有7-8 MB的限制。我再次进行了研究,发现要解决这个问题,我必须使用JNI或OpenGL。但是那一点,我不能使用它们。也许可以在其他项目中使用。因此,我将删除一些动画并处理堆管理。 - Nafiz Bayındır

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接