Android-фон прокрутки растровых плиток - PullRequest
8 голосов
/ 25 мая 2010

Я пытался определить «лучший» способ прокрутки фона из мозаичных растровых изображений на Android SurfaceView. Я действительно преуспел в этом, но хотел определить, есть ли более эффективный метод, или мой метод может не работать на всех телефонах Android.

По сути, я создаю новое, изменяемое растровое изображение, которое будет немного больше, чем размеры моего SurfaceView. В частности, мое растровое изображение содержит дополнительную линию плиток сверху, снизу, слева и справа. Я создаю холст вокруг своего нового растрового изображения и рисую на нем свои растровые плитки. Затем я могу прокрутить вверх к плитке в любом направлении, просто нарисовав подмножество размера поверхности для моего растрового изображения фона на холсте SurfaceHolder.

Мои вопросы:

  1. Есть ли лучшая техника блитов, чем рисование фонового растрового изображения на холсте моего SurfaceHolder?

  2. Каков наилучший ход действий, когда я прокручиваю до края моего фонового растрового изображения и хочу сдвинуть карту на одну длину плитки? На мой взгляд, у меня есть следующие варианты:

а. Перерисовать все плитки на моем фоне в отдельности, сместить длину плитки в одном направлении. (Это кажется мне неэффективным, так как это повлечет за собой много маленьких растровых изображений).

б. Просто сделайте фоновый рисунок настолько большим, что он охватит весь мир прокрутки. (Это может потребовать очень большого растрового изображения, но его нужно будет создать только один раз.)

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

Спасибо, что прочитали все это, и я был бы очень признателен за любой совет.

Ответы [ 4 ]

4 голосов
/ 26 июля 2011

Первоначально я использовал аналогичную вам технику в моей платформерной игре Box Fox и в RTS, но обнаружил, что она вызывает довольно заметные задержки, если вы прокручиваете достаточно, чтобы растр нужно было перерисовать.

Мой нынешний метод в этих играх похож на ваш вариант C. Я рисую слои мозаичной карты на сетке больших растровых изображений (около 7x7), занимая область, большую, чем экран. Когда пользователь прокручивает край этой сетки, я перекладываю все растровые изображения в сетке (перемещая конечные растровые изображения вперед), меняю смещение сетки, а затем просто перерисовываю новый край.

Я не совсем уверен, что быстрее с программным рендерингом (ваш вариант C или мой текущий метод). Я думаю, что мой метод может быть быстрее, если вы когда-нибудь переключитесь на рендеринг OpenGL, поскольку вам не придется загружать столько данных текстуры на видеокарту, сколько пользователь прокручивает.

Я бы не рекомендовал вариант А, потому что, как вы предлагаете, сотни маленьких растровых изображений для мозаичной карты снижают производительность, и с большими экранами она становится довольно плохой. Вариант B может даже оказаться невозможным на многих устройствах, так как довольно легко получить ошибку «размер растрового изображения превышает бюджет виртуальной машины», поскольку на многих телефонах ограничение пространства кучи достаточно мало.

Также, если вам не нужна прозрачность на вашей карте / фоне, попробуйте использовать растровые изображения RGB_565, так как в программном обеспечении намного быстрее рисовать и использовать меньше памяти.

Между прочим, я получаю ограничение 60 кадров в секунду на своем телефоне и 10 "планшете в моей RTS описанным выше способом, визуализируемом с помощью программного обеспечения, и могу плавно прокручивать карту. рендерер программного обеспечения для Android. У меня есть 2D-оболочка OpenGL, созданная для моей игры, но пока не нужно переключаться на нее.

1 голос
/ 27 июля 2011

Мое решение в картографическом приложении основано на двухуровневом кеше, первые объекты листов создаются с помощью растрового изображения и позиции, они либо хранятся на диске, либо в векторе (синхронизация важна для меня, многопоточный HTTP-обмен данными везде место).

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

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

1 голос
/ 27 июля 2011

Я думаю, что одним из эффективных способов сделать это было бы использование canvas.translate .

На первом рисунке весь холст должен быть заполнен плиткой. Новые телефоны на базе Android могут сделать это легко и быстро.

Когда фон прокручивается, я бы использовал canvas.translate(scrollX, scrollY),, тогда я рисовал бы индивидуально одну плитку, чтобы заполнить промежутки, НО, я бы использовал canvas.drawBitmap(tileImage[i], fromRect, toRect, null), который будет рисовать только те части плиток, которые необходимо отобразить, установив fromRect и toRect, чтобы они соответствовали scrollX и scrollY.

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

EDIT: Однако существует проблема с использованием canvas.translate с surfaceView, так как он с двойной буферизацией и canvas.translate будет транслировать только один буфер, но не второй одновременно, так что это чередование буферов необходимо учитывать при в SurfaceView для сохранения нарисованного изображения.

0 голосов
/ 13 ноября 2012

Я использую ваш оригинальный метод для рисования перспективного фона прокрутки. Я придумал эту идею совершенно случайно несколько дней назад, когда возился с простой техникой, чтобы провести симуляцию поля звездной перспективы. Приложение можно найти здесь: Aurora2D.apk

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...