Представим что у вас в игре есть некий мир (например некая карта замка и его окрестностей). Игровой персонаж - Единорог - исследует и взаимодействует с этим миром, делая его лучше:

Иллюстрация игры с большим миром

При этом мир слишком большой и если мы его будем показывать на экране целиком, то игрок не сможет разглядеть маленькие объекты вокруг главного игрового персонажа.

Поэтому на иллюстрации:

  • Зеленым - обведена система координат мира игры
  • Красным - обведена система координат того что показывается на экране (размера \(w\) на \(h\)) - т.е. небольшой окрестности вокруг игрока, которая отображается на весь игровой экран:

Вводим систему координат мира и экрана

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

Теперь осталось лишь в момент когда код выполняет отрисовку мира на экране научиться делать переход из системы координат мира в систему координат экрана.

Т.е. нам осталось придумать функцию \(f(x_{world}, y_{world}) = ... = (x_{screen}, y_{screen})\), такую что:

  • Игрок обязательно должен быть в центре экрана, т.е. \(f(x_0, y_0) = (w/2, h/2)\)
  • Масштаб может быть произвольным (возможно он меняется - в зависимости от скорости движения персонажа, или от колесика мышки), поэтому давайте введем некий коэффициент \(s\) (от слова scale = масштаб), он будет говорить сколько пикселей в одном метре

Давайте тогда придумаем как пересчитать координаты для произвольной печеньки из координат мира в пиксельныекоординаты экран:

Упражнение Попробуйте сами вывести формулу которая удовлетворяет двум вышеописанным свойствам

Как рассчитать координаты в экране для каждого объекта

Итак, мы хотим чтобы в метре было \(s\) пикселей и чтобы функция переводила координаты игрока в центр экрана, т.е. \(f(x_0, y_0) = (w/2, h/2)\).

Давайте выведем общий вид формулы:

1) Во-первых, переведем изначальные метровые координаты в пиксели (т.е. \(s \cdot x, s \cdot y\))

2) Во-вторых, учтем что мы хотим сместить координаты на некие \((x_{shift}, y_{shift})\) так чтобы игрок оказался в центре экрана, т.е.:

\[f(x_0, y_0) = (w/2, h/2) \implies (s \cdot x_0 + x_{shift}, s \cdot y_0 + y_{shift}) = (w/2, h/2) \implies (x_{shift}, y_{shift}) = (w/2 - s \cdot x_0, h/2 - s \cdot y_0)\]

Т.о. формула для пересчета метровых координат мира в пиксельные координаты экрана вокруг игрока:

\[f(x_{world}, y_{world}) = (s \cdot x_{world} + w/2 - s \cdot x_0, s \cdot y_{world} + h/2 - s \cdot y_0) = (x_{screen}, y_{screen})\]

Где:

  • \(x_0, y_0\) - координаты игрока в мировых координатах
  • \(s\) - произвольно выбранный масштаб - сколько пикселей в метре
  • \(w, h\) - размеры экрана в пикселях

Как это выразить в коде?

Сделайте методы int toScreenX(int worldX) и int toScreenY(int worldY) в классе откуда будет доступ до:

  • размера окна (\(w, h\))
  • координат игрока в мировых координатах (\(x_0, y_0\))

Реализуйте в этих методах формулы которые переводят соответственно из системы координат мира в систему координат экрана с учетом того какого размера окно и где находится игрок.

Теперь в месте где вызывается отрисовка предмета (например печеньки) - выполняйте отрисовку картинки с учетом данных преобразований (вызвав эти методы toScreenX и toScreenY).