windows Phone开发(6)第一个 XNA Framework 应用程序
Windows Phone开发现在有两个框架可供选择,一个是SilverLight,主要用于做应用开发,另一个是XNA Framework,主要用于游戏开发。在上一篇当文章中,我结合MSDN的教程简单总结了一下创建SilverLight应用程序的方法和基本步骤。本文将介绍和总结Windows Phone创建基本 XNA Framework 应用程序所需的步骤。
第一, 创建新项目
为 Windows Phone 创建 XNA Framework 应用程序的第一步是创建新项目。
创建新项目的步骤
-
从 Windows“开始”菜单启动 Microsoft Visual Studio 2010 。
-
通过选择“文件 | 新建项目”菜单命令来创建一个新项目。
-
将显示“新建项目”窗口。展开 Visual C# 模板,然后选择 XNA Game Studio 4.0 模板。
-
选择“Windows Phone 游戏(4.0)”模板。填写所需的项目“名称”。还可以指定“位置”和“解决方案名称”。
-
单击“确定”。将显示 Windows Phone 平台选择窗口。为“目标 Windows Phone 版本”选择 Windows Phone 7.1。
-
单击“确定”。此时将创建一个新项目并在 Visual Studio 中打开 Game1.cs 源文件。
第二, 添加内容
下一步是向您的项目中添加内容,在本例中是一个图形对象和一个声音文件。
将内容添加至项目
-
确保“解决方案资源管理器”在 Visual Studio 中可见。如果不可见,则选择“查看 | 其他窗口 | 解决方案资源管理器”来使其出现。
-
要添加的第一个项目是图形文件。本示例将使用默认情况下在该项目的 WindowsPhoneGame1\WindowsPhoneGame1\WindowsPhoneGame1 目录中创建的 PhoneGameThumb.png 文件。可以使用 PhoneGameThumb.png 或自己的图形文件,但是为了获得最佳效果,图形对象的大小应该大约为 64 x 64 像素。
右键单击“内容”节点,在本例中名为 WindowsPhoneGame1Content (Content),然后选择“添加 | 现有项目”。浏览到您的图形文件 - 在本例中为 WindowsPhoneGame1\WindowsPhoneGame1\WindowsPhoneGame1\PhoneGameThumb.png,然后单击“添加”。该图形对象将添加到项目中。
在“解决方案资源管理器”中选择该图形名称,然后在“属性”窗口中查看此文件属性。记下该图形对象的“资产名称”(在本例中为 PhoneGameThumb)。
-
下一步是添加声音文件。本示例将使用 Microsoft Windows 7 附带的 Windows Ding.wav 声音文件。在您的计算机上搜索 Windows Ding.wav 并将其复制到 WindowsPhoneGame1\WindowsPhoneGame1\WindowsPhoneGame1\Resources目录。也可以使用自己的声音文件,但最好是非常短暂的声音,长度大约 1 秒。
右键单击“内容”节点,在本例中名为 WindowsPhoneGame1Content (Content),然后选择“添加 | 现有项”。浏览到您的声音文件 - 在本例中为 WindowsPhoneGame1\WindowsPhoneGame1\WindowsPhoneGame1\Resources\Windows Ding.wav,然后单击“添加”。该声音文件将添加到项目中。
在“解决方案资源管理器”中选择该声音文件,然后在“属性”窗口中查看该文件的属性。记下该声音的“资产名称”(在本例中为 Windows Ding)。
第三, 添加代码
在此步骤中,您将添加执行以下操作的代码:围绕屏幕移动两个图形对象、检测图形对象何时冲突并在图形对象冲突时播放声音。在项目中查看默认情况下为您添加的代码。已提供游戏应用程序的框架。后续步骤将带您完成以下过程:
-
添加一些变量。
-
采用 LoadContent 方法加载您的图形对象和声音资产。
-
采用 Draw 循环在屏幕上绘制您的图形对象。
-
采用 Update 循环更新图形对象的位置并检测冲突。
Gam1.cs文件中的代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using Microsoft.Xna.Framework; 5 using Microsoft.Xna.Framework.Audio; 6 using Microsoft.Xna.Framework.Content; 7 using Microsoft.Xna.Framework.GamerServices; 8 using Microsoft.Xna.Framework.Graphics; 9 using Microsoft.Xna.Framework.Input; 10 using Microsoft.Xna.Framework.Input.Touch; 11 using Microsoft.Xna.Framework.Media; 12 13 namespace WindowsPhoneGame1 14 { 15 /// <summary> 16 /// 这是游戏的主类型 17 /// </summary> 18 public class Game1 : Microsoft.Xna.Framework.Game 19 { 20 GraphicsDeviceManager graphics; 21 SpriteBatch spriteBatch; 22 23 //以下几对变量可用于跟踪每个图形对象及其位置、速度、高度和宽度。 24 Texture2D texture1; 25 Texture2D texture2; 26 Vector2 spritePosition1; 27 Vector2 spritePosition2; 28 Vector2 spriteSpeed1 = new Vector2(50.0f, 50.0f); 29 Vector2 spriteSpeed2 = new Vector2(100.0f, 100.0f); 30 int sprite1Height; 31 int sprite1Width; 32 int sprite2Height; 33 int sprite2Width; 34 35 //该变量来包含我们的声音效果。 36 SoundEffect soundEffect; 37 38 /// <summary> 39 /// 构造方法 40 /// </summary> 41 public Game1() 42 { 43 graphics = new GraphicsDeviceManager(this); 44 Content.RootDirectory = "Content"; 45 46 // Windows Phone 的默认帧速率为 30 fps。 47 TargetElapsedTime = TimeSpan.FromTicks(333333); 48 49 // 延长锁定时的电池寿命。 50 InactiveSleepTime = TimeSpan.FromSeconds(1); 51 } 52 53 /// <summary> 54 /// 允许游戏在开始运行之前执行其所需的任何初始化。 55 /// 游戏能够在此时查询任何所需服务并加载任何非图形 56 /// 相关的内容。调用 base.Initialize 将枚举所有组件 57 /// 并对其进行初始化。 58 /// </summary> 59 protected override void Initialize() 60 { 61 // TODO: 在此处添加初始化逻辑 62 63 base.Initialize(); 64 } 65 66 /// <summary> 67 /// 对于每个游戏会调用一次 LoadContent, 68 /// 用于加载所有内容。 69 /// </summary> 70 protected override void LoadContent() 71 { 72 // 创建新的 SpriteBatch,可将其用于绘制纹理。 73 spriteBatch = new SpriteBatch(GraphicsDevice); 74 75 //该代码将加载该图形对象两次。 76 //随后,可以向项目中添加另一个图形对象,以便您可以拥有两个在屏幕周围反弹的不同图形对象。 77 //给出了每个图形对象在屏幕上的初始位置并计算了每个对象的高度和宽度。 78 79 80 texture1 = Content.Load<Texture2D>("PhoneGameThumb"); 81 texture2 = Content.Load<Texture2D>("PhoneGameThumb"); 82 83 soundEffect = Content.Load<SoundEffect>("Windows Ding"); 84 85 spritePosition1.X = 0; 86 spritePosition1.Y = 0; 87 88 spritePosition2.X = graphics.GraphicsDevice.Viewport.Width - texture1.Width; 89 spritePosition2.Y = graphics.GraphicsDevice.Viewport.Height - texture1.Height; 90 91 sprite1Height = texture1.Bounds.Height; 92 sprite1Width = texture1.Bounds.Width; 93 94 sprite2Height = texture2.Bounds.Height; 95 sprite2Width = texture2.Bounds.Width; 96 97 } 98 99 /// <summary> 100 /// 对于每个游戏会调用一次 UnloadContent, 101 /// 用于取消加载所有内容。 102 /// </summary> 103 protected override void UnloadContent() 104 { 105 // TODO: 在此处取消加载任何非 ContentManager 内容 106 } 107 108 /// <summary> 109 /// 允许游戏运行逻辑,例如更新全部内容、 110 /// 检查冲突、收集输入信息以及播放音频。 111 /// </summary> 112 /// <param name="gameTime">提供计时值的快照。</param> 113 protected override void Update(GameTime gameTime) 114 { 115 // 允许游戏退出 116 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 117 this.Exit(); 118 119 // Move the sprite around. 120 UpdateSprite(gameTime, ref spritePosition1, ref spriteSpeed1); 121 UpdateSprite(gameTime, ref spritePosition2, ref spriteSpeed2); 122 CheckForCollision(); 123 124 base.Update(gameTime); 125 } 126 127 /// <summary> 128 /// 当游戏该进行自我绘制时调用此项。 129 /// </summary> 130 /// <param name="gameTime">提供计时值的快照。</param> 131 protected override void Draw(GameTime gameTime) 132 { 133 GraphicsDevice.Clear(Color.CornflowerBlue); 134 135 // 该代码将在屏幕上图形对象的当前位置绘制每个图形对象。 136 //为图形对象提供了不同的 BlendState 以便它们看起来稍有不同,因为本示例对每个 sprite 使用相同的图形文件。 137 spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); 138 spriteBatch.Draw(texture1, spritePosition1, Color.White); 139 spriteBatch.End(); 140 141 spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.Opaque); 142 spriteBatch.Draw(texture2, spritePosition2, Color.Gray); 143 spriteBatch.End(); 144 145 base.Draw(gameTime); 146 } 147 148 /// <summary> 149 /// 检查对象是否撞到边线,如果撞到,则更改其方向 150 /// </summary> 151 /// <param name="gameTime"></param> 152 /// <param name="spritePosition"></param> 153 /// <param name="spriteSpeed"></param> 154 void UpdateSprite(GameTime gameTime, ref Vector2 spritePosition, ref Vector2 spriteSpeed) 155 { 156 // Move the sprite by speed, scaled by elapsed time. 157 spritePosition += 158 spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; 159 160 int MaxX = 161 graphics.GraphicsDevice.Viewport.Width - texture1.Width; 162 int MinX = 0; 163 int MaxY = 164 graphics.GraphicsDevice.Viewport.Height - texture1.Height; 165 int MinY = 0; 166 167 // Check for bounce. 168 if (spritePosition.X > MaxX) 169 { 170 spriteSpeed.X *= -1; 171 spritePosition.X = MaxX; 172 } 173 174 else if (spritePosition.X < MinX) 175 { 176 spriteSpeed.X *= -1; 177 spritePosition.X = MinX; 178 } 179 180 if (spritePosition.Y > MaxY) 181 { 182 spriteSpeed.Y *= -1; 183 spritePosition.Y = MaxY; 184 } 185 186 else if (spritePosition.Y < MinY) 187 { 188 spriteSpeed.Y *= -1; 189 spritePosition.Y = MinY; 190 } 191 192 } 193 194 /// <summary> 195 /// 检查每个图形对象的边界是否彼此交叉。如果彼此交叉,则播放声音。 196 /// </summary> 197 void CheckForCollision() 198 { 199 BoundingBox bb1 = new BoundingBox(new Vector3(spritePosition1.X - (sprite1Width / 2), spritePosition1.Y - (sprite1Height / 2), 0), new Vector3(spritePosition1.X + (sprite1Width / 2), spritePosition1.Y + (sprite1Height / 2), 0)); 200 201 BoundingBox bb2 = new BoundingBox(new Vector3(spritePosition2.X - (sprite2Width / 2), spritePosition2.Y - (sprite2Height / 2), 0), new Vector3(spritePosition2.X + (sprite2Width / 2), spritePosition2.Y + (sprite2Height / 2), 0)); 202 203 if (bb1.Intersects(bb2)) 204 { 205 soundEffect.Play(); 206 } 207 208 } 209 210 } 211 }
第四,生成和调试应用程序
-
在标准工具栏上,将应用程序的部署目标设置为“Windows Phone 模拟器”。
-
通过选择“调试 | 开始调试”菜单命令运行该应用程序。这将打开模拟器窗口并启动该应用程序。您将看到两个图形在屏幕周围反弹并在交叉时播放声音。
- 如果模拟器超时进入锁定屏幕,您可以通过点按屏幕底部并向上滑动来解锁。
- 您可以通过将光标放在所需的代码行上并选择“调试 | 切换断点”菜单命令在代码中设置调试断点。
- 若要停止调试,请选择“调试 | 停止调试”菜单命令。
效果图如下:
参考地址:http://msdn.microsoft.com/zh-cn/library/ff472340(VS.92).aspx