浅析Flash游戏架构

先谈前端主架构,前端程序主架构有两个主要任务:


1,要从架构高度合理划分前端各模块,提出可行的实现方案;

2,从AS级别搭建程序架构(非文档级别),制定前端编程规则和接口,规范程序各部分的职责划分。这两个任务其实包括不少具体工做,好比:游戏启动流程制定,肯定哪些SWF文件须要外部加载,那些功能能够从主程序剥离出去单独实现,前端配置文件怎么处理,公共素材怎么处理,MVC三层怎么划分,主程序框架的选定,主程序怎么和后台通信,主程序如何与模块协做,哪些代码应该放在主程序中,哪些代码应该放在模块里,主程序如何既能提供模块所须要的一切功能和数据,同时又相对模块自我保护等等等等。其实我谈的还只是一些大的方面,具体到实现的级别,还有大量细节工做要作。而这些工做在项目启动之初都是很是重要的,直接影响到项目中后期的开发和维护效率。

上面提到的那些点,我不可能全讲一遍,否则就不叫“浅谈FLASH WEB GAME”了!我只挑两个比较核心的内容跟你们略作探讨,就是前端AS框架和模块划分的问题。先谈前端框架:如今市面上流行不少前端框架,无论是针对“FLASH”的,“FLEX”的仍是“通用的”都有。咱们是否必定须要框架,或者必须使用某个框架,这彻底是仁者见仁智者见智的事,从最终的结果上讲,争论这个问题意义不大,我相信一个5W行左右的项目,任何有5年以上编程经验的人,无论用什么做战策略,最终都能攻下山头,把项目作出来。但有一点相当重要:你必须能彻底把握你的架构和你使用的框架,并能跟你的前端同事解释清楚。那好坏架构的区别在哪里呢?区别在于好的架构在开发过程当中会更轻松,你不用每天担忧的你代码,不用天天不停的写文档,以防止本身忘了复杂的逻辑,你能够在任什么时候间开始写代码,在任什么时候间去玩会儿游戏而后回来接着写;区别在于好的架构更符合业界标准,更容易被传统和正统的程序员接受理解;区别在于你能够用很简单的几句话就把你的架构思想描述清楚,用几个很简单的文档就能让别人接手你的代码,在人事变更和工做交接的时候让本身更轻松;区别在于当你掌握了一种通用框架或者本身总结一套成熟的架构后,你几乎能够套用之后的大部分项目,并不断完善它,开发愈来愈轻松,速度却愈来愈快!

咱们的项目,主程序使用的是pureMVC框架,而主UI部分是本身写的。主程序和主UI相互独立,能够单独编译测试。主程序是纯代码,用FLEX SDK编译,而主UI则是界面和AS混写并用FLASH编译。这样就把MVC中的V从物理层面上彻底独立了。


pureMVC框架正如其名字,是一款“纯粹”的MVC框架,在我看来,他只是帮咱们实现了MVC的编程思想和套路,其它多余的功能一点没有,这使它具备更高的通用性,也是它最可爱的地方。根据咱们的经验,pureMVC单核心版就已经彻底能够应对主程序有效代码在10W行如下的项目了。但在我跟不少没有用过框架的前端朋友聊天中,发现他们对这些框架自己就有抵触心理,或者有些对MVC模式都理解的不深入,用起MVC框架又怎能驾轻就熟?还有一些更过度的朋友把本身的问题也归结到框架上,说什么用了pureMVC框架后,本身的项目编译一下要十几分钟,我听了以后啼笑皆非,项目编译慢通常是由于没有合理划分模块致使主程序过大才致使的,跟框架有什么关系?若是由于你们的种种误解和这些人的言论而致使一些新人错过学习这么一款优秀的框架,我以为实为憾事!

pureMVC既然是一种MVC框架,这就意味着你首先要熟悉MVC。这种熟悉绝对不是对MVC的直译:模型、视图、控制器,而是要真正理解为何要把程序划分红这几部分,在划分主程序模块时,要时刻能站在MVC的角度考虑问题,而当面对一段实际的代码时,能快速准确的判断,这段代码应该放在MVC中的哪部分。《pureMVC最佳实践》这份短短几十页的文档中,能够说到处闪烁着MVC的思想火花,不但清楚地阐述了怎么使用框架,并且时刻从MVC的角度告诉咱们应该把哪些逻辑放在哪些部分中,应该注意什么问题。这个文档早已经有中文版,有兴趣的朋友能够本身去看看,文中有的,我这里就不赘述了。我只结合本身的体验谈一些文中可能没有涉及的,也是在真正开发中才会碰到的问题。

