Android - определить конкретные местоположения (координаты X, Y) на растровом изображении в разных разрешениях? - PullRequest
2 голосов
/ 11 ноября 2010

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

Перед использованием растровых изображений я сначала создал доску и границу, нарисовав ее вручную - drawLine & drawRect. Я решил, сколько пикселей по ширине будет основано на ширине и высоте экрана, передаваемых в onSizeChanged. Оставшийся экран я разделил на количество нужных мне столбцов или строк.

Для примера, скажем, размеры экрана 102 x 102.

Возможно, я решил установить границу в 1 и установить количество строк и столбцов в 10. Это оставило бы 100 х 100 влево (уменьшенный на два, чтобы учесть верхнюю и нижнюю границу, а также влево / вправо граница). Затем, если для столбцов и строк задано значение 10, для высоты и ширины останется 10 пикселей.

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

Теперь, как это работает с растровыми изображениями? То есть, если я создам 3 разных фоновых растровых изображения, по одному для каждой плотности, они не будут по-прежнему изменяться в соответствии с разрешением экрана каждого устройства, потому что из того, что я прочитал, было не только 3 разрешения экрана, но 5, а теперь и для планшетов - даже Больше. Если я или Android масштабируем растровые изображения вверх или вниз, чтобы соответствовать текущему размеру экрана устройства, как я узнаю, насколько широкая граница масштабируется и размеры каждого квадрата, чтобы выяснить, куда перемещать фигуру или вычислить, где игрок прикосновение. Пока что примеры, которые я рассмотрел, просто показывают, как масштабировать общее растровое изображение и получить общую ширину и высоту растровых изображений. Но я не понимаю, как определить, сколько пикселей в ширину или высоту будет у каждой части доски после ее масштабирования. Когда я рисую каждую линию и прямоугольник на основе размеров экрана из onSizeChanged, я всегда знаю эти размеры.

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

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


 @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
      intScreenWidth = w;
      intScreenHeight = h;

      // Set Border width - my real code changes this value based on the dimensions of w
      // and h that are passed in. In other words bigger screens get a slightly larger
      // border.
      intOuterBorder = 1;

      /** Reserve part of the board for the boardgame and part for player controls & score
          My real code forces this to be square, but this is good enough to get the point
          across.
      **/
      floatBoardHeight = intScreenHeight / 4 * 3;

      // My real code actually causes floatCellWidth and floatCellHeight to
      // be equal (Square).
      floatCellWidth = (intScreenWidth - intOuterBorder * 2 ) / intNumColumns;
      floatCellHeight = (floatBoardHeight - intOuterBorder * 2) / intNumRows;

      super.onSizeChanged(w, h, oldw, oldh);
   }


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

Теперь я проверю его, чтобы проверить, но я ожидаю, что он будет работать на основе того, что я видел в примере Snake SDK.

- Mike


Я проверил способ сделать то, что я просил, и это похоже на работу. Вот что я сделал:

Я создал растровое изображение 320 x 320 для доски. Он состоял из бордюра и квадратов (как шахматная доска). Ширина рамки составляла 10 пикселей по всей доске. Квадраты были 20 х 20 пикселей.

Я обнаружил ширину и высоту экрана через onSizeChanged. На дисплее 480 x 800 я бы установил новую ширину платы равной 480 x 480 и использовал бы следующий код для масштабирования всего этого:


protected void onSizeChanged(int w, int h, int oldw, int oldh) {        
    floatBoardWidth = w;
    floatBoardHeight = floatBoardWidth;

    bitmapScaledBoard = Bitmap.createScaledBitmap(bitmapBoard, (int)floatBoardWidth, (int)floatBoardHeight, true);      

        super.onSizeChanged(w, h, oldw, oldh);
}

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

floatBoardScale = floatScreenWidth / 320;

В случае экрана шириной 480, floatBoardScale равен: 1,5. Затем, чтобы вычислить, к чему была масштабирована моя граница в полном растровом изображении, я сделал:

floatBorderWidth = 10 * floatBoardScale;

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

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

Надеюсь, это поможет любому, у кого, возможно, был такой же вопрос. Кроме того, если у кого-то есть лучший способ выполнить то же самое, пожалуйста, опубликуйте его.

1 Ответ

2 голосов
/ 11 ноября 2010

Пара вещей.Во-первых, начните читать о том, как поддерживать несколько экранов. Обратите особое внимание на изучение провалов и их работы.

Далее посмотрите это видео (по крайней мере,первые 15-20 минут).

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

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

Наконец, вам следует рассмотреть вопрос о том, как свести вопрос к себе, чтобы быть более понятным, если вы не 'ищу абстрактный ответ (как этот).

Удачи!

...