Разработка игр для компьютерных систем, консольных приставок и мобильных устройств – занятие трудоемкое. Если говорить только о специфике создания игр для любой из перечисленных платформ, то можно отметить, что подход в создании игр у каждой платформы будет свой (по крайней мере, так было до недавнего времени). Более того, огромное количество устройств может иметь различное аппаратное обеспечение. Если взять, к примеру, несколько компьютеров, то все они с большой долей вероятности будут компоноваться различными комплектующими. И как быть в этом случае бедному программисту, которому нужно попытаться создать игру для всех этих разных устройств? Ответ прост: необходимы общие стандарты и спецификации. И они есть, за что им большой и огромный респект от всех нас. Конечно, не все в этом мире идеально и гармонично, те же стандарты и спецификации бывают разными, но! Для компьютерных систем есть свой стандарт – это DirectX и теперь XNA Framework, для мобильных устройств Java 2 ME, Symbian OS & C++ и Windows Mobile & C++ и C#, для Xbox 360 тоже появился свой стандарт в виде платформы XNA. В целом все постепенно унифицируется и сводится к одному стандарту, по крайней мере в семействе продуктов Microsoft. Кстати, я больше чем уверен, что вы не очень сильно любите Microsoft и дядюшку Билла, но при этом все равно пользуетесь Windows на своем компьютере. Но это не главное, главное – другое. Представьте, если бы у нас сейчас было 10 разных и мощных операционных систем от разных компаний. Думаю, что все эти компании ни за что и никогда не договорились бы об общем стандарте в разработке игр для своих операционных систем. И тогда у нас на рынке сейчас имелся бы не DirectX 10, а десять разных DirectX’ов (или как бы они там назывались)… Со стороны пользователя конкуренция – это просто замечательно, а вот со стороны программиста куча разных стандартов в одной сфере – это ой как тяжело. 2.1. И был сначала DirectX Осознав факт необходимости целостной спецификации, корпорация Microsoft много лет назад попыталась создать стандартный набор игровых библиотек для операционной системы Windows. В 1995 году на свет появилась первая версия DirectX 1.0 (изначально, правда, была еще одна ранняя версия с названием WinG, но сейчас это не столь важно). Эта версия игровой библиотеки (API) была построена на базе библиотеки Reality Lab компании RenderMorfics, которую Microsoft прикупила по этому случаю. Первый блин, как всегда, комом, поэтому и у DirectX не все сложилось сразу. Выходили новые версии библиотек, которые сменяли одна другую, а главное – постоянно изменялось содержимое самих библиотек. И только в 1999 году после выхода DirectX 7.1 (2D) и в 2001 году после выхода DirectX 8.1 (с полноценной 3D-поддержкой и первой версией шейдеров) появилась относительная стабильность. Выход новой версии DirectX 9 в 2002 году привносит ряд изменений в API, но это все плановая модернизация, а не коренное изменение всей целостности библиотеки. В период с 2004 по 2007 год DirectX 9 подвергался мощной переработке, причем обновления происходили (особенно в 2006 году) буквально через кажды два-три месяца. И уже в 2007 году появилась новая библиотека DirectX 10. Все изменения в DirectX в основном связаны с перестройкой работы с 3D-графикой и, главное, с некоторыми упрощениями в подходе создания конечного продукта. Нельзя сказать, что перестройка DirectX прошла безболезненно, в том числе и для нас с вами. Вы просто не представляете, какое количество писем я получил за это время! Люди, купившие мою книгу «DirectX 9. Уроки программирования на С++» (дата выхода – 2004 год), абсолютно не понимали, почему новый DirectX SDK (2006 года) не хочет работать с примерами, рассматриваемыми в книге! Но со временем все утряслось, и сейчас на рынке появились стабильные и мощные инструменты, направленные на создание хороших игр. 2.1.1. Уровни абстракции Схема взаимодействия DirectX и компьютерной системы на уровне абстракции может «вылиться» примерно в следующий рисунок (рис. 2.1). Как видно из этой схемы, любая игра базируется на классах DirectX, которые, в свою очередь, взаимодействуют с операционной системой или специальными сервисами, включающими в себя драйвера устройства и другие API. Такой подход в реализации многоуровневых прослоек позволяет программисту не обращать внимания на аппаратную часть устройства и спокойно работать с программным кодом. В итоге для программиста абсолютно не важно (в идеале), какое аппаратное обеспечение имеет это устройство, он работает непосредственно с кодом игры и библиотечными классами DirectX. Останавливаться подробно на устройстве и работе библиотеки DirectX в этой главе и всей книге мы не будем, поскольку к нашей теме DirectX не имеет прямого отношения и служит просто звеном одной цепочки, о котором обязательно нужно было упомянуть.
Рис. 2.1. Схема взаимодействия DirectX и аппаратной части устройства 2.2. Новые реалии Время вносит в жизнь свои коррективы. В какой-то момент стали очень бурно развиваться мобильные устройства, а также у Microsoft появился определенный интерес к рынку консольных приставок. Этот интерес материализовался консолью Xbox, а затем появилась и вторая версия приставки с несколько видоизмененным названием Xbox 360. После этого корпорация Microsoft имела на руках три разные платформы – компьютерную Windows, мобильную Windows Mobile и консольную приставку. Для всех трех платформ игровая спецификация была абсолютно разной. Разработчики, создавая игру для PC, могли перенести ее на Xbox, но для этого приходилось тратить очень много времени. Порой проекты для обеих платформ делали две разные команды, а точнее одна команда создавала, а другая адаптировала. С этим нужно было что-то делать. Создание общей спецификации для всех платформ семейства Microsoft стало большой головной болью для программистов, работающих в корпорации. Чтобы создать такую спецификацию, необходимо было создать общую инструментальную базу, один общий язык программирования, а также общую библиотеку классов. Но задача была решена. Сейчас в качестве инструментальной базы выступает инструментарий Visual C# Express или Visual Studio. Общим языком программирования стал язык C#, который, безусловно, проще и лучше своих прародителей С/C++/Java. Общей библиотекой классов стала платформа XNA Framework, которая включает огромный набор системных инструментов для решения большинства серьезных задач. В итоге мы имеем одну спецификацию, меньше головных болей и безболезненное портирование игр с одной платформы на другую. Правда, перед XNA Framework у Microsoft был еще один промежуточный этап понимания того, как должна быть устроена такая библиотека, и этот этап был ознаменован выходом Managed DirectX. 2.3. Managed DirectX Основная проблема переноса DirectX на все семейство продуктов Microsoft связана с тем, что библиотека DirectX построена на независимой спецификации модели составных компонентов (COM – Component Object Model), которая, в свою очередь, очень сильно привязана к Windows и языку программирования С++. По- этому перенос DirectX на все продукты был просто не возможен. Необходимо было выдумать и реализовать нечто новое, простое, да так, чтобы еще и работало на всех платформах сразу и одинаково. Вот так и родилась библиотека Managed DirectX для языка С# и .NET-платформы, которая по своей сути представляла системную надстройку классов над стандартным DirectX. В конечном счете на свет появились всего две версии Managed DirectX. В данный момент эта технология пребывает в летаргическом сне и, по всей видимости, там и будет пребывать еще долгое время, поскольку от развития этой платформы на неопределенное время пришлось отказаться. В основном проблема Managed DirectX и всего проекта в частности заключалась в том, что Managed DirectX – это всего лишь надстройка над DirectX. В момент создания и развития Managed DirectX никто не принимал во внимание консоль Xbox 360, возможность портирования полноценных трехмерных игр на мобильные устройства под управлением Windows Mobile и другие факторы. И когда встал вопрос о том, чтобы абстрагироваться от привязанности к DirectX и Windows, выяснилось, что с Managed DirectX сделать это будет очень-очень трудно. Вот тогда и начались разработки новой платформы, которая впоследствии получила название XNA Framework. На момент написания статьи работать с мобильными устройствами на базе Windows Mobile 5.0 можно в основном с языком программирования С++. В Visual Studio 2005 есть инструменты и для работы с С# и .NET платформой, но это еще не основной подход в реализации мобильных приложений, поскольку для работы таких приложений в Windows Mobile 5.0 необходимо установить .NET Compact Framework. По заявлениям Microsoft, в новой операционной системе Windows Mobile 6.0 .NET Compact Framework будет встроен в систему. 2.4. Платформа XNA Framework Платформа XNA Framework – это большой набор системных библиотек, построенных на базе .NET-библиотек, направленных на улучшение и упрощение создания игр для всех продуктов семейства Microsoft. Создавая игру для PC на базе платформы XNA Framework, вы можете быть уверены, что эта игра будет работать на приставке Xbox 360 и в скором времени на новой системе Windows Mobile (будем на это надеяться). Исключения в этом случае могут составлять некоторые системные классы, которые необходимы только для работы с той или иной платформой. Например, приставка Xbox 360 не имеет мыши, поэтому в программах для консоли нельзя использовать методы и классы, направленные на работу с мышью. В свою очередь, для компьютерных игр можно задавать различные разрешения экрана, тогда как Xbox 360 использует в качестве монитора телевизор, который имеет свою специфику вывода изображения на экран. Эти и другие исключения составляют мышиную долю (примерно 3–5%) от всей библиотеки XNA Framework. При правильном подходе в использовании библиотечных классов можно написать программу, которая на 100% будет работать как на консоли, так и на компьютере, или, по крайней мере, адаптация игры займет очень малое количество времени. Еще одной важной особенностью платформы XNA Framework является значительное упрощение в подходе реализации игр для всех платформ. Прежде чем начать писать именно исходный код игр с использованием DirectX SDK, необходимо создать большую кучу различных объектов, создать окно, настроить видеоадаптер и т. д. Применяя платформу XNA Framework, вы все перечисленное и даже больше создадите за пару строк исходного кода, при этом эти строки сформирует за вас сам компилятор и XNA! 2.4.1. Уровни абстракции XNA Так же как и в случае с DirectX, мы можем графически представить взаимодействие приложений через XNA Framework с аппаратной частью устройства. Посмотрите на рис. 2.2, где представлены уровни абстракции платформы XNA Framework.
Рис. 2.2. Взаимодействия XNA с аппаратной частью устройства Как видно из рис. 2.2, схема работы XNA Framework напоминает схему работы с DirectX, но в основе библиотеки XNA лежат другие компоненты и механизмы взаимодействия с аппаратной частью устройства. На рисунке также видно, что вся платформа XNA Framework состоит из трех уровней абстракции, через которые программа обращается к системе. * Игра – это самый высокий уровень абстракции, включающий в себя исход- ный код игры, различные игровые данные и компоненты. Это все то, что вы пишите и создаете сами лично. * Расширенный каркас (Extended Framework) – расширенный каркас системных высокоуровневых классов содержит простые механизмы для рабо-ты с загрузкой моделей, текстур и других графических элементов. В состав этого каркаса входят Application Model и Content Pipeline. Со време нем эта часть библиотеки может пополняться новыми компонентами, что позволит еще больше упростить создание игр. Методы, классы, структуры этого уровня абстракции можно смело использовать в своих программах. * Основной каркас (Core Framework) – основной каркас библиотеки содержит в себе ядро платформы XNA Framework и обеспечивает базовые механизмы работы всей библиотеки в целом. Этот уровень абстракции содержит несколько основных классов, таких как Graphics, Math, Input, Audio и Storage. Все классы упрощают работу соответственно с графикой, звуком, устройствами ввода информации, математическими операциями и с данными для записи или чтения их с файловой системы. Классы этого уровня вам также будут доступны в полном объеме. Со временем эта часть библиотеки может пополняться новыми компонентами. * Платформа (Platform) – это самый нижний и независимый уровень абстракции, или набор классов, осуществляющий обращение непосредственно к аппаратной части устройства. Доступ к компонентам этого уровня у программиста есть, но если их использовать, то это значительно сузит портирование созданного приложения на другие платформы. Более того, не рекомендуется использовать прямое обращение исходного кода игры к прослойке этих компонентов, и по большому счету ваша игра даже не должна подозревать об этом уровне абстракции. В состав этой прослойки входят DirectX, XACT, XInput и XContent. Подводя промежуточный итог обзора платформы XNA Framework, можно констатировать, что механизмы работы как DirectX, так и XNA Framework с аппаратной частью устройства почти одинаковы, но внутренние особенности обеих библиотек значительно отличаются друг от друга, и сейчас мы поговорим об этом более подробно. 2.4.2. Application Model В расширенном каркасе высокоуровневых классов и, в частности, в pplication Model (Модель приложения) реализована общая структура работы модели приложения. Этот набор компонентов позволяет автоматизировать процесс создания игры и создает за вас механизм реализации оконного или полноэкранного приложения, организует необходимый в игре таймер, обрабатывает различные сообщения, управляет процессом рисования сцены на экране телевизора (рендиринг), загрузкой ресурсов игры и т. д. Все перечисленные элементы преподносятся вам в виде готового шаблона игры с небольшим количеством строк исходного кода, в которые вам еобходимо вставлять свой код игры. То есть за вас создается полнофункциональный каркас игрового приложения, готовый к «употреблению». Например, давайте посмотрим на исходный код каркаса игры, созданный шаблоном XNA Game Studio Express и Visual C# Express, представленный в листинге 2.1.
//========================================================================= /// /// Листинг 2.1 /// Исходный код к книге: /// «Программирование игр для приставки Xbox 360 в XNA Game Studio Express» /// Автор книги: Горнаков С. Г. /// Класс: Game1 /// Простой шаблонный проект /// //========================================================================= #region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; #endregion namespace WindowsGame1 { /// /// Это шаблон вашей игры /// public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; ContentManager content; public Game1() { graphics = new GraphicsDeviceManager(this); content = new ContentManager(Services); } /// /// Этот метод предназначен для инициализации различных игровых данных /// Здесь можно задавать первичные состояния игровым компонентам, /// но здесь нельзя загружать график, этот метод предназначен только для /// инициализации первичных игровых состояний /// protected override void Initialize() { // Добавьте здесь код инициализации данных base.Initialize(); } /// /// Этот метод предназначен для загрузки графической составляющей в игру /// protected override void LoadGraphicsContent(bool loadAllContent) { if(loadAllContent) { // Здесь происходит загрузка компонентов в игру } } /// /// Метод для освобождения захваченных системой ресурсов /// Этот метод автоматически выгружает загруженные компоненты /// при выходе или закрытии игры /// protected override void UnloadGraphicsContent(bool unloadAllContent) { if (unloadAllContent == true) { content.Unload(); } } /// /// Здесь происходит обновление состояния игровых объектов, логики, звука, /// получение событий с устройств ввода и так далее /// protected override void Update(GameTime gameTime) { // Обработка событий, получаемых с джойстика if(GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // Добавьте свой код для обновления состояния игровых объектов // Это таймер base.Update(gameTime); } /// /// Рендиринг сцены, или вывод на экран графики /// protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // Добавьте здесь свой код base.Draw(gameTime); } } }
Класс Game1 описан в файле с расширением *.cs (Game1.cs). Расширение в данном случае указывает на то, что используется язык программирования С#. Весь исходный код создан шаблоном, а перевод комментариев на русский язык осуществлен в вольной форме. Класс Game1.cs создал за нас полное игровое оконное приложение с методами для загрузки графической составляющей игры, инициализации данных, систему вывода сцены на экран, систему обновления состояния игры и даже обработку событий, получаемых с джойстика. Неплохо, не правда ли? Более подробно с классом Game1 мы познакомимся в следующих главах, когда начнем работать над игрой. 2.4.3. Компонент Content Pipeline Одной из важнейших составляющих любой программы является графический и игровой контент, который включает в себя различные графические изображения (текстуры, спрайты…), звуковые файлы, модели и материалы. Если вспомнить методику загрузки графики в DirectX, то станет понятно, почему в XNA уделено этому большое внимание. В DirectX, чтобы загрузить модель, приходилось писать десяток-другой строк исходного кода! Более того, загружать можно было только определенные графические файлы, которые DirectX понимал. Для остальных моделей и изображений приходилось писать свои экспортеры или искать инструменты для конвертирования контента в необходимый формат данных. Используя XNA Framework и Content Pipeline (Конвейер контента), который входит в пространство имен Microsoft.Xna.Framework.Content, вам не нужно беспокоиться о том, в каком формате представлено изображение или модель. Вы просто пишите пару строк исходного кода, и ваш графический контент будет успешно загружен в игру внутренними средствами конвейера (в главе 6 мы подробно остановимся на этом вопросе). Конвейер контента понимает следующие форматы: * трехмерные модели – формат X и формат FBX. Формат Х – это всем известный Х-файл, или мэш. Формат FBX – относительно новый формат в игровой индустрии, продвигаемый компанией Autodesk, и поскольку эта же компания является создателем всем известного инструментария 3DMAX Studio, то сомнений в дальнейшем распространении этого формта нет. На сайте компании Autodesk можно бесплатно скачать плагин и конвертер для преобразования сделанной модели в 3DMAX Studio до вер- сии 8 в формат FBX. В 3DMAX Studio 9 все перечисленные средства встро- ены по умолчанию; * графические изображения – поддержаны наиболее распространенные графические форматы DDS, BMP, JPG, PNG и TGA; * материал – имеется поддержка формата FX, или формата шейдеров; * аудиоформат – осуществлена поддержка работы с проектами, созданными при помощи XACT. Подробно о самом формате и загрузке в игру звуковых данных вы узнаете в главе 13. Как видите, список поддерживаемых форматов достаточно большой и внушительный, но главное – это простота загрузки, например текстуры или модели в игру. Посмотрите на пример двух строк исходного кода, загружающих в про-грамму графическое изображение и модель. private Model myBoll; … mySprite = content.Load(«sprite») myBoll = content.Load(«boll»);
В последних двух строках этого блока кода мы загрузили в программу из корневого каталога проекта графическое изображение и модель (для дополнительной или вложенной папки используется следующая запись: «Имя_папки\\boll»). Вот и все, теперь вы можете использовать загруженные элементы для вывода на экран телевизора (о том, как это сделать, в следующих главах). Если представить себе абстрактно внутренний принцип работы Content Pipeline и то, как происходит загрузка контента в игру и его преобразование, то можно прейти к следующей схеме (рис. 2.3). Как видно из этого рисунка, весь игровой контент проходит через конвейер импорта и преобразования данных, после чего на выходе в проекте получаются файлы со специфическим расширением XNB и XACT для звуковых данных. На этапе запуска игры в игровом процессе принимают участие именно преобразованные файлы с расширением XNB и XACT. Все преобразования контента происходят внутренне, без вашего участия и на этапе компиляции проекта в Visual C# Express.
Рис. 2.3. Работа Content Pipeline в XNA Framework 2.4.4. Компонент Graphics Графическая часть библиотеки Microsoft.Xna.Framework.Graphics основана на принципе работы библиотеки DirectX. Подход в реализации программ при помощи графического конвейера XNA Framework полностью исключает работу с фиксированным конвейером, присущим всем программам с использованием DirectX и ниже. Как вы помните, DirectX до последних девятой и десятой версий имел два конвейера – фиксированный и программируемый. Второй конвейер характерен тем, что все работы с вершинами объектов, пикселями текстур, материалом, светом, матрицами происходили посредством шейдеров. Тогда как в фиксированном конвейере можно было не использовать шейдеры. В XNA Framework используются только программируемый конвейер и шейдеры. Все операции со светом, материалом, матрицами, текстурами и т. д. необходимо производить лишь через шейдеры. В связи с этим в XNA Framework предусмотрены два разных класса: BasicEffect и Effect. Первый класс BasicEffect позволяет не писать и не использовать код шейдера, или, в крайнем случае, не писать супермощные шейдерные программы. Тогда все вышеперечисленные операции будут выполняться в простом штатном режиме, а система сама будет обрабатывать данные с внутренними значениями по умолчанию. Такой подход позволяет создавать игры не только профессиональным, но и начинающим программистам. Второй класс Effect представляет полный спектр возможностей по работе с шейдерами всех трех версий. По умолчанию применяется вторая и выше версия шейдеров, при желании можно использовать и первую версию шейдеров, но только для компьютерных систем. Приставка Xbox 360 работает со второй и выше версиями шейдеров. 2.4.5. Компонент Math Как видно из названия компонента, эта библиотека предназначена для работы с математическими операциями. Компонент Math входит в пространство имен Microsoft.Xna.Framework и содержит большое количество классов, структур и методов для работы с векторными данными, матрицами, операциями по трансформации, переносу, преобразованию и т. д. В качестве основной системы координат в XNA Framework применяется правосторонняя система координат, но об этом мы поговорим подробно в третьей части книги. 2.4.6. Компонент Input Компонент Input принадлежит к пространству имен Microsoft.Xna. Framework.Input и является, в свою очередь, надстройкой над XInput. Библиотека Input содержит набор инструментов для работы с устройствами ввода информации. К устройствам ввода информации традиционно причисляются клавиатура, мышь и джойстик. Клавиатура, мышь и джойстик повсеместно используются в компьютерных системах, и в играх в том числе. В консольной приставке Xbox 360 можно работать только с джойстиком и клавиатурой, причем джойстик – это основное устройство ввода данных. Клавиатура может применяться, но вряд ли она будет использоваться пользователями повсеместно. Поэтому при создании игр для Xbox 360 в качестве основного устройства лучше использовать джойстик. 2.4.7. Компонент Audio Работа со звуком в XNA Framework построена на базе Microsoft Cross Platform Audio Creation Tool, или просто XACT. С помощью этой утилиты или даже отдельной программы создаются специализированные звуковые проекты, которые затем при помощи компонента Audio загружают все звуковые данные в игру. Такой подход сделан намеренно, дабы иметь возможность работать со звуковыми данными вне зависимости от платформы, будь то компьютер или Xbox 360. Компонент Audio принадлежит к пространству имен Microsoft.Xna.Framework.Audio. 2.4.8. Компонент Storage Компонент Storage, относящийся к пространству имен библиотеки Microsoft. Xna.Framework.Storage, организует работу с файловой системой устройства. Здесь доступен набор стандартных операций по записи и чтению данных, удалению, перезаписи и т. д. Это стандартный набор для любого устройства с файловой системой организации хранения данных, который может потребоваться в играх, например для сохранения игры или ее последующей загрузки. На этом обзор общей составляющей XNA Framework завершен. Я думаю, что смог убедить вас в том, что создавать игры стало действительно легче. В двух следующих главах мы рассмотрим инструментальные средства, которые нам понадобятся для написания исходного кода игр, а затем перейдем к созданию игр. Далее>>