1,模型部分在实际开发中除了存储数据,还有其余做用么?是的,其实它的实际职责很是多。它要给Command和Mediator提供接口,响应用户操做,进行数据操做或者请求远程数据服务,进行数据的序列化和反序列化,获得异步数据后可能还要检查数据合法化。但无论怎么样,它始终是在和数据打交道,同时也应该是你的主程序中惟一能够直接和数据打交道的管道,别的部分要想和数据有接触,首先要问问它赞成不一样意。模型处理完数据会以Notification的消息方式通知Command或者Mediator。但绝对不能在Proxy中直接调用Mediator,这是为了保证数据层的独立性、可移植性和重用性,也简化了你的架构思想。不过可移植性这个优点,估计不少搞FLASH WEB GAME的朋友暂时都没啥机会体验,呵呵。‘

2,Command,Command,Command!连叫三声“Command”,但愿能够引发你们的注意。由于Command的使用,在很大程度上反映着你对pureMVC框架的理解,甚至是对MVC模式的理解深度。在pureMVC框架中,各部分通信是用Notification消息,Proxy能够给Command和Mediator发消息,Command能够给Command和Mediator发消息,Mediator能够给Command和Mediator发消息,怎么样?你如今是否是点晕了,这是正常的,其实我也有点晕!当你代码写到必定规模后,你会更晕。其实pureMVC框架这么设计原本是为了让MVC各部分尽可能脱耦,但这带来一个负面状况就是消息发送与接收机制设计的太灵活了,灵活对小项目是好事,但对大项目来讲,每每意味着混乱,甚至会致使灾难。那怎么办呢?只能靠咱们的自觉性自我约束,简化架构思想了。根据《pureMVC最佳实践》中的建议,个人作法是这样的,尽可能使用Command,让Command成为Mediator与Proxy之间通信的惟一桥梁,Mediator和Proxy中发出的Notification,接收者必定是某个Command,而后再由Command处理并将结果转发给真正的消息接收者,Command就算仅仅起一个转发做用,仅仅有不到10行代码,也要建立一个Command类。这样不只使你的架构更加清晰,并且也更符合MVC思想,Command类的大量存在还使你架构的业务逻辑具备了更好的封装性和扩展性,可谓是一箭三雕,何乐而不为?惟一的负面影响多是你须要建立和维护更多的Command类文件,但相对于优点而言,这点影响不算啥。

3,我知道如今可能还有一些朋友在用FLASH IDE写代码,这些朋友的执着让人钦佩,但我想任何一个熟练使用过FLEX BUDIER、FD或者FDT的朋友,都毫不会再回头使用FLASH IDE写代码了。——不对啊?不是谈pureMVC的么?怎么扯到IDE上去了?这是由于我如今要讨论的问题就和IDE有关,假如你如今用的仍是FLASH IDE的话,除了随时写文档外,我真的很难想出一个很好的方案可让你在没文档支撑的状况下,轻松掌握和随时维护几万行代码。可若是你使用的是FDT,就能够在没有文档的状况下,利用“ctrl + r”和“ctrl + 鼠标左键”,以及全文件搜索等工具,瞬间搞清楚代码之间的联系和逻辑,找出要修改的地方。OK,终于到pureMVC了。若是你使用的是FDT,而且开始尝试使用pureMVC框架,可在使用的过程当中,你发现你在写主程序时,仍是不停的使用“ctrl + 鼠标左键”,而不是“ctrl + r”,这说明你必须从新审视你对pureMVC框架的理解了,请审查你的Mediator类,看里面是否是充斥着大量的public方法,若是你的对象之间依旧是经过public方法进行引用,而不是经过Notification通信的,那你也没有必要继续使用pureMVC框架了。

