Вопрос
Что делать, если у вас есть 2D-игра, в которой используются действительно большие изображения (больше, чем может поддерживать ваше оборудование)? Может быть, есть какое-то интересное решение этой проблемы, которое мне никогда не приходило в голову.
Я работаю над создателем графических приключенческих игр. Моя целевая аудитория - люди, у которых практически нет опыта разработки игр (и программирования). Если бы вы работали с таким приложением, разве вы не предпочли бы, чтобы оно обрабатывало проблему внутренне, а не говорило вам «разделить ваши изображения»?
контекст
Хорошо известно, что графические карты накладывают ряд ограничений на размер текстур, которые они могут использовать. Например, при работе с XNA максимальный размер текстуры ограничен 2048 или 4096 пикселями в зависимости от выбранного профиля.
Обычно это не представляет большой проблемы в 2D играх, потому что большинство из них имеют уровни, которые могут быть построены из более мелких отдельных частей (например, плитки или преобразованных спрайтов).
Но подумайте о нескольких классических графических приключенческих играх point'n'click (например, Monkey Island). Комнаты в графических приключенческих играх обычно разрабатываются целиком, с небольшими или отсутствующими повторяемыми участками, как художник, работающий над пейзажем. Или, возможно, такая игра, как Final Fantasy 7, в которой используются большие предварительно отрендеренные фоны.
Некоторые из этих комнат могут быть довольно большими, часто занимая три или более экрана шириной. Теперь, если мы рассмотрим эти фоны в контексте современной игры высокой четкости, они легко превысят максимальный поддерживаемый размер текстуры.
Теперь очевидным решением этого является разделение фона на более мелкие участки, которые соответствуют требованиям, и их рисование рядом. Но должен ли ты (или твой художник) быть тем, кто разделяет все твои текстуры?
Если вы работаете с высокоуровневым API, разве он не должен быть готов к тому, чтобы справиться с этой ситуацией и выполнить расщепление и сборку текстур внутри себя (или в качестве предварительной обработки, такой как XNA Content Pipeline или во время выполнения)?
редактировать
Вот то, о чем я думал, с точки зрения реализации XNA.
Мой 2D движок требует только небольшого подмножества функций Texture2D. Я действительно могу уменьшить его до этого интерфейса:
public interface ITexture
{
int Height { get; }
int Width { get; }
void Draw(SpriteBatch spriteBatch, Vector2 position, Rectangle? source, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
}
Единственный внешний метод, который я использую, который опирается на Texture2D, это SpriteBatch.Draw (), поэтому я мог бы создать мост между ними, добавив метод расширения:
public static void Draw(this SpriteBatch spriteBatch, ITexture texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
texture.Draw(spriteBatch, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
}
Это позволило бы мне использовать ITexture взаимозаменяемо всякий раз, когда я использовал Texture2D раньше.
Тогда я мог бы создать две разные реализации ITexture, например RegularTexture и LargeTexture, где RegularTexture просто обернет обычный Texture2D.
С другой стороны, LargeTexture будет хранить список Texture2D, каждый из которых соответствует одному из разделенных фрагментов полного изображения. Наиболее важной частью является то, что вызов Draw () в LargeTexture должен иметь возможность применить все преобразования и нарисовать все части, как если бы они были только одним непрерывным изображением.
Наконец, чтобы сделать весь процесс прозрачным, я бы создал унифицированный класс загрузчика текстур, который будет действовать как фабричный метод. Он будет принимать путь текстуры в качестве параметра и будет возвращать ITexture, которая будет либо RegularTexture, либо LargeTexture, в зависимости от размера изображения, превышающего ограничение, или нет. Но пользователю не нужно было знать, какой это был.
Немного перебор или это звучит нормально?