Разработка приложений для Windows Phone 7

Знакомство с XNA

Показывать лекцию целиком

Дополнительные материалы к занятию можно скачать здесь.

Вложенные файлы: Presentation_8.pptx

Вложенные папки: Lecture_8

XNA Framework

Каждый проект XNA использует класс Game, в котором содержатся все важные компоненты игры, графическое устройство, параметры окна и диспетчер содержимого. Можно добавить сюда обработку ввода и работу со звуком. Фактически, все, что игра делает на самом высоком уровне, содержится в классе игры, или, по крайней мере, находится в каком-нибудь компоненте, к которому можно получить доступ из этого класса. Самыми важными методами класса Game являются:

Initialize()
Update(GameTime time)
Draw(GameTime time)

Метод 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>#32;</Start>
            <End>#126;</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 отвечает за перерисовку строки с текстом.

    Вернуться к учебному плану