Размер растрового изображения превышает бюджет виртуальной машины при разработке игры

Я разрабатываю игру на android.Like Tower Defense. Я использую представление поверхности. Я использую какое-то изображение в виде растрового изображения (таблицы спрайтов, наборы плиток, кнопки, фоны, эффекты и т. Д.). Теперь изображения весят почти 5-6 МБ. И я получаю эту ошибку, когда запускаю игру:

Размер растрового изображения превышает бюджет виртуальной машины

Внешнее выделение 19464192 байта слишком велико для этого процесса.

Я называю такие изображения

BitmapFactory.decodeResource(res, id)

и я помещаю его в массив. Я не могу масштабировать изображения. Я использую их все. я пробовал это

options.inPurgeable=true;  

и это работает, но изображение загружается очень медленно. Я загружаю спрайт-лист с этим, и когда он загружается, я получаю очень-очень низкий fps.

Что я могу сделать?


person Nafiz Bayındır    schedule 31.03.2012    source источник


Ответы (2)


У меня тоже была эта проблема; на самом деле нет другого решения, кроме как уменьшить количество/размер растровых изображений, которые вы загрузили сразу. Некоторые старые Android-устройства выделяют в куче только 16 МБ для всего вашего приложения, а растровые изображения хранятся в памяти в несжатом виде после их загрузки, поэтому несложно превысить 16 МБ с большими фонами и т. д. (32-битное растровое изображение 854x480 составляет около 1,6 МБ без сжатия.)

В моей игре я смог обойти это, загрузив только растровые изображения, которые я собирался использовать на текущем уровне (например, у меня есть один объект Bitmap для фона, который перезагружается из ресурсов каждый раз, когда он изменяется, вместо того, чтобы поддерживать несколько растровых изображений. в памяти.Я просто поддерживаю int, который отслеживает, какой ресурс я загрузил в данный момент.)

Ваш лист спрайтов огромен, поэтому я думаю, что вы правы в том, что вам нужно уменьшить размер ваших анимаций. В качестве альтернативы, загрузка из ресурсов происходит довольно быстро, так что вы можете обойтись чем-то вроде загрузки полосы анимации только для текущего направления персонажа и сделать небольшую паузу, когда он поворачивается, пока вы заменяете ее новой полосой анимации. Хотя это может быть сложно.

Кроме того, я настоятельно рекомендую протестировать ваше приложение на эмуляторе с кучей виртуальной машины, установленной на 16 МБ, чтобы убедиться, что вы устранили проблему для всех устройств. (Эмулятор обычно по умолчанию имеет размер 24 МБ, поэтому его легко не протестировать и получить несколько отзывов с 1 звездой после выпуска.)

person Luke    schedule 07.07.2012

Я не разработчик игр, однако мне хотелось бы думать, что я достаточно знаю Android.

Загрузка изображений такого размера почти наверняка вызовет ошибки. Почему изображения такого размера?

Пример приведен по адресу http://p-xr.com/android-tutorial-how-to-paint-animate-loop-and-remove-a-sprite/. Если вы заметили, что у него спрайт взрыва всего ~200Кб. Даже более детальное изображение не заняло бы намного больше места в файле.

ОК некоторые предложения:

  • Вы загружаете все листы спрайтов на один лист или каждый лист спрайтов находится в отдельном файле? Если они все в одном, я бы разделил их.

  • Уменьшите разрешение изображений, устройства Android являются портативными, а некоторые имеют только экран с низким разрешением. Например, HTC Wildfire имеет разрешение 240x320 (устройство LDPI) и является довольно распространенным устройством. Вы не указали размеры изображения, поэтому мы не можем быть уверены, что это практично.

Ну наконец то; Я не программист игр, но этот учебник (часть той же серии) показался мне весьма поучительным — http://p-xr.com/android-tutorial-2d-canvas-graphics/. Интересно, применяете ли вы шаблон, который не подходит для Android, однако без кода я не могу сказать.

Правильно, немного не по теме, но стоит отметить...

Люди недооценивают силу представления. Несмотря на то, что в использовании SurfaceView есть определенная логика, стандартное представление довольно много делает само по себе. SurfaceView чаще всего требует запуска базового потока (который вам придется настроить самостоятельно), чтобы заставить его работать. Однако View вызывает onDraw(), который можно использовать различными способами, включая метод postinvalidate() (см. What делает postInvalidate()?).

В любом случае, возможно, стоит ознакомиться с этим руководством http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/. Лично это был отличный пример пользовательского представления и того, что вы можете с ним сделать. Я переписал несколько разделов и сделал приложение для карманных часов.

person Graham Smith    schedule 01.04.2012
comment
Я благодарен за вашу помощь, но я не могу решить. Я использую большой спрайт-лист, потому что слишком много анимации. Например, это спрайт-лист существа из моей игры: nafiz.in /bigeye.png Я использую Galaxy S, и я использую эти таблицы спрайтов в полном размере. Во-первых, я должен работать на своем устройстве. Вероятно, для растрового изображения существует ограничение в 7-8 МБ. Я снова провел исследование и обнаружил, что для решения этой проблемы я должен использовать jni или opengl. Но в этом смысле я не могу их использовать. Возможно, другой проект. Поэтому я удалю некоторые анимация и работа над управлением кучей. - person Nafiz Bayındır; 03.04.2012