netlib.narod.ru< Назад | Оглавление | Далее >

Основы блочной графики

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

Что такое блок?

Те, кого мучает этот вопрос, должны спросить себя. Шутка. Если серьезно, блок ни что иное, как кирпичик для строительства ландшафта. Подобно тому, как обычные строительные кирпичи по отдельности не представляют ничего особенного, блоки также достаточно просты. Чтобы получить имеющий смымсл результат, вы должны разместить вместе несколько блоков.

Чтобы понять, как блоки работают в ландшафтной библиотеке, вам достаточно взглянуть на обычную мозаику. Каждый элемент мозаики сам по себе ничего не значит, но все вместе они формируют замечательную картинку. Взгляните на рис. 5.1, чтобы увидеть мозаику из блоков.


Рис. 5.1. Мозаика из блоков на экране

Рис. 5.1. Мозаика из блоков на экране


Как видно на рис. 5.1, в каждом отдельном блоке мозаики мало смысла, но когда они расположены вместе с другими блокам, они формируют завершенную картину. Блоки для ландшафтной библиотеки работают полностью аналогичным способом. Думайте о земле, как о холсте, а о блоках ландшафта, как о кистях.

Теперь, когда вы знаете о том, что такое блоки, как насчет нескольких примеров? Взгляните на рис. 5.2, где показан пример нескольких блоков для ландшафтной библиотеки.


Рис. 5.2. Пример ландшафтных блоков

Рис. 5.2. Пример ландшафтных блоков


На рис. 5.2 изображены четыре ландшафтных блока. Если глядеть слева направо, они изображают траву, границу травы, угол травы и камни на траве. Даже такой ограниченный список позволяет вам создавать травяные поля, усеянные камнями.

Зачем использовать блоки?

Теперь, когда вы узнали что такое блоки, давайте узнаем для чего их используют разработчики игр. Есть три основные причины, по которым разработчики применяют в своих играх блочную графику: экономия памяти, повторное использование графики и динамическое содержание.

Использование блоков для экономии памяти

Давайте для примера возьмем карту игры Warcraft III, ширина которой равна 100 блокам, и высота также равна 100 блокам. Подобная сетка карты изображена на рис. 5.3.


Рис. 5.3. Пример карты для размещения блоков

Рис. 5.3. Пример карты для размещения блоков


Пока ничего особенного, вы просто получили карту размером 100 x 100 блоков. Всего получается 10 000 блоков. Теперь представим, что в качестве карты вы решили использовать не блоки, а одно большое растровое изображение. Чтобы вычислить объем требуемой для карты памяти, вы должны умножить общее количество блоков на размер одного блока. Эту концепцию демонстрируют следующие вычисления:

Ничего себе! Посмотрите на результат. Простая карта, размером 100 x 100 блоков требует для своего хранения колоссального объема памяти — 163 Мбайт. Даже если вы решите ограничиться 8-разрядным цветом (256-ю цветами), все равно придется выделить 41 Мбайт только для хранения карты. Если вы не читаете эту книгу в 2008 году, 163 Мбайт только для хранения игровой карты — это слишком много.

Хорошо, теперь, когда вы видели темную сторону, настало время для небольшого просвещения. Возьмем предыдущий пример, и вычислим объем памяти, необходимый для хранения той же карты размером 100 x 100, но в этот раз с использованием блоков.

Взгляните на результат. Используя набор из 100 блоков вы можете создать карту размером 100 x 100, заняв всего два мегабайта памяти. Черт, вы можете использовать набор из 1000 блоков, и вам понадобится менее 20 Мбайт памяти.

Итак, вот что мы имеем. Первая причина для использования блоков в ваших стратегических играх заключается в экономии памяти.

Применение блоков для повторного использования графики

Повторное использование графики очень важно в разработке игр, время художника также важно, как и время разработичика (если не более важно!). Взгляните на рис. 5.4.


Рис. 5.4. Простая игровая карта

Рис. 5.4. Простая игровая карта


На рис. 5.4 вы видите травяное поле, усыпанное различными камнями. При дальнейшем осмотре вы заметите, что все камни очень похожи. Теперь представьте, что художник должен вручную разместить каждую скалу. Через некоторое время это становится очень утомительно, поскольку художник тратит все время на перемещение одной и той же графики, вместо того, чтобы создавать новое содержание.

Рис. 5.5 проливает новый свет на рис. 5.4.


Рис. 5.5. Простая игровая карта, состоящая из блоков

Рис. 5.5. Простая игровая карта, состоящая из блоков


