Общий шаблон для масштабирования «реальных единиц» в пикселях?

10

Это дополнительный вопрос к этому другому .

Я хотел бы знать , существует ли общий / типичный / лучший шаблон для масштабирования моего представления о мире (в настоящее время 160Kmx160Km), чтобы соответствовать его области рисования (в настоящее время 800x600 пикселей).

Я могу придумать как минимум четыре разных подхода:

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

drawCircle(sc(radius), sc(position))

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

Функция декоратора . Я мог бы просто украсить существующие функции промежуточного программного обеспечения, обеспечивая автоматическое масштабирование для всех параметров, которые являются экземплярами класса Vector3D, но проблема в том, что эти функции также работают с одинаковыми параметрами listили Vector2Dслишком, и у декоратора не было бы возможности узнать какие списки нужно масштабировать (например, радиус), а какие нет (значения RGB).

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

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

PS: для этого проекта я использую python (с pygame ), но - хотя ответ на python / pygame очень важен, меня больше интересует общее / общее описание шаблона, а не его конкретная реализация.

Заранее спасибо за ваше время и опыт.

макинтош
источник

Ответы:

6

Стандартный способ сделать это - установить матрицу преобразования для преобразования во время рендеринга. Для 3D-рендеринга это матрица преобразования вида для камеры, которая это делает.

В большинстве 2D API есть способ указать преобразование вида, либо в виде матрицы 2x3, либо в виде отдельного масштаба, перемещения и поворота.

Беглый взгляд на документацию по pygame показывает, что вам придется реализовать матрицу преобразования вида самостоятельно. Позволяет ли вам получить свой собственный класс из его поверхностного класса, чтобы позволить вам добавить эту функциональность?

Адам
источник
Вы ответите очень полезно (+1). Я могу подклассифицировать свой поверхностный класс, но мне нужно больше времени, чтобы выяснить, смогу ли я достичь того, что указано в вашем посте. Я очень новичок в игровом программировании и графике в целом, у вас есть какая-нибудь ссылка, чтобы рекомендовать объяснить этот матричный подход (или даже только математику, связанную с использованием матрицы для масштабирования поверхности?). Спасибо!
Мак
1
Поскольку это 2D, и в нем нет вращения, @mac в основном говорит об обёртывании функций, и вы можете использовать простое масштабное деление в этих обёртках. Причина, по которой обычно используется полная матрица, заключается в том, что в большинстве API есть матрица, управляющая окном просмотра, но, похоже, что в Pygame нет, поэтому вам придется делать это самостоятельно на один уровень выше.
Патрик Хьюз
2

так как это очень распространенная проблема, мне интересно, существует ли установленная модель, которая элегантно решает эту проблему, которую мне не удалось найти.

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

Если вы используете 3D API, вы можете получить эту функцию бесплатно - просто измените параметры камеры / области просмотра.

PyGame является очень старым API и, к сожалению, действительно подходит только для 2D. Даже если вы могли бы разработать адекватные системы масштабирования для разных уровней масштабирования, производительность будет недостаточно хорошей, а внешний вид, вероятно, будет неприемлемо плохим.

Я бы посоветовал, что если вы хотите увеличить или уменьшить масштаб, вы как можно скорее перейдете на современный 3D API. Я бы порекомендовал pyglet, но есть и другие.

Kylotan
источник
Спасибо за ваш ответ (+1). Я уже использовал pygletsв прошлом для 3D-моделирования. Это, безусловно, более, чем способно pygame, но поддержка 2D довольно низкоуровневая, чем в pygame. Доступная документация / примеры также менее подробны, что для меня обидно, так как я новичок в разработке игр, и мне действительно нужно понять основы наиболее часто выполняемых операций. :) Что касается «возраста» пигмеев: вы правы. Однако идет модернизация ! :)
Mac
Что касается: «Редко, когда вам нужна какая-то одна подпрограмма для запуска с 2 различными уровнями масштабирования» ... Я подумал, что именно это будет использоваться при изменении размера окна / разрешения полноэкранной игры. Из вашего комментария я понял, что это не так: есть ли указатель на то, что является «общим» вместо этого?
Мак
Какие 2D операции вы выполняете, когда pyglet находится на более низком уровне, чем pygame? Оба позволяют рисовать спрайт с 1 строкой кода. Когда вы изменяете размер окна 2D-игры, отношение пикселей к мировым единицам почти всегда остается постоянным. Таким образом, вы просто получаете больше спрайтов: вы не рисуете их по-другому.
Килотан
Что касается низкоуровневой стороны: я не являюсь настоящим экспертом ни в одной из двух библиотек, но в Pyglets я не смог воспроизвести из коробки «готовые» способы рендеринга групп, предлагаемые Pygame (как, pygame.sprite.LayeredUpdatesнапример,). Что касается неизменного соотношения: я понял, что вы имеете в виду. Поведение, которое вы описываете, не то, которое я хочу воспроизвести, но я поняла, что вы имеете в виду, спасибо за разъяснения! :)
Mac
У pyglet есть объекты OrderedGroup - документы здесь, если вы или кто-либо еще заинтересован: pyglet.org/doc/programming_guide/displaying_images.html#sprites
Kylotan,