Знакомство с XNA
Дополнительные материалы к занятию можно скачать здесь.
Вложенные файлы: Presentation_8.pptx
Вложенные папки: Lecture_8
XNA Framework
Каждый проект XNA использует класс Game, в котором содержатся все важные компоненты игры, графическое устройство, параметры окна и диспетчер содержимого. Можно добавить сюда обработку ввода и работу со звуком. Фактически, все, что игра делает на самом высоком уровне, содержится в классе игры, или, по крайней мере, находится в каком-нибудь компоненте, к которому можно получить доступ из этого класса. Самыми важными методами класса Game являются:
Метод Initialize загружает содержимое игры, устанавливает начальные параметры и инициализирует все, что нужно. Его метод LoadGraphicsContent используется для выполнения операций загрузки.
Метод Update вызывается перед рисованием каждого кадра для обновления игрового времени, ввода, работы со звуком, и так далее.
Метод Draw вызывается в каждом кадре для рисования содержимого экрана.
К классу игры можно добавлять классы GameComponent, в которых тоже есть методы Update и Draw. Эти методы автоматически вызываются из методов Update и Draw. Инициализация может выполняться непосредственно в конструкторе [23].
Конвейер содержимого
Конвейер содержимого (content pipeline) используется для импорта, сборки и загрузки игровых составляющих, таких как текстуры, трехмерные модели, шейдеры и звуковые файлы, в игровом проекте. Это значительно сокращает объем кода, необходимого для получения в игре графики, трехмерных данных и шейдеров [23].
Конвейер содержимого состоит из пяти DLL-библиотек:
- Microsoft.Xna.Framework.Content.Pipeline.dll содержит базовые функции для конвейера содержимого.
- Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll используется для компиляции и импорта шейдеров.
- Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll это самая большая из библиотек, содержащая код для импорта файлов трехмерных моделей формата .fbx и поддерживающая множество функций, например функцию наложения текстур [23].
- Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll используется для импорта в игру файлов текстур. Это могут быть файлы используемого в DirectX формата .dds (лучший формат для текстур, поддерживающий аппаратное сжатие), но также поддерживаются и форматы .png, .jpg, .bmp и .tga. Двухмерные спрайты также являются текстурами и для них обычно используется несжатый 32-разрядный формат.
- Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll позволяет импортировать файлы трехмерных моделей формата .x, используемого во многих приложениях и примерах DirectX [23].
Для разработки приложений XNA Microsoft разработала XNA Game Studio. С помощью этой среды разработки можно создавать кроссплатфоремнные игры для Windows, Xbox 360 и Zune.
16 сентября 2010 была выпущена XNA Game Studio 4. Она включает в себя поддержку аппаратного 3D ускорения в Windows Phone 7 и интеграцию с Visual Studio 2010 [24].
В качестве примера приведем приложение XNA, в котором надпись двигается по экрану.
Вначале создаем новое приложение Windows Phone Game 4 в Visual Studio 2010 Express for Windows Phone.
К проекту добавляем шрифт Lindsey:
Со следующим содержимым:
<?xml version="1.0" encoding="utf-8"?> <XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics"> <Asset Type="Graphics:FontDescription"> <FontName>Lindsey</FontName> <Size>32</Size> <Spacing>0</Spacing> <UseKerning>true</UseKerning> <Style>Bold</Style> <CharacterRegions> <CharacterRegion> <Start> </Start> <End>~</End> </CharacterRegion> </CharacterRegions> </Asset> </XnaContent>
Затем заполняем файл Game1.cs (за основу взят пример из [25]):
using System; using System.Collections.Generic; using System.Linq; 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.Input.Touch; using Microsoft.Xna.Framework.Media; namespace Lecture_8 { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; const float SPEED = 240f; const string TEXT = "This is XNA Project!"; SpriteFont Lindsey; Vector2 midPoint; Vector2 pathVector; Vector2 pathDirection; Vector2 textPosition; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; TargetElapsedTime = TimeSpan.FromTicks(333333); } protected override void Initialize() { base.Initialize(); } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); Viewport viewport = this.GraphicsDevice.Viewport; Lindsey = this.Content.Load<SpriteFont>("Lindsey"); Vector2 textSize = Lindsey.MeasureString(TEXT); Vector2 position1 = new Vector2(viewport.Width - textSize.X, 0); Vector2 position2 = new Vector2(0, viewport.Height - textSize.Y); midPoint = Vector2.Lerp(position1, position2, 0.5f); pathVector = position2 - position1; pathDirection = Vector2.Normalize(pathVector); textPosition = position1; } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); float pixelChange = SPEED * (float)gameTime.ElapsedGameTime.TotalSeconds; textPosition += pixelChange * pathDirection; if ((textPosition - midPoint).LengthSquared() > (0.5f * pathVector).LengthSquared()) { float excess = (textPosition - midPoint).Length() - (0.5f * pathVector).Length(); pathDirection = -pathDirection; textPosition += 2 * excess * pathDirection; } base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.White); spriteBatch.Begin(); spriteBatch.DrawString(Lindsey, TEXT, textPosition, Color.Red); spriteBatch.End(); base.Draw(gameTime); } } }Листинг .
Результат:
Функция LoadContent() осуществляет начальную загрузку ресурсов (в нашем случае шрифта Lindsey), задаются начальные координаты надписи с помощью векторов, в функции Update описывается перемещение надписи, а функция Draw отвечает за перерисовку строки с текстом.