Смотрите, карта составлена из блоков. Вы, возможно, не заметили этого раньше, но в действительности карта составлена из блоков всего двух видов. Благодаря использованию блоков, один и тот же шаблон камней используется в одном изображении несколько раз. Это уменьшает нагрузку на художников, поскольку размещением готовых блоков может заниматься разработчик (или кто-нибудь еще).

Использование блоков для динамического содержимого

Динамическое содержимое требуется для многих стратегических игр. Возьмем, например, генератор случайных карт. Одна из игр, использующих генератор случайных карт — Civilization. В ней вы указываете тип карты, которую хотите получить, и игра генерирует ее для вас на лету. Когда у вас есть блоки, вы пишете алгоритм, размещающий их таким образом, чтобы полученная карта выглядела привлекательно. А если бы нам требовалось создать одно гигантское растровое изовражение — это был бы кошмар. Вы можете представить себе поточечное рисование каждого элемента программой?

Достаточно взглянуть на рис. 5.5, чтобы увидеть, как алгоритм может генерировать динамическое содержимое. Вам достаточно просто установить генератор случайных чисел для размещения на карте блоков с камнями. Это позволяет создавать динамическое содержимое легко и быстро.

Как создавать блоки?

Ах, замечательная часть! Сначала вы можете любить создание блоков. В конце концов вы можете возненавидеть это занятие. Почему так? Создание блоков — утомительная и отнимающая много времени работа. Конечно, некоторые люди действительно наслаждаются ею, только я не отношусь к их числу.

Выбор размера блоков

Вы должны начать с выбора графического пакета, такого как Adobe Photoshop 7. Затем следует выбрать размер основного блока. Для наборов блоков, которые не являются изометрическими, размер блока обычно выбирается из степеней двойки, например 32 x 32, 64 x 64 или 128 x 128. Размер блока, который вы реально выберете, зависит от конкретной ситуации. Нет никаких стандартов выбора размера блоков, но вы должны учесть следующее:

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

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


Рис. 5.6. Интерфейс с видимым фрагментом 16 x 16 блоков

Рис. 5.6. Интерфейс с видимым фрагментом 16 x 16 блоков


На рис. 5.6 командные кнопки и интерфейс занимают пространство в правой и нижней частях экрана. Остальная часть интерфейса отведена под состоящую из блоков карту. Если установить размер видимой части карты равным 16 x 16 блоков, разрешение экрана должно быть достаточно для корректного отображения. Чтобы вычислить максимально возможный размер блока следует разделить минимальное разрешение экрана на выбранное количество отображаемых блоков. Воспользуемся для определения максимального размера блока следующими формулами:

Предположив, что минимальное разрешение экрана равно 800 x 600, мы можем вычислить, что максимально возможный размер блоков на рис. 5.6 равен (800 / 16) = 50 точек в ширину и (600 / 16) = 37 точек в высоту. Если вы придерживаетесь метода, в котором размеры блоков равны степеням двойки, то максимальный размер блоков ограничен 32 точками в ширину и 32 точками в высоту.

Если вы чувствуете, что блоки размером 32 x 32 точки слишком малы, следует пересмотреть количество одновременно отображаемых блоков карты. В действительности все зависит от того, сколько подразделений вы планируете показывать одновременно. Если ваша игра требует, чтобы игрок управлял огромными армиями, предпочтительнее использовать блоки небольшого размера. Если в игре будет всего несколько подразделений, как, например в Warcraft III от Blizzard, использование блоков большого размера не вызовет никаких проблем.

Определение необходимых блоков

Теперь, когда вы знаете размер базового блока для вашей игры, можно перейти к фактическому созданию блоков. С чего же начать? Я начинаю строительство с создания фрагментов земной поверхности для игры. Например, в играх Age of Empires и Age of Wonders от Ensemble Studios, базовыми строительными блоками библиотеки работы с ландшафтом являются трава, почва или даже снег.

Вы знаете, что следует создать базовые блоки для изображения травы, почвы, снега и т.д. Теперь, когда вы уже вступили на этот путь, следует внести разнообразие в пейзаж. Кто захочет играть на огромных полях травы, верно? Если вы выбираете в качестве базового блока изображение травы, можно подумать о добавлении к списку блоков камней, деревьев, воды, кустарников или даже небольших участков почвы. Чтобы подхлестнуть творческие способности, посмотрите на рис. 5.7.


Рис. 5.7. Несколько блоков из набора

Рис. 5.7. Несколько блоков из набора


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

Как отображать блоки?

Теперь начинается самая интересная часть! Отображение блоков в теории выглядит очень просто, но выполнить его на практике достаточно сложно. Насколько трудным может быть отображение блоков в сетке? Вы заметили ключевое слово в предыдущем предложении? Если вы решили, что это слово «сетка», — наградите себя аплодисментами.

