Подгонка Android игры под разные размеры экрана

11

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

user1404512
источник

Ответы:

11

Если вы не используете AbsoluteLayout (как правило, это очень плохая идея, так как вы создаете макет с использованием координат x / y, который будет соответствовать только устройству, на котором он был спроектирован), этого не должно произойти - приложения Android автоматически подстраиваются под размер экрана устройства , Однако из того, что вы описываете (Layout не адаптируется к Table Screen), похоже, что здесь может быть проблема с AbsoluteLayout.

Убедитесь, что в XML-файлах макета вы НЕ используете абсолютные макеты (это включает в себя установку явных координат / ширины / высоты в любом виде просмотра). Вместо этого рассмотрите возможность использования:

  • LinearLayout - укладывает несколько видов по горизонтали или вертикали
  • FrameLayout - обычно содержит один дочерний элемент
  • RelativeLayout - выровнять детей относительно друг друга
  • TableLayout - макет на основе таблицы
  • ScrollView - может содержать один дочерний элемент (например, LinearLayout) и позволяет прокручивать его содержимое

... все, что лучше всего подходит для вашей цели.

Если вы новичок в Android , то Google предлагает хороший учебник, который знакомит с различными типами макетов, упомянутыми выше. Другие учебники можно найти здесь .

Кроме того, ваш уровень API будет иметь отношение (чтобы узнать, используете ли вы Android 2.x или 4.x - я не предполагаю, что 3.x недоступен для смартфонов), чтобы выяснить причину вашей проблемы.

Вы переводите свое приложение в портретный режим, установив:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set screen orientation for this dialog to portrait
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

... в вашей деятельности, которая отображает взгляды игры?

Пожалуйста, предоставьте больше информации о том, как вы создаете макеты ваших представлений (используете ли вы XML для макета, который вы позже раздули в своей деятельности, или вы используете макет в коде в своей деятельности и т. Д ....)? Более того: пробовали ли вы запустить свое приложение на смартфоне и эмуляторе размером с планшет? Если да, проблема сохраняется?


ОБНОВЛЕНИЕ: КАК МАСШТАБИТЬ БИТМАПЫ

ОП спросил, как он может масштабировать растровое изображение, которое он использует в своей игре. Один из вариантов (из всего, что я знаю о настройке OP): SurfaceHolder.Callback, который вы переопределяете для отображения своей игры и в котором вы рендерите все растровые изображения и т.д. ..., имеет метод, который называется:

surfaceChanged(SurfaceHolder holder, int format, int width, int height)

Этот метод дает вам ширину / высоту вашей поверхности, так что теперь вы можете использовать:

Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)

из класса Bitmap . Чтобы изменить размеры ваших изображений пропорционально размеру поверхности, на которую вы рисуете.

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

Скажем, у вас есть растровое изображение A с размерами 25x50 (ширина x высота), которое отображается на экране с размерами 100x200 (ширина x высота). Для этого размера экрана (100x200) растровое изображение имеет правильные размеры - теперь, если вы хотите отобразить растровое изображение на большом экране, вам необходимо:

  • Рассчитать масштабный коэффициент для размера растрового изображения
  • Поддерживать соотношение сторон растрового изображения (чтобы оно не искажалось)

Скажем, больший экран 200x300 (widthxheight), тогда масштабный коэффициент для ширины:

200(target screen width)/100(default screen width) = 2

Таким образом, 2 - это наш масштабный коэффициент для значения ширины и высоты растрового изображения, поскольку нам нужно поддерживать соотношение сторон растрового изображения, мы можем просто умножить масштабный коэффициент на ширину и высоту растрового изображения:

bitmapWidth * 2 = scaledBitmapWidth
bitmapHeight * 2 = scaledBitmapHeight

Таким образом, используя наш пример растрового изображения A сверху и упомянутую формулу, новые размеры растрового изображения будут: 50x100 (widthxheight), потому что:

 2*25(width) = 50 height
 2*50(height) = 100 height

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

   Bitmap.createScaledBitmap (myBitmap, 50, 100, false)

myBitmap в приведенном выше примере является исходным растровым изображением A, которое имеет размеры 25x50 и масштабируется до 50x100 с использованием приведенного выше фрагмента кода.


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

  • Используете ли вы игровой движок, такой как AndEngine или Unity ?
  • Вы пишете свой макет в XML? Если да, каков ваш root-макет для рендеринга вашего игрового контента?
  • Вы упомянули, что внедряете SurfaceHolder.Callback? Ширина / высота, указанная в вызове метода surfaceChanged, дает размер поверхности. Это тот же самый размер, когда ваше приложение работает на смартфоне или планшете?
  • Есть ли у вас доступ к SurfaceView (или к тому, что связано с этим SurfaceHolder. Обратный вызов, который вы реализуете), чтобы мы могли определить, является ли это жестким заданием размера приложения для размера смартфона.
  • Возникают ли одинаковые проблемы изменения размера в эмуляторе с разными разрешениями экрана?

