Microsoft XNA

Microsoft XNA ("XNA's Not Acronymed")，完全支援受控代码的运行环境，由微软提供用以帮助电脑游戏开发、电脑软件开发及管理的一些工具。XNA把游戏设计员从“反复刻版编程”中解放出来，还把游戏开发上的所有需要结合到一个系统之中。XNA 工具集在2004年3月24日在美国加州圣荷西市的游戏开发者大会首次亮相，第一个公开技术预览在2006年3月14日推出，最新版本3.0在2008年10月30日推出。

## 概观

### XNA Framework

XNA Framework 是建置于.NET Framework 2.0上，XNA 将DirectX的功能以受控代码的方式封装运作（因此微软终止了Managed DirectX 9.0的开发，所以有人称XNA为Managed DirectX 2.0），另外还加入了一些专注于游戏开发上类别库，在指定的平台上使“程式码重用”达之最大效果。XNA Framework 在一个特别为有管理式游戏运行的通用语言运行库（Common Language Runtime）版本上运行。这个执行层支援Windows XP、Windows Vista、Windows 7、Windows Phone 7和XBox 360。由于游戏是开发在执行层上，使得游戏能在所有支持XNA Framework 的平台上只要很少甚至不需要任何更改便能运行。现时所有在XNA Framework 上的游戏必需使用C #和XNA Game Studio Express IDE开发。

XNA 的程式都是继承自Game class，它包含了所有重要的游戏组件，比如图形设备（Graphic Device）、窗口设置以及内容管理器，你也可以添加GameComponent class到你的Game class。XNA Framework 把所有用作游戏编程的低阶技术封装起来，例如XNA提供了Effect（BasicEffect）类别来处理大部分绘图着色相关的工作，开发人员不需再理会“矩阵变数”相乘，只要指定物件的World、View、Projection即可，其相乘效果由Shader档自动处理。Effect 本身还能用于加载和编译shader, Effect.CurrentTechnique 可用于指定technique, 像是AmbientLight; Effect.SetValue可以用来设定Shader的参数。一个effect包含一个或多个technique，一个technique包含一个以上的pass。在pass里面可能还有VertexShader, PixelShader，这些元素构成一份effect文件, 这也就是极简化后的HLSL程式码。因此，游戏开发员就可以专注于游戏内容开发而不用关心游戏移植至不同平台上的问题，游戏只要开发于XNA 的平台上，所有硬件只要支援XNA都能运行。XNA Framework 还内置一些工具，例如XACT以帮助游戏内容开发。这些工具还能帮助开发视觉和听觉效果和和像真度很高的模型制作。

XNA Framework 同时支持2D 和3D 的游戏开发也支援XBox 360 的控制器和震动效果。Content Pipeline被用来导入.fbx格式，而且加载像纹理（Texture）、3D模型、着色器（shader）。Shader指令经过编译之后，直接载入到显卡上的GPU来执行。Xbox Live卖场可以升级开发者的XNA Game Studio Express 以使能把他们开发的游戏用于Xbox 360上。

### XNA的流程简介

首先，让我们看看Programs.cs档案的摘要内容:

```
   using System;
   namespace WindowsGame1
   {
   #if WINDOWS || XBOX
   static class Program
   {

       static void Main(string[] args)
       {
           using (Game1 game = new Game1())
           {
               game.Run();
           }
       }
   }
     #endif
   }
```

首先要使用System名称空间，并且判断执行环境是否在Windows或是Xbox360下

并写了一个静态类别 Program 里面的static void Main(string args){...}

