Опубликован: 05.08.2010 | Уровень: специалист | Доступ: платный
Самостоятельная работа 1:

Компьютерная 2D-графика в Microsoft XNA Game Studio 3.0

Самостоятельная работа 1: 12345678910 || Самостоятельная работа 2 >
Аннотация: В данной лабораторной работе мы последовательно спроектируем 2D - игру, приведенную в источнике Горнаков С.Г. Разработка компьютерных игр под Windows в XNA Game Studio Express. - М.: ДМК Пресс, 2007, - 384 с.

Эта игра называется " Летящие в прерии " и ее упрощенная легенда заключается в том, что потерпел крушение самолет над прериями, а задача игрока - спасти как можно больше объектов, падающих с неба.

Специализированный пакет для разработки игровых приложений от Microsoft, который называется XNA Game Studio 3.0, содержит набор классов, представляющих собой упаковку управляемого DirectX и существенно упрощающего программирование игр. Пакет XNA Game Studio 3.0 интегрируется в оболочку Microsoft Visual Studio 2008 как бесплатное дополнение.

Все необходимые для выполнения данной работы файлы можно найти в прилагаемом каталоге (кроме Visual Studio 2008 ), а также скачать по следующим ссылкам:

XNAGS30_setup.exe (62.5 MB): http://www.microsoft.com/downloads/details.aspx?FamilyId=7D70D6ED-1EDD-4852-9883-9A33C0AD8FEE&displaylang=en

dotnetfx3setup.exe (2.8 MB): http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=10cc340b-f857-4a14-83f5-25634c3bf043

xnafx30_redist.msi (7.6 MB): http://www.microsoft.com/downloads/details.aspx?familyid=6521d889-5414-49b8-ab32-e3fff05a4c50&displaylang=en

simsetup_r.exe (1.42 Mb): http://ru.sminstall.com/

Lab58_Install.exe (2.8 MB): Установочный пакет - должен получиться в результате выполнения лабораторной работы

и их можно использовать только в учебных целях!!!

Игровая терминология