Существует три основных способа отображения блоков в вашей игре: двухмерный, изометрический и трехмерный.

Отображение двухмерной сетки

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


Рис. 5.8. Двухмерная сетка для размещения блоков

Рис. 5.8. Двухмерная сетка для размещения блоков


Вы уже видели это раньше, поскольку я пользуюсь этим методом во многих примерах. Первый блок карты располагается в верхнем левом углу сетки. Последний блок карты находится в нижнем правом углу. Отображение карты из блоков так же просто, как обход карты слева направо и сверху вниз. Взгляните на следующий фрагмент кода:

int x,y;
// отображение сверху вниз
for(y = 0; y < 10; y++) {
   // Отображение слева направо
      for(x = 0; x < 10; x++) {
      // Ваша функция для отображения блока
      vDisplayTile(x, y);
   }
}

В коде есть два цикла. Первый цикл увеличивает позицию блока по вертикали. Второй цикл увеличивает позицию блока по горизонтали. Поместив цикл перебора позиций по горизонтали внутрь цикла перебора позиций по вертикали, вы получаете рисунок всей сетки. Рис. 5.9 показывает, в каком порядке рисуются блоки.


Рис. 5.9. Порядок двухмерных блоков

Рис. 5.9. Порядок двухмерных блоков


Обратите внимание, что нумерация блоков начинается с 0 в верхнем левом углу и заканчивается 99 в нижнем правом углу. Разве это не просто?

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

// Глобальный массив для карты блоков
int g_iTileMap[100]; // 10*10 = 100 ячеек необходимо

// Прототип функции отображения блока
void vDisplayTile(int x, int y);

void main()
{
   int x, y;

   // Сверху вниз
   for(y = 0; y < 10; y++) {
      // Слева направо
      for (x = 0; x < 10; x++) {
          // Отображение блока
          vDisplayTile(x, y);
      }
   }
}

void vDisplayTile(int x, int y)
{
   int iTile;
   int tileWidth = 64;
   int tileHeight = 64;
   int mapWidth = 10;

   //
   // Вычисляем номер блока, расположенного
   // по полученным координатам x и y.
   //
   iTile = g_iTileMap[(x + (y * mapWidth))];

   // Отображение на экране растрового изображения
   // Следующая функция является фиктивной
   // и представляет лишь псевдокод. Чтобы код
   // работал вам необходимо заменить ее на
   // настоящую функцию рисования блока.
   //
   DrawBitmap(iTile, (x * tileWidth), (y * tileHeight));
}

В приведенной выше функции main() программа в цикле последовательно перебирает блоки и вызывает функцию vDisplayTile(). Код функции отображения блока начинается с вычисления, где в массиве блоков расположено значение, относящееся к данному блоку, и извлечения этого значения. При вычислении берется координата X и к ней прибавляется координата Y умноженная на ширину карты. Эту концепцию иллюстрирует рис. 5.10.


Рис. 5.10. Вычисление местоположения в массиве

Рис. 5.10. Вычисление местоположения в массиве


Как вычислить местоположение в массиве

Получение местоположение блока в массиве начинается с координаты X. Рассмотрим пример нахождения в массиве блока с координатами 5,5. На рис. 5.10 от блока в верхнем левом углу мы перемещаемся на пять блоков вправо. В результате мы окажемся в позиции, отмеченной на рисунке буквой A.

Теперь к текущей позиции вы должны прибавить координату Y блока, умноженную на ширину карты. Ширина карты равна десяти блокам, поэтому мы прибавляем 10 * 5 (координата Y) к текущей позиции. Следуйте по стрелке, размещенной справа от позиции, помеченной буквой A, и вы увидите, что она заканчивается в искомой позиции массива, отмеченной буквой B.

Итак, следуя рис. 5.10, мы получаем следующую формулу:

На рис. 5.10 массив для хранения карты представлен в виде сетки, но в действительности это один линейный участок памяти. Его просто легче представить себе, если изобразить в виде сетки. Преимущество использования массива состоит в том, что он непосредственно соответствует тому, что видит пользователь. Нет никаких сложных связанных списков, которые следует обходить, только один простой массив.

Как вычислить видимую позицию

Следующая функция в программе, DrawBitmap(), является искусственной функцией, которая напоминает обычную графическую функцию, используемую для отображения двухмерного растрового изображения. В вызове этой воображаемой функции присутствуют три параметра: графический блок, экранная координата X и экранная координата Y.

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

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

Третий параметр, координата Y, действует аналогично второму параметру, за исключением того, что задает позицию выводимого изображения по вертикали.