是程式的进入点(C#基本常识)，然后产生一个Game1物件game，最后使用Game1物件的run方法执行游戏。

后面介绍有关Game1物件的类别分段程式码

```
  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.Media;
```

这里是很基本的命名空间使用，简介每个名称空间的用途。

- System C#最基本的名称空间
- System,Collections.Generic 泛型的名称空间
- System.Linq Ling(一种嵌入式的数据库查询语言)的名称空间
- Microsoft.Xna.Framework XNA基础名称空间
- Microsoft.Xna.Framework.Audio XNA音效方面名称空间
- Microsoft.Xna.Framework.Content XNA内容输出入名称空间
- Microsoft.Xna.Framework.GamerServices XNA玩家权限名称空间
- Microsoft.Xna.Framework.Graphics XNA绘图名称空间
- Microsoft.Xna.Framework.Input XNA输出入(键盘、鼠标)名称空间
- Microsoft.Xna.Framework.Media XNA多媒体名称空间

```
  namespace WindowsGame1
  {
    .....
  }
```

首先设定了一个WindowsGame1的名称空间，里面包含着一个类别:

```
   public class Game1 : Microsoft.Xna.Framework.Game
   {
     ......
   }
```

Game1类别，继承Microsoft.Xna.Framework.Game类别

其中Game1类别里面又有

```
       GraphicsDeviceManager graphics;
       SpriteBatch spriteBatch;

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

GraphicsDeviceManager类别是管理有关绘图卡方面的设定

SpriteBatch类别则是有关2D图片、文字的绘画设定。

还可以看到一个建构式public Game1{...}

里面让graphics物件先产生出来

并规定Content的目录在Content资料夹之下

接下来

```
       protected override void Initialize()
       {
           base.Initialize();
       }
```

是一个覆写原父类别的初始方法

因为Microsoft已经把繁复的初始内写在父类别当中

变得相当简化，直接呼叫base(基底类别)使用即可

所以可以让制作者专心在游戏重点的初始化

接下来

```
        protected override void LoadContent()
       {
           spriteBatch = new SpriteBatch(GraphicsDevice);
       }
```

这是覆写读取材质 音效...etc的方法，先让spritBatch物件透过绘图装置参数，而产生

然后制作者可以上载其想要的内容，写法如下:

```
  Content.Load<T>("AssetName");
```

T可以是很多种类型，像是Texture2D、Model...等，而AssetName则是内容名称。

这里主要是使用到了泛型

```
       protected override void UnloadContent()
       {

       }
```

这个覆写方法是用来回收内容的。接下来

```
       protected override void Update(GameTime gameTime)
       {
           if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
               this.Exit();
           base.Update(gameTime);
       }
```

这是覆写了逻辑更新的方法，也是整个游戏的重心所在，GameTime物件可以取得游戏时间。

另外透过GamePad物件 可以得知玩家1是否按下了倒退键而结束游戏如果想透过键盘可以这样写:

```
   if (Keyboard.GetState().IsKeyDown(Keys.Back)){...}
```

最后会呼叫父类别 base.Update(gameTime);

接下来

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

这部分是绘图的部分，也需要游戏时间确定画面跟逻辑更新是同步的。

首先使用GameDevice物件Clear方法，把画面清成淡蓝色，同时也呼叫父类别进行运作。

Update跟Draw会连续进行每秒钟60HZ的更新速度来跑动游戏，直到出现离开程式指令。

### XNA中实现Shader

BasicEffect是XNA 内建的 Shader, 支援12种渲染模型，ContentPipeline根据xnb模型文件说明，设置模型的MeshPart的BasicEffect参数。

XNA中实现Shader很简单。对XNA程式来说，Shader是一个小程式，只要把shader文件（.fx）导入到Contents 即可，会自动生成素材（material）。

```
 '''technique''' Technique1
 {
     '''pass''' Pass1
     {
        VertexShader = '''compile''' ''vs_2_0'' VertexShaderFunction();
        PixelShader = '''compile''' ''ps_2_0'' PixelShaderFunction();
     }
 }
```

再透过XNA Effect class 来加载和编译shader。HLSL可以在XNA或是DirectX使用。

```
 effect = Content.Load<Effect>("MyShader"); 
 effect.CurrentTechnique = effect.Techniques ["AmbientLight" ]; 
 effect.Begin(); 
 foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
 {
    pass.Begin(); 
 ... 
    pass.End();
 }
 effect.End(); // 終止使用 effect
```

如果想要改用BasicEffect 以外的Shader, 你必须自己呼叫DrawPrimitive。

### XNA Build

2006年, Microsoft XNA Build March 2006 CTP 在GDC 上被发布。XNA Build 是一工具，允许你管理复杂的编译，类似Msbuild 和Ants，功能更强大。2006年8月30日微软宣布了XNA Game Studio Express Beta1。2006年12月微软又发布了XNA Game Studio Express的正式版，该版本加入了内容管道（Content Pipeline）。

### XNA Game Studio

2010年美国当地时间3月15日，微软官方XNA发布了期待已久的XNA 4.0的社区预览版和路线图，包含在Windows Phone Developer Tool CTP中。目前只有英文版本，可以用于编写Silverlight或XNA for Windows Phone游戏，Xbox游戏，PC游戏，没有Zune游戏的开发模版。

#### XNA Game Studio Express

第一个XNA Game Studio Express 的beta版本首度于2006年8月30日提供下载，2006年11月1日有第二个版本推出。2006年12月11日微软首度提供正式版

2007年4月24日, Microsoft 更新 XNA Game Studio Express 1.0 Refresh.

#### XNA Game Studio 2.0

XNA Game Studio 2.0 于2007年12月13日推出. XNA Game Studio 2.0Visual Studio 2005亦实作有相同的特色与功能 (包括免费的 Visual C# 2005 Express Edition)。

#### XNA Game Studio 3.0

XNA Game Studio 3.0 (基于Visual Studio 2008) 支援Zune的游戏开发。beta版在2008年9月推出.2008年10月30日推出正式版. XNA Game Studio 3.0 目前可支援 C# 3.0, Visual Studio 2008之上还支援LINQ. 在XNA3.0中，SoundEffect可以不透过XACT也可以做到特效的处理。

#### XNA Game Studio 3.1

XNA Game Studio 3.1于2009年6月11日推出。可支援 video playback, 并修正了Audio API, 还支援Xbox LIVE Party system 并且可以使用 Xbox 360 Avatars。

#### XNA Game Studio 4

XNA Game Studio 4 最早2010年3月9日由 "Community Technical Preview" 在 GDC 上发布, 并于2010年9月16日完整推出。XNA 4整合了Visual Studio 2010, 可支援Windows Phone 7 平台 (包括：3D API的硬件加速)。VertexDeclaration 在 XNA Game Studio 4.0中略有改变，另外SpriteBatch.Begin也可以配合pixel shader。

### XNA Framework Content Pipeline

XNA架构素材管道（XNA Framework Content Pipeline）是一种可延伸的素材处理框架，素材（Content）是在Visual C# Express内进行管理。在添加素材时，需要选择工具（importer），例如: Autodesk FBX，.FX, .XAP，这些工具用于接收资料，FBX是一种转移3D（3D transport）文件格式，将其标准化（normalize）。

### XDK Extensions

正式名称是 XNA Game Studio Professional, XDK Extensions 是 XNA Game Studio 附加，可用于发展Microsoft Xbox 360.

### XNA 批评

虽然已被世界上很多开发员采用，但XNA 并未能真正发挥的作用，例如使游戏编程更容易。这是因为他没有一些重要的功能如骨骼动画（Skeletal animation），对初学者而言还是比较复杂的编程。另一个问题是有人认为XNA 没让开发者有太多控制权，这使得大多数的大型游戏制件过还是用C++直接调用DirectX。

在程式编辑上，XNA 确实大幅改善了繁杂的程式设计。包括：资源回收系统、简易声音API, 与背景保护程式的冲突改善等。但是由于企业界已经投入大量心力在C++与DirectX上面，目前仍然鲜见有企业愿意针对新语言C# 还有新平台XNA 进行投资。

## 外部链接

- Microsoft XNA official homepage
- "XNA Game Studio Express Beta 2 Launches" from IGN
- XNA Samples, Videos, GameComponents and Articles

## 基本资料

- 日语原文：XNA
- 开发者：Microsoft
- 软件版本周期：4.0
- 软件版本周期：2010年9月16日
- 操作系统：Microsoft Windows
- 类型：应用程序框架
- 许可协议：EULA
- 网站： XNA Homepage