Важной частью разработки любой игры, безусловно, является ее проектирование, которое включает в себя очень большую подготовительную работу. Нельзя просто так сесть за компьютер и с чистого листа приступить к программированию. Необходимо досконально проработать концепцию будущей игры, придумать сценарий, сделать множество рисунков и набросков, распределить обязанности персонажей и многое другое. Это очень сложный этап работы над всем проектом. Правда, вы пока не умеете программировать. Поэтому работать над игрой нам придется по-другому. В течение всех последующих публикаций мы шаг за шагом будем постепенно усовершенствовать исходный код программы, добавляя в игру все новые и новые элементы. Каждый последующий проект – это модернизация предыдущего и новый этап в создании нашей будущей игры. На основе полученных знаний вы сможете спокойно перейти к собственным более сложным и интересным проектам.
Какую игру мы будем делать
В основу игры легла идея космической леталки с видом сверху. По сценарию игры, космический корабль возвращается домой на Землю после изматывающей и длительной экспедиции в звездном пространстве. Подлетая к дому, команда получает приказ с Земли в срочном порядке проследовать к другому кораблю, терпящему бедствие. Самый короткий путь к нему лежит через метеоритное поле. Команда корабля знает, что любое столкновение с метеоритом уменьшает запас прочности силового поля. Как только оно ослабнет до предела, корабль просто погибнет. Поэтому главная задача – избежать столкновения с метеоритами и добраться до бедствующего в звездном пространстве экипажа. Думается, что общий смысл идеи вам понятен. Озвученный сценарий можно превратить, например, в один из уровней большой кампании, но мы будем реализовывать предложенную идею как отдельно взятую игру.
Рис. 1Рис. 5
Двухмерная графика
На сегодня наша задача заключается в том, чтобы научиться правильно подготавливать рисунки для проектов и рассмотреть механизм правильной загрузки и вывода изображений на экран. А начнем мы с основ 2D-графики. В двухмерной графике есть такое понятие, как «спрайт». Спрайт – это простое двухмерное изображение, нарисованное в любом графическом редакторе. В нашей игре будет несколько таких спрайтов, и на текущей стадии в игру добавится изображение космического корабля. Чтобы вывести корабль на экран, необходимо написать в программе несколько строк исходного кода и задать точку вывода изображения в двухмерной системе координат. Двухмерная система координат в программировании 2D-графики перевернута по отношению к обычной декартовой системе координат, к которой мы привыкли со школьных времен. Начало этой системы находится в левом верхнем углу экрана телевизора. Положительная ось Х проходит по верхней части экрана слева направо, а положительная ось Y идет сверху вниз по левой боковой кромке экрана. Отрицательные части обеих осей координат лежат за областью экрана (рис. 1). Ко всему прочему, любой спрайт – это изображение, которое заключено в прямоугольник. Когда мы рисуем спрайт на экране, его начальной точкой отчета всегда будет оставаться верхний левый угол графического изображения (рис. 2). Поэтому, когда вы рисуете спрайт на экране, вы задаете точку вывода именно для верхнего левого угла изображения в той самой перевернутой системе координат (рис. 3).
Каталоги для хранения игровой графики
Все изображения игры, а также любые другие проектные данные можно хранить непосредственно в корневом каталоге проекта, но значительно проще организовать для этих целей простую и понятную иерархию папок. Обычно в XNA Game Studio Express для проектов предлагается следующая структура папок.
Папка Content предназначена для хранения всей игровой начинки, добавляемой в программу. Создав такую папку в каталоге проекта, вы можете добавить к ней еще ряд дополнительных папок для отдельного хранения графических изображений, моделей, звуковых файлов, шрифтов и так далее. Одной из них может быть папка с названием Textures.
Папка Textures чаще всего вложена в папку Content и содержит все графические изображения игры, будь то спрайты, текстуры или игровые карты. Мы также будем хранить всю нашу графику в этой папке.
В своих проектах вы можете создавать любую удобную для вас структуру папок с любыми названиями, мы лишь рассказываем об общепринятом варианте. Чуть позже мы добавим в игру изображение, которое сначала нужно подготовить соответствующим образом.
Подготавливаем графическое изображение корабля
После того как вы сделали рисунок в одном из графических редакторов, в этом изображении нужно вырезать у него фон или подложку. Делается это, чтобы при выводе спрайта на экран вокруг исходного изображения не было видно фона. Если взять наш космический корабль и нарисовать его в графическом редакторе, то по умолчанию мы его нарисуем на белом фоне, который можно также закрасить и другим цветом. Чтобы в игре не было видно фона, его вырезают средствами редактора, и тогда на экране остается только само изображение корабля.
В XNA Framework существует и программный способ решения этой задачи, но в этом случае код игры несколько усложнится, и для читателей журнала этот механизм может быть непонятен. Поэтому пока что проще всего вырезать или стереть фон в изображении корабля. Чаще всего игровая графика рисуется в графическом редакторе Adobe Photoshop, который уже давно стал промышленным стандартом. Поэтому на его примере мы рассмотрим порядок действий, необходимых для удаления фона в изображении, поскольку этот вопрос очень часто интересует начинающих художников.
Откройте Adobe Photoshop и создайте новый файл, выбрав в меню редактора команду File и далее New. В появившемся диалоговом окне New в полях Width и Height укажите размеры будущего рисунка по ширине и высоте (рис. 4). Для корабля мы задаем размер по ширине в 110 пикселей и по высоте 90 пикселей. Размеры корабля были смоделированы ранее на общем фоне экрана и оказались наиболее подходящими под разрешение экрана в 1280 на 720 пикселей. После определения размеров рисунка нажмите в диалоговом окне New кнопку ОК. Редактор на основе полученных данных создаст область для рисования. Теперь нам необходимо создать поверх основного фона новый слой, на котором мы нарисуем корабль. В меню редактора выберите команду Layer и далее в контекстном меню команду New, а затем Layer. Откроется диалоговое окно с названием New Layer. Нажмите в этом окне кнопку ОК, создав тем самым новый дополнительный слой. В панели Layers, которая находится в нижней части правой стороны графического редактора, только что добавленный слой будет иметь название Layer 1 и помечен значком «Кисточка» как текущий редактируемый (рис. 5). Именно на этом слое необходимо рисовать изображение, и тогда впоследствии вам будет очень легко стереть фон у созданного изображения. После того как рисунок будет готов, необходимо просто убрать видимость слоя Background следующим способом. Нажмите в панели Layers левой кнопкой мыши на значке с изображением глаза, который находится напротив слоя Background. Дополнительно можно прямо в рисунке щелкнуть правой кнопкой мыши на слое Background и в появившемся контекстном меню выбрать команду Delete Layer. Как только вы это сделаете, вокруг изображения весь фон будет представлен серо-белыми квадратиками (так обозначается его «прозрачность»). Когда все перечисленные манипуляции будут сделаны, сохраните рисунок в одном из графических форматов (мы будем использовать формат PNG) у себя на компьютере, выполнив в меню редактора команду File и далее Save As.
Рис. 3Рис. 4
Добавляем корабль в проект
После того как вы подготовили изображение корабля, можно приступать к работе над игрой. Откройте проект Ship с диска журнала или продолжайте модифицировать проект, рассмотренный в предыдущем номере «СИ». Чтобы использовать в играх графические изображения, необходимо эти изображения добавить к проектным данным текущего проекта. При этом простое добавление графики в каталог с программой никаких результатов не даст, изображение должно добавляться в проект явно. Но прежде давайте создадим удобную структуру папок для хранения графических файлов проекта, а затем добавим в проект изображение космического корабля.
В открытом проекте щелкните правой кнопкой мыши в панели Solution Explorer на названии проекта. Откроется контекстное меню, где нужно выбрать команду Add и далее New Folder. После выполнения этой команды в каталоге проекта сформируется новая папка, которой нужно дать название Content. Затем в этой папке создайте аналогичным образом еще одну папку, но уже с названием Textures. Вот именно здесь мы и будем хранить графику игры.
Теперь для явного добавления в проект Ship изображения корабля щелкните правой кнопкой мыши в панели Solution Explorer на названии только что созданной папки Textures. В появившемся контекстном меню выберите команды Add и далее Exiting Item. Откроется диалоговое окно Add Exiting Item (рис. 6). В этом окне в списке Files of Types нужно выбрать вид файла, который требуется добавить в проект. Как вы помните, графические изображения принадлежат к типу Content Pipeline, поэтому выберите этот тип, а затем проследуйте из этого диалогового окна в папку, в которой вы ранее сохранили созданный рисунок корабля. Выделите название графического файла курсором и нажмите кнопку Add. Вне зависимости от того, в каком месте файловой системы компьютера лежал корабль, студия разработки игр скопирует файл ship.png в папку Textures текущего проекта.
Рисуем графику на экране
Когда вы явно добавили графическое изображение корабля в проект Ship, можно переходить к работе с исходным кодом класса Game1. Откройте в текстовом редакторе студии разработки игр файл Game1.cs. В глобальных переменных этого класса к имеющимся объявлениям добавим три новых строки кода.
SpriteBatch spriteBatch;
public Texture2D ship;
public Vector2 shipPosition;
В первой строке этого блока кода создается объект spriteBatch системного класса SpriteBatch. С помощью этого объекта мы будем рисовать на экране телевизора всю графику игры. Объявление и создание объекта spriteBatch происходит стандартным образом для XNA Framework и именно такая конструкция кода используется во всех проектах. Затем происходит объявление объекта ship класса Texture2D. Системный класс Texture2D предоставляет программисту возможность работы с двухмерными графическими изображениями. Объект этого класса ship и будет представлять или содержать графический файл ship.png после того как мы загрузим этот файл в игру.
В последней строке этого блока кода объявляется структурная переменная shipPosition структуры Vector2. Эта структура дает возможность задавать сразу две координаты по осям X и Y. С помощью переменной shipPosition в нашей игре мы сможем задавать точку вывода корабля на экран телевизора, а затем с помощью этой же структурной переменной и перемещать корабль по экрану.
Идем далее по исходному коду класса Game1. Для всех последующих проектов нам необходимо выбрать оптимальное разрешение экрана. Если этого не сделать, то студия разработки игр для проекта сама установит разрешение экрана в 800 на 600 пикселей. В этом случае, на каком бы телевизоре вы ни запускали созданную игру, программа будет применять исключительно разрешение 800 на 600 пикселей. Рабочим разрешением для нашей игры была выбрана величина в 1280 на 720 пикселей (High Definition – 720p). Это один из стандартных вариантов выбора разрешения экрана для режима HD, но этот вариант будет работать на всех телевизорах, включая простые кинескопные. Чтобы установить в игре такое разрешение, необходимо в конструкторе класса Game1 добавить всего две новые строки кода.
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
Далее в методе Initialize() нам нужно задать точку вывода корабля на экране следующим образом.
protected override void Initialize()
{
shipPosition = new Vector2(600, 400);
base.Initialize();
}
Начальная точка координат для корабля – это его верхний левый угол. В данном случае переменная shipPosition с помощью структуры Vector2 задает точку вывода корабля на экран по двум осям X и Y. Дополнительно в исходном коде можно сделать и вот такую запись, но эта запись аналогична первому варианту.
protected override void Initialize()
{
shipPosition.X = 600;
shipPosition.Y = 400;
base.Initialize();
}
Если не определять координаты вывода спрайта на экран, то по умолчанию значение положения спрайта задается двумя нулями и тогда корабль будет нарисован в верхнем левом углу экрана. Теперь нам необходимо в методе LoadGraphicsContent() создать объект spriteBatch и загрузить в игру изображение корабля.
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
ship = content.Load(“Content//Textures//ship");
}
}
Рис. 2
Создание объекта spriteBatch происходит типичным образом, а сама конструкция кода используется во всех программах. Во второй строке этого блока кода мы загружаем изображение корабля (ship.png) в программу и назначаем это изображение на объект ship. Теперь, где бы в исходном коде вы ни использовали объект ship, вы всегда будете обращаться к изображению корабля через этот объект. Для загрузки в игру рисунка корабля используется метод Load(). В качестве параметра этого метода указывается путь к графическому изображению. В нашей записи два слеша обозначают папку Textures, находящуюся в рабочем каталоге проекта. Если вы хотите загрузить изображение из корневого каталога, то достаточно указать просто имя файла без слешей и соответственно положить в корневой каталог само изображение. В строке загрузки графического файла указывается только название файла без его расширения. После компиляции приложения, XNA Content Pipeline преобразует все графические ресурсы игры в свой специфический формат XNB, и программа будет использовать уже преобразованные файлы. Теперь нам осталось только нарисовать корабль на экране телевизора. Для этих целей в классе Game1 имеется метод Draw(). В этот метод нам нужно добавить следующие дополнения.
Методы Begin() и End() класса SpriteBatch задают соответственно начало и окончание представления на экране телевизора двухмерной графики. Между двумя вызовами этих методов необходимо рисовать все графические изображения игры. Вызывать в своих программах эти методы можно сколько угодно, но на каждый вызов метода Begin(), должен обязательно следовать вызов метода End(). Само представление или рисование корабля на экране происходит в следующей строке кода.
Здесь первым параметром метода Draw() является объект ship, представленный графическим изображением корабля ship.png. Второй параметр shipPosition задает расположение корабля на экране по осям X и Y. Самый последний параметр задает цвет, в который будет закрашен корабль. Сейчас используется белый цвет, что означает рисование корабля в оригинале без какой-либо дополнительной ретуши. На этом все манипуляции с исходным кодом программы окончены. Можно смело компилировать программу и передавать ее на Xbox 360, но я предлагаю добавить в программу дополнительную информацию.
Рис. 6Рис. 7
Информация об игре
Когда вы открываете игру на приставке Xbox 360, то с правой стороны от названия игры имеется небольшое по размеру окно, в котором разработчики помещают описание игры. Чтобы в своем проекте добавить такое описание, нужно открыть и заполнить в текущем проекте простую текстовую форму. Щелкните на названии проекта Ship в Solution Explorer правой кнопкой мыши и выберите команду Properties. Откроется окно свойств текущего проекта. В этом окне нажмите кнопку Assembly Information. Откроется небольшая по размеру форма, поля которой необходимо заполнить (рис. 7). В этой форме поле Description как раз и служит для описания игры, а также для корректного отображения русского языка в меню приставки Xbox 360 в списке Neutral Language стоит выбрать язык «Russian». После заполнения всех полей формы нажмите кнопку ОК, а затем откомпилируйте проект, передайте на приставку и запустите его. На экране телевизора вы увидите корабль, который пока находится в статическом состоянии, но уже в следующем номере журнала мы научим его перемещаться по экрану, а также добавим в игру космическое звездное небо. <<2-я часть «Игры своими руками»4-я часть «Игры своими руками»>>
1184 Прочтений • [Игра для Xbox 360 своими руками. Часть 3] [12.04.2012] [Комментариев: 0]