Общее подозрение: не все смартфоны имеют одинаковый размер экрана, на самом деле существует широкий диапазон размеров экрана, что заставляет меня задуматься: тестировали ли вы когда-нибудь свое приложение на смартфоне с экраном другого размера? Потому что тот факт, что он соответствует вашему экрану, а не планшету, заставляет задуматься, кто и когда устанавливает эти размеры. Потому что я сомневаюсь, что приложение может приспосабливаться ко всем размерам экрана смартфона, но не к размеру планшета - не будет иметь особого смысла (потому что на них более или менее работает одно и то же ядро ​​Android, некоторые различия между sx, 3. x и 4.x в сторону) ЕСЛИ вы не используете платформу, которая не поддерживает (по какой-либо причине - может быть, вам придется купить дополнительную поддержку планшета или что-то еще) с размерами экрана планшета. Вот почему очень важно знать, правильно ли изменяется размер приложения только на вашем телефоне, или на других смартфонах. Единственный способ узнать, как приложение может быть ограничено размером экрана одного конкретного телефона, - это использовать AbsoluteLayout и вообще абсолютные размеры для виджетов и т. Д.


ОБНОВЛЕНИЕ: Масштабирование x / y координат

Чтобы настроить местоположение вашего растрового изображения в соответствии с размером экрана, нужно выполнить что-то вроде следующего:

  • Размеры экрана: 100/200 (ширина / высота)
  • Расположение растрового изображения: x = 50 / y = 100

Теперь, если вы увеличите размер экрана, вам придется масштабировать эти значения x / y вдоль:

  • Размеры экрана: 200/400 (ширина / высота)

Коэффициент масштабирования будет равен 2, потому что ширина и высота одинаково увеличены в два раза. Следовательно, размеры будут ...

  • Расположение растрового изображения: x = 100 / y = 200

Еще одна попытка - на этот раз с разными масштабными коэффициентами для ширины / высоты

  • Размеры экрана: 100/150 (ширина / высота)
  • Расположение растрового изображения: x = 50 / y = 50

Если новый целевой экран - 150/250, то расчеты:

  • Коэффициент масштабирования для ширины = targetWidth / originalWidth = 1,5
  • Коэффициент масштабирования для высоты = targetHeight / originalHeight = 1.666 ... (Период)

Теперь нам нужно масштабировать координаты x / y, x масштабируется с использованием width-scale, а height масштабируется с использованием height-scale, вот результат:

  • х = оригинал Х * 1,5 = 75
  • y = originalY * 1.666 .. (период) = 83.333 ... (период)

Таким образом, новые размеры экрана и масштабированные координаты x / y:

  • ширина = 150
  • высота = 250
  • х = 75
  • у = 83,333 ... (период)

Короче говоря, алгоритм масштабирования растровых изображений:

X = (targetScreenWidth / defaultScreenWidth) * defaultXCoordinate
Y = (targetScreenHeight / defaultScreenHeight) * defaultYCoordinate
Zainodis
источник
Моя игра использует игровую панель, которая расширяет SurfaceHolder.Callback (она находится в XML-файле, который вызывается Activity). Может ли это быть частью проблемы?
user1404512
@ user1404512 SurfaceHolder.Callback обычно связан с SurfaceView - и это также зависит от того, как настроен SurfaceView (ширина / высота), если он встроен в другой Layout (например, FrameLayout и т. д.) ... в ваш A SurfaceHolder.Callback там должен быть метод: public void surfaceChanged (держатель SurfaceHolder, формат int, int width, int height) ширина и высота должны соответствовать размеру того, что рисуется на экране - что в вашем случае будет одинаковым для планшетов и смартфонов - может ты это проверяешь?
AgentKnopf
Да, я думаю, что должен сказать следующее: когда я запускаю его на своем планшете, даже если размер экрана больше, все растровые изображения имеют одинаковый размер. Есть ли способ сделать так, чтобы растровые изображения оставались одинаковыми даже на экранах разных размеров?
user1404512
@ user1404512 Очень важно, чтобы вы ответили на все те вопросы, которые мы задавали вам, потому что мы все еще не знаем, как устроен ваш макет, что затрудняет ответ на любой конкретный вопрос. Что касается ваших растровых изображений: я обновил свой ответ, чтобы как можно лучше ответить на вопрос о масштабировании растровых изображений, учитывая, что очень мало известно о вашей настройке.
AgentKnopf
Нет, я не использую игровой движок. У меня есть мой макет в XML, и в моем XML-файле у меня есть SurfaceHolder.Callback, который является весь экран. Ширина и высота держателя меняются от экрана к экрану. Я думаю, что моя проблема в том, что я рисую растровые изображения с координатами X и Y, но масштаб растровых изображений остается неизменным от экрана к экрану. Есть ли способ это исправить? Заранее большое спасибо!
user1404512
3

На Android.com есть хорошая и актуальная статья: http://developer.android.com/guide/practices/screens_support.html

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

Помните, что вы также можете создавать различные конфигурации виртуальных устройств Android для эмулятора во время тестирования макета и внешнего вида: http://developer.android.com/guide/developing/devices/emulator.html

AMB
источник
0

Просто выстрел в темноте здесь. Вы установили основной макет для заполнения родительского элемента как по вертикали, так и по горизонтали?

Дерек
источник