Для масштабирования игр, над которыми я работаю, я использую комбинацию класса a, чтобы захватить ввод с помощью пинча, и класса, который рассматривает экран как окно просмотра.Настоящим «секретным соусом» здесь является область просмотра.
Вам нужно обращаться с экраном, как будто это «прямоугольник в коробке», и применять линейные преобразования для отображения между пиксельным пространствомэкран и «игровое пространство» объектов в вашей игре.Я обычно использую Box2D под игрой, поэтому все игры в «метрах».
Окно просмотра работает так, как показано на схеме ниже:
Общий метод отображения границ мирового пространства(Wxmin, Wxmax) на координаты экрана (0, Sxmax) осуществляется путем линейного отображения с формулировкой ay = mx + b.Учитывая две известные точки для преобразования:
Wxmin (метры) отображается на (пиксель) 0, а Wxmax (метры) отображается на (пиксель) Sxmax Solving y0 = m x0 + b и y1 = m x1 + b1 дает:
m = Sxmax / (Wxmax - Wxmin) и b = -Wxmin * Sxmax / (Wxmax - Wxmin) (= -m * Wxmin) Заменим (Wxmax - Wxmin)с масштабом * (Wxmax-Wxmin) для измерения x и масштабом * (Wymax-Wymin) / aspectRatio в измерении y.
Значение (Wxmax - Wxmin) = масштаб * worldSizeMeters (xDimension)
Значение Wxmin = центр области просмотра - 1/2 ширины области просмотра
и т. Д.
В коде:
void Viewport::CalculateViewport()
{
// Bottom Left and Top Right of the viewport
_vSizeMeters.width = _vScale*_worldSizeMeters.width;
_vSizeMeters.height = _vScale*_worldSizeMeters.height/_aspectRatio;
_vBottomLeftMeters.x = _vCenterMeters.x - _vSizeMeters.width/2;
_vBottomLeftMeters.y = _vCenterMeters.y - _vSizeMeters.height/2;
_vTopRightMeters.x = _vCenterMeters.x + _vSizeMeters.width/2;
_vTopRightMeters.y = _vCenterMeters.y + _vSizeMeters.height/2;
// Scale from Pixels/Meters
_vScalePixelToMeter.x = _screenSizePixels.width/(_vSizeMeters.width);
_vScalePixelToMeter.y = _screenSizePixels.height/(_vSizeMeters.height);
// Offset based on the screen center.
_vOffsetPixels.x = -_vScalePixelToMeter.x * (_vCenterMeters.x - _vScale*_worldSizeMeters.width/2);
_vOffsetPixels.y = -_vScalePixelToMeter.y * (_vCenterMeters.y - _vScale*_worldSizeMeters.height/2/_aspectRatio);
_ptmRatio = _screenSizePixels.width/_vSizeMeters.width;
Notifier::Instance().Notify(Notifier::NE_VIEWPORT_CHANGED);
}
Сам класс Viewport предоставляет методыдля вычисления точек из одного пространства в другое, а также для вычисления ptmRatio (отношение пикселей к метрам), которое отображает размер чего-либо в пространстве экрана (в пикселях) на что-то в игровом пространстве (в метрах). Это позволяет вам динамически изменять размер ваших спрайтов при увеличении / уменьшении.
Существует большая статья, описывающая здесь и код github .
Было ли это полезно?