(С сайта: http://www.xnadev.ru/articles.php?article_id=36)

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

Sprite – этот термин часто заменяют русскоязычным неологизмом спрайт – словарь Lingvo 12 определяет понятие "спрайт" как "элемент динамического графического отображения". В игровой индустрии синонимами слова спрайт являются такие слова, как "изображение", "картинка", иногда пользуются словом "текстура", однако обычно это понятие несет несколько иную смысловую нагрузку. Как правило спрайт – это двумерное изображение, причем, в узком смысле слова это – лишь изображение, а в широком – это игровой объект, который обладает гораздо более широким набором возможностей, нежели обычное изображение. Спрайты имеют прямоугольную форму, однако в компьютерных играх часто встречаются непрямоугольные объекты. Это достигается за счет задавания прозрачных областей при рисовании спрайта. Термин "анимированный спрайт" относится к спрайту, который выводится с использованием анимации, создающей иллюзию движения, перемещения каких-либо частей изображения – движение рук и ног персонажа при перемещении, движение колёс автомобиля, лопастей пропеллеров самолёта и т.д. Анимация обычно реализуется поочередной сменой нескольких статичных изображений, специально подготовленных для того, чтобы создать иллюзию движения.

Textureтекстура. Обычно текстурами называют двумерные изображения, которые "накладывают" на трехмерные модели. В терминологии XNA понятие текстуры и спрайта при разговоре о двумерных игровых объектах совпадает.

Background – фон. Так называется изображение, обычно – соответствующее размерами размерам игрового поля, которое является фоном для других изображений. Фон может быть неподвижным и подвижным. Подвижный фон (scrolling background) используется в играх, называемых скроллерами (scrollers). Скроллинг – это один из принятых игровых терминов. Он означает прокрутку, перемещение содержимого окна. Скроллинговые игры чрезвычайно распространены среди двумерных игр. Например, использование скроллингового фона позволяет создать иллюзию движения в двумерном гоночном симуляторе. Фон в двумерной игре может состоять из нескольких частей, движущихся с различной скоростью – это позволяет создать эффект трехмерности игрового мира.

2D-game – двумерная играигра, в которой использованы двумерные изображения.

3D-game – трёхмерная игра – использующая трехмерные модели и трехмерный игровой мир.

Tile – тайл – небольшое изображение, которое используется для конструирования уровней в играх. Tile можно перевести как "мозаика" или "черепица".

Polygone (полигон, многоугольник) – пространственный многоугольник, который используется для создания трехмерных объектов. Как правило, в компьютерной графике используются треугольники.

Pixel (пиксель) – наименьший элемент растрового изображения, точка, отображаемая на экране. Обычно в пикселях измеряют разрешение текстур (например – 1024х768), экранное разрешение монитора, размеры игровых окон. Слово Pixel – это аббревитура от Picture's ELement.

Texel (тексель) – точка текстуры в трехмерном пространстве.Слово Texel – это сокращение от Texture Element.

Voxel (воксель) – точка трехмерного изображения. Это слово – аббревиатура от Volumetric Pixel – объемный пиксель.

Texture Filtering (фильтрация текстур) – уменьшение искажений при наложении текстур на трехмерный объект.

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

Transparency (прозрачность) – прозрачными могут быть части двумерных изображений – это позволяет создавать изображения сложной формы, которые, фактически, ограничены прямоугольником. Прозрачными бывают и объекты в трехмерном игровом мире – например – это может быть прозрачная вода или стекло, определенным образом преломляющие свет.

Light Model (модель освещения) – способы моделирования освещения объектов.

Создание заготовки приложения

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

  • Запустите установочный пакет XNAGS30_setup.exe, расположенный в прилагаемом к работе каталоге Setup, чтобы интегрировать библиотеку XNA Game Studio 3.0 в уже установленную оболочку Microsoft Visual Studio 2008
  • Запустите Microsoft Visual Studio 2008 с интегрированным в нее пакетом XNA Game Studio 3.0
  • Командой File/New/Project вызовите диалоговое окно New Project, выберите шаблон типа Windows Game и заполните его согласно снимка

Обратите внимание на значение выпадающего списка в правом верхнем углу окна. Поскольку библиотека XNA Framework предоставляет компоненты только игровой составляющей, а основной средой исполнения является библиотека .NET Framework, сразу настроим проект на использование версии .NET Framework 3.0 как наиболее распространенной в ближайшем будущем. Это позволит охватить большее количество потенциальных пользователей нашего продукта. Хотя в конечном итоге нам, для подстраховки, все равно придется включать в установочный диск программы вместе с инсталляционным пакетом игры также и пакеты с установщиками библиотек .NET Framework 3.0 и XNA Framework 3.0.

Оболочка создаст заготовку проекта с именем Game2D и со всеми необходимыми для начальной разработки файлами и подключенными библиотеками.


Файл Game1.cs содержит основной класс игры. Он не имеет графического представления в режиме Design, как в случае классических приложений типа Windows Application, и предполагает последовательное развитие кодовой части только инструментами языка C# совместно с библиотечными типами. В начале файла размещается код подключения необходимых пространств имен, как в обычных приложениях на C#

using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

Заготовка класса Game1, сгенерированная оболочкой, имеет структуру, приведенную на снимке


Обратите внимание, что основной класс игры Game1 расширяет базовый библиотечный класс Game точно также, как в приложениях на базе Windows Forms наследуется библиотечный класс Form. Пять защищенных методов базового класса Game перекрываются заготовками, а также автоматически создается публичный конструктор по умолчанию, в котором выполняется инициализация графического устройства (программируемого конвейера).

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

System.Diagnostics.Debug.WriteLine("Имя_метода()");

и открыть панель Output командой View/Output, то после кратковременного запуска программы получим примерно такой результат

Game1()
Initialize()
LoadContent()
Update()
Draw()
Draw()
Draw()
Update()
Draw()
Update()
Draw()
Update()
Draw()
Draw()
Update()
Draw()
..........
Update()
Draw()
Update()
Draw()
Update()
Draw()
UnloadContent()

Конструктор класса Game1() и метод Initialize() во многих случаях взаимозаменяемы, но только после того, как будет создан главный объект приложения graphics. Сюда добавляется код для выполнения действий, которые нужно выполнить всего один раз при запуске игрового приложения, например, прописать заголовок окна в случае использования оконного (а не полноэкранного) режима.

  • Добавьте в конец метода Game1() код присвоения заголовка окна и его размеров, чтобы конструктор стал таким
    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        // Включается стандартный курсор мыши !!!!!!!!!!!!!!!!!!!!!!!!!
        // this.IsMouseVisible = true;
    
        this.Window.Title = "Оконное приложение игры";
        graphics.PreferredBackBufferWidth = 300;
        graphics.PreferredBackBufferHeight = 300 * 2 / 3;
    }
  • Запустите заготовку приложения, созданную мастером, и получится примерно следующий результат


Метод LoadContent() выполняет загрузку графического содержимого игры, включая векторные 3D-модели или растровую графику любого типового формата.

Метод Update() обновляет состояние игры. В нем располагают код, отвечающий за логику игры на основе получения информации с устройств ввода, анализа звуковой составляющей, анализа столкновений объектов, выхода объектов за пределы ограничивающего объема и т.д. Этот метод срабатывает циклически и принимает в качестве аргумента объект таймера, позволяющий контролировать системное время.

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

Метод UnloadContent() срабатывает при завершении игры и должен освобождать ресурсы, занятые игрой. При стандартной загрузке ресурсов в методе LoadContent() специального кода освобождения содержимого писать не нужно, все выполняется автоматически сборщиком мусора GC. Код выгрузки прописывается только тогда, когда применяются нестандартные загрузчики контента.

