2024年3月10日发(作者:)
利用有限状态栅重构XNA游对
广g,i1大学华软软件学院刘生建袁冠远
[摘要]在wind0ws系统上开发游戏一般要求开发者不仅要掌握c++语言、Windows SDK,还要了解DirectX、人工智能技术等,这
往往造成较高的游戏开发门槛。随着微软xNA框架的推出,越来越多的开发者可以快速推出自己的游戏作品,但是正因为这个框
架很容易上手,也导致了很多游戏初学者虽然实现了游戏的功能,但是代码的组织较为混乱。本文从实际的教学经验中总结了如何
利用有限状态机原理重构XNA游戏的一些思路。
[关键词]游戏XNA重构 有限状态机(FSM)
1.传统的游戏编程思想
c}}做传统的桌面商业应用程序一般采用事件驱动的方法,代码比
较清晰。而做过游戏编程的人都知道,在游戏编程中因为效率原因一
般不直接采用事件驱动的开发方法,而采用循环查询为主的处理方法,
现状态的处理和迁移。
3.简单的XNA状态机实现
借助c#强大的语言表达能力,我们可以轻松的实现游戏或者精灵
的状态控制。为了今后更好的复用该设计模式,我们可利用c#的泛型
程序主体伪代码如下:
while(没有主动退出&&没有失败)f
Update(time);//更新系统状态
Draw(time);//根据状态刷新屏幕
)
初学者的Update代码往往包含了游戏的所有逻辑处理,我们简化
示意如下:
void update(DateTime delta)(
输人检查; //根据玩家操作改变角色的位置等
人T智能处理;//根据时间改变怪物精灵的位置、速度、魔法值、
能量值等
switch(游戏状态)f
case选关:
If(确认)state=运行;
break;
ease运行:
If(按下暂停键)state=暂停;
Iff超时)stare=失败:
break;
case暂停:
If(按下恢复键)state=运行;
break;
case失败:
If(继续)state=选关;
else退 :
break;
】
)
Draw方法与Update比较对应,本例子中也是根据状态画出不同的
屏幕,比如选关状态画 游戏的可选关卡及操作方法提示,而运行中状
态则画出游戏背景及宝藏、游戏中玩家控制的角色精灵(here)及若干非
玩家控制的怪物精灵(NPCs),这个例子中未展开输入检查及人工智能
处理的代码,可以预见也是很多个判断分支组成的代码。随着游戏逻
辑的不断增加,这样的代码就会迅速变得十分臃肿,难以阅读维护。
2.利用有限状态机的思想来改进代码
在日常生活中有很多事物都只有有限的几种状态,比如家里的电
灯,大楼里的电梯等,电灯有一个开关按钮可以改变其状态,电灯的状
态可以通过图1的示意图来直观展示。同样在游戏中,也可以使用类
似的状态迁移图来表示游戏的状态变化及玩家角色的状态变化,再根
据状态图完成相应的编码。
图l电灯的状态迁移图
一
种最简单的有限状态机包含FSM类来代表有限状态机、FSMState
代表状态类,开发者可以继承出各种具体状态类,在状态类中实现数据
封装及相应的条件跳转来切换到新的状态 。运行时先创建一个FSM
实例并设置它的 前状态为初始状态,之后就在游戏循环中不断调用
FSM的update方法,而该方法最终调用当前状态的Update方法,从而实
————
286--——
表示,首先设计一个所有的状态类State
public class State<T>{//T类型的状态
protected SpriteFont m font;,/用该字体往屏幕上绘制英文文字
protected KeyboardState m
_
keyboardState;//用该状态查询玩家
的按键
public virtual Void Enter(T owner){//进入此状态时被调用
)
,/帧处理函数,owner代表状态的主体
public vitrual void Execute(T owner,GameTime gameTime)(
j
//帧绘制函数,owner代表状态的主体
public virtual void Draw(T owner,GameTime gameTime){
)
public virtual void Exit(T owner){//离开此状态时被调用
1
}
以上的状态祖先类十分简单,实际使用时要创建相应的派生状态
类才可使用。通常游戏本身是有状态的,大部分精灵也是有状态的。
尤其是人丁智能控制的NPC,利用状态来控制会让代码变得比较清
晰。下面就以游戏的状态来实例,本例子中我们设定一个状态是选荚,
另一个状态是运行游戏,相应的状态类如下所示:
public class Menu:sta <MyGame>{//选关的状态
public override void Enter(MyGame owner)(
if(m_font==nul1)//此处加载字体只是在屏幕上绘制调试信
息
nl
~
font=owner.Con[ent.Load<Spritef’0nt>f@”fonts\score”1;
Console.WriteLine(”Enter Menu”);
}
public override void Exit(MyGame owner) {
Console.WriteLine(”Exit Menu”);
)
public override void Execute(MyGame owner,Game 1’hne game-
Time)(
m
keyboardState=Keyboard.GetState0;//获取键盘状态
汀(m—keyboardState.IsKeyDown(Keys.Up)){// ̄v E箭头
owner.Level=owner.Level一1;,/关卡减1
)
if(m—keyboardState.IsK yD0wn(K ys.Down))(
owner.1 evel=owner.Level+1 ill关卡增1
}
if(m_keyboardState.IsKeyD0wn(Keys.Enter))(
owner.GameState:new PIay0;,,按下回车进入运行状态
)
public override void Draw(MyGame owner,GameTime game Fime)
{
string msg String.Format(”Current Level:{O}”,owner.Leve1);
owner.SpriteBatch.DrawString(m font,msg,new Vector2(10,
101 co1or.Gnldenrod);//绘制当前关卡信息
,/绘制操作提示
owner.SpriteBatch.DrawString(m font,”change level(UplDown)
”
,
new Vector2(10,lOO),Color.Azure);
owner.SpriteBateh.DrawStirng(m_font ”OK(Emer)”,new Vec-
tor2(10,1 40),Color.BlueViolet);
1 (下转第288页)
议
2.2 2安全认证服务器
安全认证服务器运行在网络环境下,集中控制所有用户对网络的
访问,同时提供认证、授权和审计服务。
使用者在进行身份认证时,仅需要输入用户名和由电子令牌产生
的“动态口令”。通过安全认证代理强制执行安全口令策略机制,将认
汪信息送安全认证服务器端调用同步信任认证算法模块对“动态口令”
进行认证,保证认证过程的完成。
2.23安全认证代理
◆采用双因素(静态口令及动态口令双因素)身份认证技术和一次
性认证原则,保证一次一密。
◆可支持TACACS和RADIUS远程拨号访问认证协议,允许用户进
行远程拨号访问。
◆用户的重要信息(如口令)均以变换形式在存储设备中存储或存
信道中传输。
◆客户端提供认证API开发接口,包括C、VC、VB、F(.xP“,、POW—
ERBUILDER等各种软件开发接口。可以非常方便地嵌入原应 系统,
无需添加额外的访问设备。
安全认证代理是安全认证服务器的客户端,是企业网络中任何需
要受保护的认证资源。安全认证代理在系统中就像一个“安全哨兵”。
更特别的是:对Web来说,一个安全认证代理是用来保护Web服务器的
安全软件,并且被TCP/IP网络连接到运行着的安全认证服务器上,这就
为Web服务器提供了身份认证服务。T安全认证代理是动态口令Web
的职能关键之处,因为安全认证代理直接被安装在Web Server层上,并
且强制执行安全策略。
当用户试图进入被安全认证代理保护的资源时,用户马上被要求
输入其有效的身份证明,即PIN码和从动态口令卡中产生的动态口
令。这些数据通过SSL传送到安全认证服务器上,在那里验证输入的
PIN和动态口令是否有效。被授权的林果动态口令用户很容易就可进
入,而未被授权的人则被拒绝进入受保护的Web服务器。
安全认汪代理保护Web Server所选定的页面和目录。在Web
Server的目录和文件启动代理软件后,所有试图访问这 被保护的Web
页而的用户,需f}{示动态口令令牌码。只有这些Server数据库巾注册
了的用户才能访问受林果动态口令保护的页面. 冈此,既可以把网站
作为公 资源提供给所有用户,也可以把它作为高机密网站来给可信
任刖户发送保密信息。
安伞认证代婵对如下Web平台提供林果动态l_=I令保护:
一安全认证代理for Windows N F/2000
保护llS虚拟服务器、路径和文件;Outlook Web Access;Mieroso|}
Silt Server和S Server Commeree Edition;Microsoft Proxy Selwerl l
■安全认证代理[or Lotus Dota1.1()
},I I,oIllS数据库(地址簿、LI历、邮件等)、I RL路径和安装存
Wind+,w—NT 台上的Domino Web服务器 的文件
■安伞认证代婵fbr Netseape/iPlanet Well Servers
俅护Well服务器根目录或在Windows NT或UNIX半 (Solaris、
HP一1 JX和AIX)l 的登录认证。
安全认证代理町快捷简便地布置安全服务,而不需要 用户的桌
嘶交 。存用户获准访问机密Web资源之前,必须确定用户的身份,强
制实施他们制定的安全策略,既可以把网站作为公共资源提供给所有
用户,也可以把它作为高机密网站来给可信任用户发送保密信息。
23动态口令双因素安全认证系统的特点
◆开放式体系,系统支持WINDOWS NT、NETWARE、UNIX、LINUX
等网络系统平台。
◆用户数据和动态密码种子受加密保护。
(上接第286页) 1
相信读者不难仿照上面写出自己的运行状态的示意代码了,关键
是在帧处理函数和帧绘制函数应实现游戏本身的需求。下面我们看看
游戏类主要的代码:
public class MyGame:Microsoft.Xna.Framework.Game{
State<MyGame>m
◆支持IIS和APACHE等www服务器,可控制网页的特殊访问。
◆提供ASP调用接口,可轻易实现与WEB服务器的无缝集成。
◆由于令牌是脱机使用的,客户端的应用环境并不局限于计算机
系统,对电话委托系统,甚至是ATM、POS等都可以使用令牌。
◆单向、简捷的认证过程,能够有效防止非授权用户的访问
◆集中式的网络认证和管理,完整的日志功能,便于审汁追踪。
◆抗反向工程,自我保护。
◆可选的热备份认证服务器,确保系统可靠性。
2.4应用程序接口
提供多种应用系统开发接口:
◆C接口、VB接口、FoxPro接口、DELPHI接口、PB接口
◆CGI接口
 ̄ASP接口
 ̄JAVA接口
2.5令牌物理特性
◆Tl桴塑料外壳
◆电子令牌小巧便捷,使用方便
◆加强型电子令牌有按键选择,可提供PIN码输入
◆不使用时自动进入省电状态(指卜式令忡)
◆超低功耗,节能环侏
2.6动态口令舣冈素安令认证系统的发装
动态口令双因素安伞认证系统安装时除r添加必嘤的设 ( 奠
伞认证服务器、安仝认证代理、令牌等,安全认旺服务 要十立人客
原仃的网络内,安令认证代卵足需要侏护的网络资源是系统一{1已经
存的应 )外,只需对原应用系统的I 1々认汪部分稍作改动,就能
动态口令系统的无缝嵌入,I,GE_r DYNAPASS/SERVER提供多种认证接
口,包括C、VC、VB、FOXPRO、POWERBUII 13ER等,以适应不同刖, 的
需要。对于互联网的应用,LGE rDYNAPASS/SERVER提供ASP渊用拔
口、摔件模块,实现与现有WEB服务器的无缝集成。
参考文献
[1]高林计算机网络技术人民邮电出版社
[2]徐俊明组合网络理论科学出版社
[3]段水福.无线局域网(WLAN)设计与实现.浙江大学出版社
创建初始状态:
protected override void LoadContent(){
spriteBatch=new SpriteBatch(GraphicsDevice)
this.GameState=new Menu0;
m
}
在帧处理函数中调用游戏状态类的相应函数:
state;//状态
int m
level;//关卡
if(m—sta/e!=nul1)m—state.Execute(this,gameTime);
在帧绘制函数中也相应调用游戏状态类的相应函数:
protected override void Draw(GameTim gameTime){
m
spriteBatch.Begin0;
GraphicsDevice.Clear(Color.CornflowerBlue);
m
level=l;
if(Ill—state!=nul1)nl—state.Draw(this,gameTime);
}
public State<MyGame>GameStme{
get{return m—state;}
set(
if(m—state!=nul1)m_state.Exit(this);
m
—
base.Draw(gameTime);
m
spriteBatch.Endf1:
)
4.小结
state value;
if(m_state!=nul1)m_state.Enter(this);
}
)
通过有限状态机我们可以实现游戏处理逻辑的模块化处理,提高
了灵活性与扩展性,增加了代码的可维护性,本文通过简单的例子示范
了如何利用有限状态机来重构现有的XNA游戏代码,希望对游戏开发
初学者起到抛砖引玉的作用。
参考文献
通过GameState属性的设置,我们实现了旧状态的离开与新状态的
进入处理,增加了程序的灵活性,比如写日志或者发出提示音等。也免
去了传统的状态机类使用。为了使状态类能正常工作,我们需要首先
--——
[1](美)Mat Buckland著.<(Programming Game AI by Exa1nple}
Wordware Publishing,Inc,2005:43—77
288--——


发布评论