4,单例模式影响到底有多大?pureMVC是一个彻底依赖单例模式的框架。单例模式彷佛在AS界一直有很大争议,这样的话,pureMVC确定也会有相应的争议了。持反对意见的人,大多集中在“性能”和“团队协做”方面,他们认为一个单例持有过多引用会带来性能问题,并且生怕在团队协做中本身的单例类被人无心修改,引起离奇的BUG。性能方面,我以前也没作过10W以上的项目,不敢妄言,但10W行如下的项目,绝对没有问题,若是你两三万行的架构就开始碰到主架构性能问题,估计十有八九是本身的代码写的有问题;团队协做方面,我以为pureMVC的Fa?ade模式是很是灵活好用的,你们能够略作讨论,制定一个简单的规则,好比模块只能经过fa?ade获取数据和发送Notification,不能直接调用主程序其余CLASS,只要架构程序员不犯错,模块程序员甚至连犯错的机会都没有,若是他们有,仍是你的架构思路有问题,请继续审视本身的代码。反正单例模式的问题究竟是什么,我到如今也没彻底搞懂,主要是咱们的项目没碰到过此类问题,但愿碰到过的朋友能再仔细跟火山说说,我也好弄清楚问题到底出在哪里了,本身之后能够更好的避免此类问题发生。

额,框架部分先谈上面4点吧,赶快进入下一个话题,模块划分:模块划分主要包括“核心模块划分”和“子模块划分”。核心模块的划分思路是这样的:它们是游戏启动所必须的,相互之间是紧密联系的,还要常常的被子模块调用;而相对的,子模块的划分思路是:他们在游戏启动过程当中不是必须的,能够在游戏过程当中再加载,子模块相互之间基本上彻底没有联系,一个子模块的增长和删除不会影响到任何其余子模块,子模块可能须要调用主程序的接口或者得到主程序的数据,但主程序绝对不该该依赖某个子模块。

明确了模块划分思路再具体看看哪些部分应该划分为核心模块,哪些部分应该划分为子模块。通常状况下,核心模块按照游戏启动顺序包括:一个壳子SWF → 配置文件包 → 登陆注册SWF → 主程序SWF → 主UI的SWF → 公共素材包。而子模块相对来讲简单不少,好比具体的某个小游戏,某个场景,以及某个场景里的触发功能等等。下面我对核心模块逐一略作解释。“一个壳子SWF”:这是一个体积很小,但意义很大的SWF;它后面老是跟着随机变量,确保每次用户加载的都是最新的;它里面定义着一些须要常常更新并且每次更新都必须保证用户也在第一时间就获得最新值的变量;它里面最好有一个简单背景图,保证用户在超低网速的时候输入游戏网址不至于长时间面对一片空白;它里面有安全策略的设定,是咱们游戏和不少第三方平台合做的基石;它里面还定义着主程序被加载进来以前的游戏启动流程等等。“配置文件包”:核心模块版本号啊,全局文字说明啊,service接口定义啊,各个核心模块须要的配置信息啊什么的,通常是一些XML文件。“登陆注册SWF”:这个简单,在加载重量级的SWF前,先加载登陆注册SWF,能够保证用户第一时间就能打开登陆注册界面,并且能够有效节省服务器带宽。“主程序SWF”:这个就是我前面费了好大劲讲的主程序部分了。“主UI”:主程序和主UI为何要分开两个SWF,我前面已经提过了,后面还有说明,这里暂时不讲。“公共素材包”:公共素材包是一个游戏不可缺乏,但也不能过度依赖的东西。它包括一些全局的道具和效果,好比表情、技能特效、场景传送门等等。公共素材包里面最好就是一些简单的动画,体积小功能简单,严禁在公共素材包里添加上百K的东西,或者代码上百行的小模块,公共素材包建议500K如下。