Обратите внимание, что при создании заготовки кода приложения игры имя основного класса Game1 сгенерировано оболочкой автоматически (как Form1 в случаях обычных приложений), но при необходимости классу всегда можно присвоить более осмысленное имя, например StartGame, что мы и сделаем.

  • В Проводнике решений Solution Explorer вызовите контекстное меню для файла Game1.cs и, выполнив команду Rename, смените имя файла с Game1.cs на StartGame.cs

После этого оболочка везде в коде заготовки сделает замену Game1 на имя StartGame. Теперь наша задача состоит в том, чтобы последовательно развивая код заготовки и вводя все новые игровые элементы, довести его до зрелой 2D-игры.

Переход в полноэкранный режим и назначение клавиши выхода

В заготовке приложения, созданной мастером, предусмотрен код выхода из игры и находится он в методе Update(). Но этот код расчитан на работу с джойстиком и поддерживается классом GamePad. Наша задача задействовать код анализа клавиатуры с помощью класса Keyboard и структуры KeyboardState и закрепить окончание игры за клавишей Esc. Клавиша Esc распознается с применением перечисления Keys.

  • Измените код метода Update() в основном классе игры для назначения клавиши окончания игры, чтобы он стал таким
KeyboardState keyboardState;
protected override void Update(GameTime gameTime)
{
    // Выход из игры...
    // Читать буфер клавиатуры 
    KeyboardState keyboardState = Keyboard.GetState();
    // Распознать клавишу Esc
    if (keyboardState.IsKeyDown(Keys.Escape) == true)
        this.Exit();

    // TODO: Add your update logic here

    base.Update(gameTime);
}

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

  • Дополните конструктор основного класса StartGame() следующим кодом переключения приложения в полноэкранный режим
public StartGame()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
    // Включается стандартный курсор мыши !!!!!!!!!!!!!!!!!!!!!!!!!
    // this.IsMouseVisible = true;
    //this.Window.Title = "Оконное приложение игры";
 
    // Установка разрешения экрана 
    graphics.PreferredBackBufferWidth = 1024;
    graphics.PreferredBackBufferHeight = 768;

    // Переключение в полноэкранный режим
    graphics.ToggleFullScreen();// или graphics.IsFullScreen = true;
 
    // Проверка разрешения экрана
    System.Diagnostics.Debug.WriteLine(String.Format("width={0}, height={1}",
        this.Window.ClientBounds.Width,
        this.Window.ClientBounds.Height));
}
  • Запустите приложение и убедитесь, что приложение запускается в полноэкранном режиме, причем, установленное разрешение экрана соблюдается (это видно в окне View/Output оболочки при запуске приложения в отладочном режиме). Не забывайте, что для завершения приложения мы назначили клавишу Esc
  • Удалите из конструктора основного класса код проверки разрешения экрана и назначение заголовка окну, поскольку в полноэкранном режиме окна уже нет
Самостоятельная работа 1: 12345678910 || Самостоятельная работа 2 >
Алексей Бабушкин
Алексей Бабушкин

При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.Xna.Framework.Graphics;

   

namespace Application1

{

    public partial class MainForm : Form

    {

        // Объявим поле графического устройства для видимости в методах

        GraphicsDevice device;

   

        public MainForm()

        {

            InitializeComponent();

   

            // Подпишемся на событие Load формы

            this.Load += new EventHandler(MainForm_Load);

   

            // Попишемся на событие FormClosed формы

            this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed);

        }

   

        void MainForm_FormClosed(object sender, FormClosedEventArgs e)

        {

            //  Удаляем (освобождаем) устройство

            device.Dispose();

            // На всякий случай присваиваем ссылке на устройство значение null

            device = null;       

        }

   

        void MainForm_Load(object sender, EventArgs e)

        {

            // Создаем объект представления для настройки графического устройства

            PresentationParameters presentParams = new PresentationParameters();

            // Настраиваем объект представления через его свойства

            presentParams.IsFullScreen = false; // Включаем оконный режим

            presentParams.BackBufferCount = 1;  // Включаем задний буфер

                                                // для двойной буферизации

            // Переключение переднего и заднего буферов

            // должно осуществляться с максимальной эффективностью

            presentParams.SwapEffect = SwapEffect.Discard;

            // Устанавливаем размеры заднего буфера по клиентской области окна формы

            presentParams.BackBufferWidth = this.ClientSize.Width;

            presentParams.BackBufferHeight = this.ClientSize.Height;

   

            // Создадим графическое устройство с заданными настройками

            device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,

                this.Handle, presentParams);

        }

   

        protected override void OnPaint(PaintEventArgs e)

        {

            device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);

   

            base.OnPaint(e);

        }

    }

}

Выбрасывается исключение:

Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл.

Делаю все пунктуально. В чем может быть проблема?

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000