`
feipigwang
  • 浏览: 741550 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

第一部分:基础知识(第一章)一个XNA 手机程序(续)

阅读更多

SpriteFont1.spritefont 这个文件名起的实在不是十分生动。建议以它描述的实际字体来进行重命名;如果您需要继续使用默认字体设置,你可以将其重命名为 Segoe14.spritefont。右键单击文件名并选择属性可以查看这个文件的属性——您可以看到该资产的名称,也就是不带扩展名的文件名:Sagoe14。该资产名在程序中指向您所加载的字体。如果你将资产名更改成独立于文件名的名字,在将来的使用中你将会混淆,找不到你所对应的字体。

在初始阶段,XNAHelloPhone项目包含2个C#代码文件:Program.cs和Game1.cs。第一个文件非常简单而且和Windows Phone 7游戏程序丝毫无关!只有当定义了WINDOWS或XBOX标记之后,预处理器指令才能激活Program类。当编译Windows Phone程序时,WINDOWS_PHONE标记取而代之。

对很多小游戏来讲,你几乎会将所有时间都花费在Game1.cs文件上。Game1类继承自Game类,在其原始状态它定义了2个字段:graphics和spriteBatch。在这两个字段的基础上我再增加三个:

XNA Project: XnaHelloPhone File: Game1.cs (excerpt showing fields)

namespace XnaHelloPhone

{

public class Game1 : Microsoft.Xna.Framework.Game

{

GraphicsDeviceManager graphics;

SpriteBatch spriteBatch;

string text = "Hello, Windows Phone 7!";

SpriteFont segoe14;

Vector2 textPosition;

}

}

这三个新的字段简单的指出了什么样的文本会显示,显示的字体以及文本在屏幕上显示的位置。该位置是以相对于显示屏的左上角的像素坐标来指定的。Vector2结构有两个字段指定X和Y的浮点类型。出于性能方面的考虑,XNA的所有浮点值是单精度的。(Silverlight 为双精度。)Vector2结构通常用于二维点、大小和甚至载体。

当游戏在手机上运行时,Game1类被实例化,Game1的构造函数也被同时执行。标准代码如下:

XNA Project: XnaHelloPhone File: Game1.cs (excerpt)

public Game1()

{

graphics = new GraphicsDeviceManager(this);

Content.RootDirectory = "Content";

// Frame rate is 30 fps by default for Windows Phone.

TargetElapsedTime = TimeSpan.FromTicks(333333);

}

第一条语句将图形字段(graphics field)初始化。在第二个语句中,内容(Content)是游戏的属性,它属于ContentManager类型,RootDirectory是该类的属性。将此属性设置为"Content",这是符合当前存储14point Segoe字体的内容目录。第三条语句设置该程序的游戏循环时间,它管理程序更新视频显示的频率。Windows Phone 7屏幕刷新频率为每秒30帧。

Game1实例化后,在Game1实例中调用Run方法,游戏类的基类启动“游戏启动”的进程。第一个步骤之一是调用初始化(Initialize)方法,这一游戏的衍生物可以重写。XNA游戏工作室自动生成框架方法,我没有添加任何内容:

XNA Project: XnaHelloPhone File: Game1.cs (excerpt)

protected override void Initialize()

{

base.Initialize();

}

初始化方法不是加载字体或其他内容的地方。这是稍后时,基类调用LoadContent时的方法。

XNA Project: XnaHelloPhone File: Game1.cs (excerpt)

protected override void LoadContent()

{

spriteBatch = new SpriteBatch(GraphicsDevice);

segoe14 = this.Content.Load<spritefont>("Segoe14");</spritefont>

Vector2 textSize = segoe14.MeasureString(text);

Viewport viewport = this.GraphicsDevice.Viewport;

textPosition = new Vector2((viewport.Width - textSize.X) / 2,

(viewport.Height - textSize.Y) / 2);

}

在此方法中的第一个语句是系统自动提供的。您很快就会看到如何使用此spriteBatch对象来显示子画面(sprites)。

其他语句是我添加的,你会看到我倾向于用this这个关键词作为Content和GraphicsDevice等属性的前缀来提醒自己,他们是属性而不是静态的类。如前所述,Content的属性是ContentManager类型的。通用的 Load 方法允许加载Content到程序,在这种情况下Content的属性是SpriteFont类型。用引号引起来的名称是Content属性中资产的名称。此语句用来存储加载在SpriteFont类型的segoe14字段中的字体。

XNA中,子画面(sprites)(包括文本字符串)通常通过指定相对于左上角或相对于子画面(sprites)左上角的像素坐标来显示。若要计算这些坐标,最好知道屏幕大小和文本显示时特定字体的大小。

SpriteFont类有一个测算大小非常方便的方法,名为MeasureString,以像素为单位返回Vector2对象与特定的文本字符串的大小。(14磅的Segoe UI Mono字体,相当于18-2/3像素的高度,MeasureString调用后返回28的像素高度。)(For the 14-point Segoe UI Mono font, which has an equivalent height of 18-2/3 pixels, the MeasureString call returns a height of 28 pixels.)

XNA程序通常使用GraphicsDevice类的视区(Viewport)属性来获取屏幕的大小。这通过游戏的GraphicsDevice属性来访问,并提供了宽度和高度属性。

然后直接计算textPosition——与Viewport左上角相对应的坐标(point)即为所显示的文本字符串的左上角。(It is then straightforward to calculate textPosition—the point relative to the upper-left corner of the viewport where the upper-left corner of the text string is to be displayed.)

到目前为止该程序的初始化阶段已经完成,真正开始实质性的操作。程序进入游戏循环。在以30 帧每秒刷新率的视频显示同步过程中,程序中的两种方法被不断调用:更新(Update)接着绘制(Draw)不断循环往复: 更新、 绘制、 更新、 绘制、更新、绘制……(如果每次Update方法需要超过1/30秒完成这个过程其实要比前面所述更加复杂,但我们将在后面几章中详细讨论这些时序问题。)

Draw方法可以让你在显示屏上进行绘制。但这就是你想做的。如果您需要执行一些计算为绘图做准备,你就应该先执行Update方法。Update方法是Draw方法的准备程序。很多时候XNA程序会基于用户输入来移动子画面在显示屏上的位置。对手机用户来说,此用户输入主要涉及手指触摸屏幕。所有对用户输入的处理也应该在Update方法中执行。您将会在第3章中看到示例。

你应该编写您自己的Update和Draw方法,以便他们能尽快的执行。这点相当明显,但我猜,有些非常重要的因素却可能不是很明显:

您应该避免Update和Draw的代码定期从该程序的本地堆(heap?)中分配内存。(You should avoid code in Update and Draw that routinely allocates memory from the program’s local heap.)最终,.Net垃圾回收器会收回部分此内存,而在垃圾回收器做这个工作的时候,你的游戏就可能会卡(your game might stutter a bit)。在关于XNA编程的章节中,您将可以看到如何来避免从堆(heap?)中分配内存。

您的Draw方法可能不会包含任何可疑的代码;它通常潜伏在Update方法中从而导致各种麻烦。尽量避免涉及类的任何新的表达式。这些都将导致内存分配。实例化结构是可以的,不过(however有点奇怪,前后不象是转折关系。Instantiating a structure is fine, however, because structure instances are stored on the stack and not in the heap.),因为结构实例化存储在堆栈上,而不是堆(heap?)。(XNA在对象类型的定义中更多的使用结构而不是类,您经常需要在Update中创建。)但在没有明确的新表达式的情况下,也可能发生堆(heap?)分配。例如,连接两个字符串就会在堆(heap?)上创建另一个字符串。如果您需要在Update方法中巧妙的执行字符串操作,则应使用StringBuilder。简而言之,XNA提供使用StringBuilder对象显示文本的方法。

然而,在XnaHelloPhone中,Update方法简直微不足道。程序所显示的文本固定在一个特定的位置。所有必要的计算也已在LoadContent方法中执行完毕。因此,无需对Update方法做任何改动,只需简单的保留XNA 游戏工作室最初创建其时候的样子即可:

XNA Project: XnaHelloPhone File: Game1.cs (excerpt)

protected override void Update(GameTime gameTime)

{

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

this.Exit();

base.Update(gameTime);

}

默认代码使用静态的游戏板(GamePad)类检查手机硬件的后退按钮是否被按下,并使用此功能键退出游戏。

最后,还有Draw方法。以下代码为您创建的是单一背景色淡蓝色的版本:

XNA Project: XnaHelloPhone File: Game1.cs (excerpt)

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.CornflowerBlue);

base.Draw(gameTime);

}

在XNA编程社区,一种名为CornflowerBlue的颜色成为其标志性的颜色。当您开发一个XNA程序时,淡蓝色屏幕的外观是非常令人舒服的,因为这意味着程序如同已经使用过Draw方法一样。

但如果您想要节省电源而在OLED上显示的话,你会得到较暗的背景。在修改后的版本中,我妥协的将背景设置为深蓝色。而在Silverlight中,XNA支持被视为标准的140个颜色。下面代码执行后文本显示为白色:

XNA Project: XnaHelloPhone File: Game1.cs (excerpt)

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.Navy);

spriteBatch.Begin();

spriteBatch.DrawString(segoe14, text, textPosition, Color.White);

spriteBatch.End();

base.Draw(gameTime);

}

显示屏上的子画面(Sprites)被捆绑成一个SpriteBatch对象,它在调用LoadContent时被创建出来。在调用开始(Begin)和结束(End)之间可以有多个调用DrawString来绘制文本和位图。这些是仅有的选项。此特定的索绳调用引用字体、 要显示的文本、 屏幕上,和颜色的左上角相对于文本的左上角的位置。

分享到:
评论

相关推荐

    XNA中文教程《XNA入门指南》第一章

    国内第一本XNA教程中文《XNA入门指南》,经《A Beginners Guild to XNA》原作者 Mike Fleischauer 书面授权中国XNA开发网翻译!书中如有错误请访问www.ChinaXNA.com 或者 www.XNADev.cn

    XNA中文教程Word版(共14章)

    第1章XNA介绍.doc 第2章创建你的第一个游戏Pong.doc 第3章辅助类.doc 第4章游戏组件.doc 第5章编写自己的XNA图形引擎.doc 第6章管理Shader.doc 第7章实现法线映射.doc 第8章 添加天空和地面.doc 第8章Post-Screen ...

    第1章XNA介绍

    作为一个游戏程序员,你或许知道 DirectX ,甚至也许具有XNA 框架的基础知识。 这一个章节解释了如何安装 XNA Game Studio Express 和如何以有效率的方式使用它。它也包含相当多的技巧,这些技巧甚至可能对任何一个...

    XNA入门指南-第一章

    XNA入门指南,,入门级 XNA入门指南 XNA入门指南

    XNA高级编程:Xbox 360和Windows

    第1章XNA介绍,第2章创建你的第一个游戏Pong,第3章辅助类,第4章游戏组件,第5章编写自己的XNA图形引擎,第6章管理Shader,第7章实现法线映射,第8章 添加天空和地面………………

    XNA游戏代码部分一个2D,1个3D的可以参考

    XNA游戏代码部分一个2D,1个3D的可以参考XNA游戏代码部分一个2D,1个3D的可以参考

    XNA中文手册 XNA中文手册

    XNA中文手册XNA中文手册XNA中文手册XNA中文手册

    XNA:管理Shader

    在开始下几章炫酷的normal mapping effect或者post screen shader之前,你首先必须学会基础。shader不仅仅用于高质量的特效,也取代非常简单的渲染过程,这些处理曾经被用在固定功能管道的渲染。在学习了一点儿...

    Windows Phone 10. XNA 3D 模型浏览器

    当年您也可以使用Silverlight来写游戏,或者使用XNA来编写一个以数据为中心的应用程序。每个应用程序框架都有其自身的优势;选择合适的编程模型,可以使您的生产率大幅提高,并且缩短应用上市时间。 在Windows Phone...

    XNA学习资料,XNA

    XNA学习资料,XNAXNA学习资料,XNAXNA学习资料,XNAXNA学习资料,XNA

    xna4.0 中文 + 源码

    xna4.0 中文 + 源码 这个xna教程很不错。源码也在里面。

    XNA Game Studio 4.0.4 (2012).zip

    XNA Game Studio 是一个整合式的游戏开发环境,能够支持程序设计师使用 C# 程序语言,搭配其提供的工具和类别库设计游戏程序,其第一版发表于 2006 年 12 月,这个版本只能支持程序设计师开发能够在 Windows 平台和 ...

    Direct_3D与XNA游戏开发基础(C#版)

    介绍了Direct_3D的基础知识与XNA游戏开发基础

    XNA 3D 演示 例子

    一个 XNA3.0例子 一个 XNA3.0例子

    原创:C# xna 3.1 小游戏 Beta 1.0

    4)网络通讯(这部分就大了,因为有计划写局域网版,想写成广域网版,但技术还不到,加积累。) 网络通讯,延申的就多了:组队系统,聊天系统(私,队,公,世界),角色信息改变事件发送给各各角色的状态信息...

    xna_demo(a demo for xna)

    xna a demo for xna a demo for xna a demo for xna

    Windows Phone开发-XNA基础

    Windows Phone开发-XNA基础

    xna3.0的一个源码

    1.操作键说明: 数字键:1 - 创建PC ;2 - 创建敌人 ;3 - 创建树木 方向键:A、S、D、W 射 击:J

    一个关于XNA GUI的小例子 做工不是很精细,但是可以知道原理

    一个关于XNA GUI的小例子 做工不是很精细,但是可以知道原理

    XNA的一本不错的电子书

    一本国外的关于XNA编程的电子书。XNA主要是像业余游戏开发者准备的游戏开发套件。

Global site tag (gtag.js) - Google Analytics