看了上面的讲解,你能够能以为核心模块分那么多,太麻烦了。不错,在我看来,对SWF加载流程的分解和控制,对异步程序的掌控正是衡量一个AS程序员是否经验丰富,是否足够老道的重要指标,不少从其它语言转到AS并有多年编程经验的朋友,架构方面可能和AS程序员差很少,甚至比不少自学成才的AS程序员作的更好,但这方面每每不如长期与CPU和SWF体积搏斗的老牌AS程序员。核心模块划分的越合理,用户体验每每越好,后期编写和维护代码的效率会越高,但在前期会比较麻烦,并且对架构师的架构经验和能力必须提出更高的要求。什么都不分,主程序、素材、核心模块都弄在一个SWF里,用户一开始必须先下载完这个SWF,或者弄了一堆核心模块和超多公共素材,用户一开始必须面对loading条不停的周而复始,必须等全部核心要素所有加载完成才能进行一些基本操做的作法,从架构角度上讲,是最简单的作法,由于不用过多考虑复杂的异步和SWF拆分问题,但从用户体验和长远的开发维护上讲是很是不利的。根据咱们的经验,用户登陆前加载的全部资源体积应该控制在200K左右,而用户进入游戏主场景前,加载的资源总数应该控制在1M左右。还有前面提到过的那位用了pureMVC后项目编译一下要十几分钟的朋友,估计就是把全部东西都弄到一个SWF里的作法。主程序随便改动测试一下,就要十几分钟,牵一发而动全身,开发效率从何谈起?根据咱们的经验,任何主程序、核心模块还有子模块的编译,都必须在10秒之内,这才是合理的——个人机器是07年花了3000多买的戴尔品牌机。

→谈完主架构,接着谈主UI。主UI通常指主要的人机交互界面,这里的主UI区分于主架构中的mediator,当你看过pureMVC文档后,你就知道了,mediator只不过起到一个真正的V和pureMVC框架之间的桥梁做用,pureMVC里的mediator其实并不实现什么功能,真正的功能都是在主UI里实现的。但主UI又不得不算是主程序的组成部分,由于它不像其余模块,基本上只须要调用主程序的接口就好了,自己并不须要对主程序提供接口。而主UI做为用户操做界面,必须大量的向主程序的mediator提供接口,或者发送events。因此主程序和主UI之间的配合必须很是密切才行。

不一样的游戏类型,能够选择的UI解决方案也不一样。策略类很是适合用FLEX;MMORPG这类标准网游,很是适合用ASWING;而像咱们海底世界这类游戏界面很是夸张,没什么标准规则,又不是太复杂的界面,仍是适合本身开发。相信任何有过游戏项目经验的人都应该能理解,UI也是FLASH开发中的重头戏,不少细节的处理很是麻烦,在项目早期具备很大的工做量。仍是以咱们的项目为例,咱们的UI架构思路是这样的:

1,全部的界面组件都是直接拖放在stage上的,其功能代码大部分都是在发布时编译的,基本上不用new的方式。这种方式的好处是方便编辑界面,从整体上直观的把握全部的UI,减轻程序运行时的负担,同时避免addToStage带来的诸多问题。缺点是,当UI膨胀到必定规模时,可能会须要你有一台配置比较好的电脑——哎,说到这里我就伤心啊,我那台玩魔兽效果全关还卡的电脑,一直陪伴个人整个UI开发历程。

2,UI的FLA层次结构是这样的:第一层是文档类或者与UI主类关联的某个MC,咱们选用的是MC的方式,由于MC的方式更灵活;第二层是这个MC里的全部组件,这些组件大部分是根据功能划分在一块儿的一组元件,好比你的我的面板,而这个组件自己也是个MC;第三层是组件里的全部元件或者共用组件,元件就是背景啊,按钮啊什么的,而共用组件好比滚动条啊翻页组件啊什么的;主要的就这三层,其实那些共用组件MC再往里面双击还能够划分一层。对应FLA的层次结构,AS的结构以下:文档类或者主MC关联的类是第一层,这个类里持有全部的界面元件的引用;第二层是这些界面元件对应的组件CLASS,组件的功能都是在这里实现的,好比我的面板的MC将会对应一个MyPanel的CLASS,这个CLASS里实现MyPanel的全部功能。至于CLASS和元件之间是怎么对应的,我用的是一种松耦合的代理模式,也就是将MyPanel对应的MC做为参数传递给MyPanel这个CLASS,而这个CLASS会有本身的私有变量记录对应MC里须要进行操做的元件,具体到功能实现时,从代码层面上看,就好像CLASS操做的都是本身的私有变量,而不是直接操做界面元件,这样,当界面元件修更名字时,CLASS的改动很小。并且这种代理模式能够实现一个CLASS代理不一样的元件,当界面只是须要修改外观,不须要修改功能时,很是方便。那么这些CLASS是在哪里初始化并得到它要代理的MC呢?正是在主MC对应的UI主类中,好比当得到MyPanel对应的MC后,就会马上public var myPanel:MyPanel = new MyPanel(myPanel_mc);当全部的组件注册完成后,这个UI主类就持有了全部组件的引用,能够方便主程序调用;代码的第三层其实就是共用组件,比较特殊的是,个人共用组件,好比滚动条,也是用代理模式写的。