Вернемся к примеру на рис. 5.10. Координаты X и Y в пикселах для блока с координатами на карте 5, 5 будут равны (5 * 64), (5 * 64), или 320, 320. Большинство графических функций позволяют указать координаты X и Y растрового изображения, так что пример не должен вызывать никаких затруднений.

Вот как вычисляются координаты X и Y для блока в пикселях:

Отображение изометрических блоков

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

Множество игр используют изометрические блоки, например, Age of Empires, Civilization и Command & Conquer. Основное преимущество изометрических блоков в том, что они позволяют реализовать качественный трехмерный вид без использования настоящей трехмерной графики. Однако, это уже не является причиной для беспокойства, поскольку компьютеры большинства игроков замечательно справляются с трехмерной графикой. Поэтому большинство стратегий реального времени сегодня используют трехмерную графику. Использование изометрических блоков весьма ограничено.

Хотя большинство коммерческих игр прекратили использование наборов изометрических блоков, они еще жизнеспособны и вы можете применять их. Взгляните на рис. 5.11, чтобы увидеть карту из изометрических блоков.


Рис. 5.11. Базовая карта изометрических блоков

Рис. 5.11. Базовая карта изометрических блоков


Фактически, карта для изометрических блоков является картой для двухмерных блоков, повернутой на 45 градусов по двум осям. Это создает интересную сетку, поскольку с точки зрения зрителя блоки теперь кажутся повернутыми. Поскольку карта развернута, координаты X и Y теперь не соответствуют экранным координатам X и Y. На рис. 5.11 новые оси соответственно помечены. Обратите внимание, что ось X направлена от середины верхней части экрана к к его нижнему правому углу. Ось Y начинается также в середине верхней части экрана, но направлена к нижнему левому углу. В результате блок с координатами 0,0 расположен в центре верхней части экрана. Не слишком простой метод отображения!

Как только мы разместили начальный блок с координатами 0, 0, достаточно легко вывести алгоритм дальнейшего рисования. Он практически тот же, что использовался для отображения двухмерных блоков, за исключением того, что координаты блоков слегка изменились. Взгляните на рис. 5.12, чтобы увидеть, в каком порядке отображаются изометрические блоки.


Рис. 5.12. Порядок отображения изометрических блоков

Рис. 5.12. Порядок отображения изометрических блоков


На рис. 5.12 видно, что блоки по прежнему отображаются в сетке, вот только сама сетка повернута. В результате для каждого отображаемого блока необходимо указывать смещения координат X и Y.

Чтобы не прерывать рассказ я отложу обсуждение кода для отображения изометрических блоков до конца главы. Если желаете, можете взглянуть на него сейчас, или подождите, пока не прочтете следующие разделы.

Отображение трехмерных блоков

Да, святой грааль графики, — трехмерная графика! Большинство стратегических игр сегодня используют трехмерные блоки. У трехмерных блоков много преимуществ, в том числе:

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

Второе преимущество, вращение, говорит само за себя. Если вы когда-нибудь пробовали вращать двухмерное растровое изображение, чтобы увидеть, что находится с другой стороны, то понимаете о чем я говорю. С другой стороны ничего нет. В двухмерной графике что вы видите, то и получаете. Как только вы перейдете к трехмерной графике, вы сможете вращать блоки и разглядывать их со всех сторон. Вы будете получать абсолютно разные изображения в зависимости от точки зрения камеры. Кроме того, использование трехмерной графики экономит занимаемую изображениями память. Вам достаточно создать один кадр анимации, вместо множества изображений для каждого из возможных углов зрения.

Третье преимущество, глубина, связано со вращением, когда трехмерные блоки обретают реальную глубину, если вы перемещаете точку зрения вверх или вниз. Практически невозможно создать двухмерные блоки для каждой возможной высоты камеры пользователя.

Так как же отображать трехмерные блоки? Легко! Вы всего лишь преобразуете их в местоположение и применяете обычную функцию рисования. Действительно, трехмерные блоки отображаются точно так же, как и двухмерные. Вы просто помещаете их в сетку и визуализируете от более далеких к более близким. Составленная из трехмерных блоков карта изображена на рис. 5.13.


Рис. 5.13. Пример карты из трехмерных блоков

Рис. 5.13. Пример карты из трехмерных блоков


Хм-м-м, не так уж интересно? Рис. 5.13 не слишком отличается от карты из двухмерных блоков. Это важный момент. Трехмерная графика не означает драматического изменения вида вашей стратегической игры; она только лишь добавляет гибкости и открывает для вас новые возможности. Чтобы применять в стратегической игре трехмерную графику не требуется переход к трехмерному виду от первого лица. Вы можете придерживаться традиционного для стратегий реального времени вида и при этом использоваить трехмерную графику. В этом и заключается вся красота.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz