[Проект] Как фиксировать камеру на игроке если игровой мир - большой?
Представим что у вас в игре есть некий мир (например некая карта замка и его окрестностей). Игровой персонаж - Единорог - исследует и взаимодействует с этим миром, делая его лучше:
При этом мир слишком большой и если мы его будем показывать на экране целиком, то игрок не сможет разглядеть маленькие объекты вокруг главного игрового персонажа.
Поэтому на иллюстрации:
- Зеленым - обведена система координат мира игры
- Красным - обведена система координат того что показывается на экране (размера \(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
).