3,彻底代理模式为咱们创造了一种可能,就是把UI和UI对应的代码分开编译。这跟FLEX的皮肤更换机制有殊途同归之妙,只不过它的组件是要new出来的,布局是要代码控制的,皮肤都是一个个CLASS,总体效果通常都要编译后才能看出来;而个人组件是直接拖到舞台上的,布局大部分是直接在FLASH IDE里手动布置好的,皮肤都是一个个命名过的MC,总体效果编译以前基本上就能看出来。FLEX在更换皮肤的时候,CLASS名绝对不能变,而个人UI在更换皮肤时,MC的名字和层次结构不能变。FLEX关联皮肤是在编译时完成的,而个人UI关联皮肤是在运行时,当启动程序加载完UI代码的SWF和皮肤的SWF后,动态指定的。把皮肤和功能代码分开编译成两个SWF有个好处,就是在实际开发过程当中,咱们会碰到有时候只须要修改代码,而有时候只须要修改界面的状况,固然,就算你把代码和界面一块儿编译成一个SWF文件了,也彻底能够对应这种状况,无非是编译一次的时间稍微长了一点点。可当你面对这样的状况呢:某次游戏版本更新出现情况,须要你目前功能不变,但画面必须退回到上一个版本。这时候你傻眼了吧?你开始对策划们咆哮:“大家能不能想一想好再让咱们作啊?”但你仍是不得不从新打开已经作好的UI,把里面最新的界面再修改回老版本,同时还不敢把最新的删了,由于下一个版本估计立刻又要替换回最新的画面了。可若是你的皮肤和代码是分开编译成两个SWF的,这种状况就简单了,你可让运维从SVN上拉出上一个版本的皮肤SWF从新发布一下就行了,你所要作的只不过是动一下嘴皮。

4,最后谈一下UI的数据层吧,UI是否须要数据层呢?答案是确定的。尽管你能够从主程序那里得到任何你想要的数据,尽管大部分时间你只是须要数据来显示一下而已,但UI本身记住某些数据会大大方便本身写代码。UI的数据层不须要主程序那么复杂,每一个组件有本身的数据变量,而后整个UI再有一个存放公共数据的地方就足够了。

→谈完主程序和主UI,最后再简单谈一下小游戏、场景和模块。先说小游戏吧,小游戏是相对最独立的一块,可能只须要主程序提供用户数据,并在游戏结束后将分数发送给主程序就好了。因此这部分从管理的角度上来说是相对轻松的,但这不意味着小游戏开发就简单了,有时候,麻雀虽小五脏俱全,想开发出一个性能和用户体验俱佳的小游戏绝非朝夕之功,要是碰到一些算法复杂的小游戏,那就有得头痛了。其实对于海底世界这类儿童社区游戏,小游戏应该走创意和简单路线,搞得太复杂了,既很差开发,小孩子又不必定玩得来。

相对于小游戏,场景和模块就和主程序甚至是主UI关系密切了,但无论怎么密切,大部分时候它们都是在所要数据,发送事件,或者触发某个界面的显示与隐藏。若是某个模块的修改须要常常波及到主程序,或者不少模块在作同一件事,重复写着同一段代码,这时候就必须从新审视架构,看是否是某些地方架构的不合理了,不合理的地方,只要时机容许,必定要尽快改掉,绝对不能听任自流,一起小毒瘤最终可能引起癌症。模块和场景程序员在咱们公司实际上是很是累的,由于每周都须要发布新的版本,每次都很赶。在这种状况下,场景和模块程序员的责任心就很是重要,他们随便哪里随意了一下,会直接致使糟糕的用户体验,由于大部分时间,用户直接接触的东西都是他们的做品。架构写的再好,最终模块都作的很糟糕,对用户来讲没有任何价值!因此,一个老道的,有责任心的,可以快速开发出优良用户体验的AS模块程序员,彻底有理由拿高薪,由于他们能作到的,一些所谓的纯架构师未必作获得!
相关文章
相关标签/搜索