Основы XNA

Дата: 30.12.2009
Категории: Visual Studio (C#) XNA Game Studio

Solution ExplorerО том, что такое XNA и что с его помощью можно сделать я рассказывал в статье XNA Game Studio. Описание и возможности. Рекомендую прочесть сперва ее, прежде чем продолжать читать эту.

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

Также рекомендую познакомиться с существующей литературой по XNA Game Studio.

Создание проекта

Проект XNA создается как и любое другое приложение: File -> New -> Project. Если вы установили XNA Game Studio, то в разделе C# у вас появится пункт XNA Game Studio.

3

Затем выбираете проект Windows Game (3.0), как показано на рисунке ниже. Версия может быть другой.

Windows Game

Указываете в какой директории создавать проект и жмите ОК.

Файлы и папки приложения

Итак, вы создали новое приложение, и на экране появилось достаточно много кода, а в Solution Explorer есть несколько элементов.

Solution Explorer

Рассмотрим самые важные из них на текущий момент.

Файл Game.ico (это, надеюсь, и без меня понятно) — иконка исполняемого файла приложения.

Content — это директория в которой будут храниться все ресурсы игры (текстуры, модели, и т. д.)

Program.cs — файл содержащий основной класс приложения.

Game1.cs — класс игры. В файле Game1.cs описаны основные методы приложения.

Последовательность методов

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

1. Первым вызывается конструктор класса Game1;

2. Затем вызывается метод Initialize().

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

З. Далее вызывается метод LoadContent(). В нем вы можете загрузить все необходимые ресурсы для вашей игры.

4. Затем начинается игровой цикл, который состоит из двух методов: Update() и Draw().

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

Метод Draw предназначен для отрисовки на экране всех объектов.

5. После того, как пользователь решил выйти из приложения вызывается метод UnloadContent(). Выгружается весь контент, загруженный в методе LoadContent().

Нужно знать, что методы Update() и Draw() вызываются не последовательно, т.е. на 1 вызов метода Update, метод Draw может вызваться несколько раз. Возможна такая ситуация, что метод Update вызовется, но метод Draw не вызовется.

Также, если свернуть окно, то метод Draw вызываться не будет вообще, но метод Update будет продолжать вызываться.

Объект GameTime — игровое время

В методы Update и  Draw в качестве входного параметра приходит объект GameTime. Он содержит информацию об игровом времени. Оно необходимо для того, чтобы уменьшить зависимость приложения от аппаратного обеспечения. То есть если не учитывать игровое время, то игра на разных компьютерах будет идти с разной скоростью.

Из объекта GameTime мы можем получить несколько свойств.

ElapsedGameTime — время прошедшее с последнего вызова метода Update или Draw.

TotalGameTime — время прошедшее с момента запуска игры.

Полноэкранный режим

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

Посмотрите на конструктор класса, которая должна выглядеть так:

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
}

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

Следущая  строчка указывает путь к директории с контентом игры.

Как я уже сказал выше, GraphicsDeviceManager определяет параметры вывода изображения. Установим полноэкранный режим с разрешением 1280*1024 (если ваш монитор не поддерживает это разрешение, измените его на поддерживаемое). За разрешение отвечают свойства PreferredBackBufferWidth и PreferredBackBufferHeight. Чтобы сделать приложение полноэкранным, установим свойство IsFullScreen = true. Таким образом код будет следующим:

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    graphics.PreferredBackBufferWidth = 1280; // ширина
    graphics.PreferredBackBufferHeight = 1024; // высота
    graphics.IsFullScreen = true; // полноэкранный режим
}

Вывод спрайта

Для вывода спрайтов существует класс SpriteBatch. Это основной объект для работы с 2D графикой. Рисование должно происходить между вызовами методов Begin и End. Описание объекта уже реализовано в созданном шаблоне проекта.

Объявлен:

SpriteBatch spriteBatch;

И его создание в методе LoadContent()

spriteBatch = new SpriteBatch(GraphicsDevice);

Но для начала нужно подготовить изображение и добавить в проект. Щелкните правой кнопкой по Content в Solution Explorer и выберите Add -> Existing Item… Пусть файл будет называться img.png

Добавление ресурса

Для хранения самих спрайтов существует класс Texture2D. Давайте его объявим:

Texture2D sprite;

Затем нужно загрузить добавленный спрайт. Для этого в методе LoadContent пишем:

sprite = Content.Load<Texture2D>("img");

Теперь осталось только вывести спрайт. Метод Draw будет выглядеть так:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin();
    spriteBatch.Draw(sprite, new Vector2(0, 0), Color.White);
    spriteBatch.End();

    base.Draw(gameTime);
}

Первая строка (уже была), это грубо говоря очищение экрана, и заливка цветом указанным в качестве входного параметра в метод Clear, в данном случае это Color.CornflowerBlue

Дальше мы вызываем метод Begin, затем рисуем все необходимые спрайты (у нас будет только один), и вызываем метод End.

Метод Draw объекта spriteBatch отрисовывает sprite в координатах (0, 0), с наложением белого цвета. Кстати, это наложение дает очень интересный эффект.

Вот мы и вывели этот спрайт, правда в углу экрана. Обратите внимание, что у метода Draw есть много вариаций, т.е. в качестве параметров в него можно передавать разное, и соответственно выводить будет по разному. Например, можно с легкостью повернуть изображение на любой угол. Кстати черта XNA, это простота, все сложные алгоритмы были продуманы и выполнены за вас разработчиками из Microsoft. XNA действительно упрощает разработку, а следовательно и ускоряет ее. И вообще, зачем заново изобретать велосипед, если множество алгоритмов уже давно были придуманы и отлично работают? Зачем их снова реализовывать, отлаживать и т. д.?

Это было короткое отступление, а теперь продолжим…

Перемещение спрайта

Как я уже говорил координаты вывода спрайта указываются так:

new Vector2(0, 0)

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

Для начала нужно объявить переменную:

Vector2 cur;

Это двумерный вектор, имеющий 2 координаты — X и Y. Затем в методе Update будем присваивать координатам X и Y координаты курсора:

cur.X = Mouse.GetState().X;
cur.Y = Mouse.GetState().Y;

Код предельно прост, я даже не знаю, что тут еще добавить.

Ну и последнее, нужно будет изменить параметры в функции отрисовки спрайта (метод Draw):

spriteBatch.Draw(sprite, cur, Color.White);

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

Ну и в методе UnloadContent вызываем:

sprite.Dispose();

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

Теперь запускаем приложение и пробуем.

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

Ну на этом все, выкладываю исходники. Скачать.

Коментарии отсутствуют