Flash mmorpg游戏引擎及工具开发概述-张明光

3,194 views

Published on

Published in: Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,194
On SlideShare
0
From Embeds
0
Number of Embeds
57
Actions
Shares
0
Downloads
68
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Flash mmorpg游戏引擎及工具开发概述-张明光

  1. 1. Flash-MMORPG游戏引擎及工具开发概述<br />张明光(saiman)<br />2010.7.1<br />QQ:457691057<br />Blog:http://wxsr.blogbus.com/<br />
  2. 2. 主题:<br />
  3. 3. WEBGAME 核心(引擎)基础架构<br />1.游戏核心架构设计<br />核心(引擎)是由多个系统组成的共同体,每个系统都负责管理自己<br />专属的职能,系统间协调工作最终完成一项或多项功能(效果).<br />组成:<br />1.事件心跳机制(系统)<br /> 解决交互,互动等问题<br />2.对象管理机制(系统)<br /> 抽象对象,类架构<br />3.资源管理机制(系统)<br /> 各种资源或配置文件管理<br />4.通信管理机制(系统)<br /> 解决核心内外通信问题<br />特性:<br />1.有效地提高开发效率<br />2.有利于团队分工开发<br />3.有利于2次开发及扩展<br />
  4. 4. 职能系统模型----职能管理器<br />1.游戏核心架构设计<br />定义:职能管理器是由一个或多个子管理器(子管理系统组成),<br /> 及一个通信代理组成.经由代理管理接受请求或回馈信息.<br />特点<br />使用特定的通信协议,并经由唯一的进出通道(通信代理)与外界进行通信.<br />从属管理器以单例形式存在,并以特定的命名空间进行封装.<br />基于相同的接口或子接口实现自身的通信协议(命令)及对外访问方法<br />
  5. 5. 事件心跳管理机制 ---------指令管理器<br />1.游戏核心架构设计<br />事件,心跳管理机制<br />
  6. 6. 指令管理器(职能管理器)----事件,心跳管理中心<br />事件,心跳管理机制<br />定义:由心跳指令及事件指令这两种实现了 IOrder接口的指令来作为通信信息载体,并通过指令管代理进行注册分流.到其从属管理器<br /> (心跳管理器,事件管理器)进行对循环或触发类交互的管理中心<br />特点:<br />1. 通信载体实现了共同的接口(Iorder)<br />2. 以回调机制取代事件机制的大部分功能.<br />组成:<br />1.事件管理器<br />AS3事件机制的特征<br />2.心跳管理器 心跳管理的注意事项<br />public interface IOrder<br />{<br /> function get execHandler():Function;<br /> function get callbackHandler():Function;<br /> function setUp(execHandler:Function,args:Array, callbackHandler:Function)<br />}<br />
  7. 7. 一.命令管理模式<br />public interface IOrder<br />{<br /> functionset id(value:int):void;<br /> function get id():int<br /> function execHandler():Object;<br /> function callbackHandler(args:Array):Object;<br /> function setUp(execHandler:Function,args:Array, callbackHandler:Function);<br />}<br />指令模式与as3的事件机制<br />的优势与区别:<br />1.事件机制传递一个事件,<br />需要放到事件流当中.<br />要一层接一层的封装事件.<br />然后通过实现了IEventDispatcher接口的对象将一个事件派发出去.<br />这个过程可能创建的实例很多.而且因为要安插到事件流当中进行冒泡遍历.当注册的事件越多消耗越大.<br />2.指令模式则是以预先封装好的方法及回调方式组装成一个指令原型,通信过程不需理会嵌套的层级数,直接对应用对原型的方法进行回调,而且指令原型实例只有相关的2个方法没有其他相关属性.不像事件机制需要整个对象进行引用,再加上生命周期结束后便可方便御载,销毁.<br />事件,心跳管理机制<br />
  8. 8. 二.事件及心跳管理机制<br />AS3的事件机制(事件流三个阶段)<br />Target.addEventListener(EventType.EVENT_NAME,eventResponse)<br />捕获阶段<br />该阶段包括从舞台到目 ,标节点的父节点范围内的所有点。<br />目标阶段:<br />该阶段仅包括目标节点.<br />冒泡阶段:<br />冒泡阶段包括从目标节点的父节点返回到舞台的行程中遇到的节点<br />事件,心跳管理机制<br />事件管理器:<br /> 对核心的所有交互对象的事件侦听进行<br />强制注册,收集管理,并实现统一的注册,销毁等接口<br />对象回收注意:<br />1.保证该对象没有存在引用关系<br />( 实例属性的要保证为null)<br />2.随意注册事件侦听(弱引用).<br />3.对象的任意引用<br />
  9. 9. 心跳管理器:<br />心跳:以一定的时间间隔为标注,间隔时间内调度一次的事件模式.<br />目的:更好更合理的对需要进行心跳的对象进行统一管理,且节省不必要的性能浪费.<br />途径:<br />DisplayObject.ENTER_FRAME:<br />特征:动作的执行以帧频为频率.每次执行必须最大程度保证当前帧的逻辑及渲染已经完成.(根据执行的情况可能会出现丢帧显现)<br />适合于偏向渲染的心跳处理.如组件,可视对象涉及渲染的属性修改.等<br />Timer<br />特征:能自定义制定的时间间隔进行心跳处理而不依赖于帧频,但帧频的执行对其也有一定影响.执行的间隔的准确度跟当然cpu消耗有直接关系.<br />适用于偏向逻辑型运算的心跳处理<br />setInterval<br />是一个封装好的Timer管理器.但没有实现群组,队列等功能的Timer的工厂模式实现.<br />于as2时的区别主要在于as2时setInterval只要事件间隔到,就会马上执行下一轮代码块,<br />而不管之前的代码块是否已经执行完毕.<br />setTimeout<br />能在执行完制定次数后自动销毁的计数器,是基于setInterval 的一个实现扩展.<br />功能要求:能实现动态创建timer并对相应注册的指令进行操作.<br />对于相同心跳的指令进行群组共同注册到统一timer心跳下以减少timer数目增多导致的性能下降.<br />能进行 增,删,改,查,销毁等操作.根据实际需求还可以实现对同一对象下所有心跳频率的统一停止<br />开始,销毁等功能.<br />该部分功能特别适用对于管理场景下不同角色或怪物的速度,逻辑等<br />事件,心跳管理机制<br />
  10. 10. 破解 playerglobal.swc的<br />SetIntervalTimer部分实现的代码<br />package flash.utils<br />{<br /> import flash.events.*;<br /> final class SetIntervalTimer extends Timer<br /> {<br />varid:uint;<br /> private varrest:Array;<br /> private varclosure:Function;<br /> private static varintervals:Array = [];<br /> function SetIntervalTimer(closure:Function, delay:Number, repeats:Boolean, rest:Array)<br /> {<br /> super(delay, repeats ? (0) : (1));<br />this.closure = closure;<br />this.rest = rest;<br />addEventListener(TimerEvent.TIMER, this.onTimer);<br /> start();<br /> this.id = intervals.length + 1;<br />intervals.push(this);<br /> return;<br /> }// end function<br /> private function onTimer(event:Event) : void<br /> {<br />this.closure.apply(null, this.rest);<br /> if (repeatCount == 1)<br /> {<br /> if (intervals[(this.id - 1)] == this)<br /> {<br /> delete intervals[(this.id - 1)];<br /> }<br /> }<br /> return;<br /> }// end function<br /> static function clearInterval(id_to_clear:uint) : void<br /> {<br />id_to_clear = id_to_clear - 1;<br /> if (intervals[id_to_clear] is )<br /> {<br /> intervals[id_to_clear].stop();<br /> delete intervals[id_to_clear];<br /> }<br /> return;<br /> }// end function<br /> }<br />}<br />事件,心跳管理机制<br />心跳管理器:<br /> 基于与事件管理器相同统一的管理接口<br />对核心的所有交互对象的循环间隔调用进行<br />集中优化管理.<br />注意:<br />1.timer实例越少越好,相同间隔的轨到统一timer管理.<br />2.相同倍数的间隔timer,改用最小公倍数为间隔.<br />3.逻辑型心跳适用Timer实现,重绘型适宜用EnterFrame<br />4.实现对象实例的所有心跳命令的统一分组,回收或暂停<br />
  11. 11. 通信管理机制 -------模块及系统间的通信<br />通信管理机制<br />1.游戏核心架构设计<br />
  12. 12. 通信管理与模块<br />通信管理机制<br />作为游戏核心的一个重要系统机制的同时也是沟通不同系统的的桥梁<br />分类:<br />通信管理:<br />.系统通信管理<br />1.全局数据的存储,查询<br />2.配置数据及常量的管理<br />3.统一接口形式访问管理<br />.模块通信管理:<br /> 对所有模块都将注册其中并对 其进行管理,模块通过接口方法send将信息发送模块管理器,并由模块管理器发送信件<br />对内通信:(核心内)<br /> 系统间通信<br /> 系统内部通信<br />对外通信:(核心外或2次开发)<br />1.模块间通信 <br />2.模块内部通信<br />3.与服务端等外部程序间的通信<br />信件指令 <br />-----扩展命令模式的通信载体<br />Message=Head+Body<br />一个Message(信件)应由两部分组成即Head(信件头,标记信件的通信类型,发信人,收信人等基本信息的载体)及Body(信件主体,通信的行为逻辑,及回调等具体方式的Iorder接口的实现)<br />
  13. 13. MODULE—模块<br />通信管理机制<br />说明:<br />核心(引擎)开发的模块部分主要是为了解决 <br /> 核心外或2次开发时不同功能组成的协调工作,而提供一种模板式开发方式.<br /> 并且封装及提供统一的通信模式<br />模块间通信(ModuleToModule)<br />模块与服务端通信(ModuleToSevice)<br />模块内部的通信(SubModule--订阅式通信)<br />模块化开发<br />模块-Moudle(MVC)<br />public interface IModule<br />{<br /> function get view():IBaseSprite<br /> function set view(value:IBaseSprite):void<br /> function register(moduleName:String):void<br /> function send(message:IMessage):void<br /> functionget proxy():IProxy<br />}<br />
  14. 14. 模块化开发<br />通信管理机制<br />模块分类:<br /><ul><li>9.类型:主线,支线,循环,活动,常规
  15. 15. 10.内容:对话,打怪,收集,押送,探险,特殊
  16. 16. 11.组队 (跟随,同步)
  17. 17. 12.宠物(跟随,同步)
  18. 18. 13.坐骑
  19. 19. 14.法宝
  20. 20. 15.帮会
  21. 21. 16.国家
  22. 22. 17.挂机
  23. 23. 1.登录
  24. 24. 2.角色(装备切换)
  25. 25. 3.导航/技能快捷栏, (键盘操控管理,拖拉管;理)
  26. 26. 4.地图 (bitmapdata矩阵处理)
  27. 27. 5.好友(图文混排,html文本,tree数据结构)
  28. 28. 6.消息 (系统消息,私聊信息,集群信息)
  29. 29. 7.商店 (ui组件设计)
  30. 30. 8 任务(ui组件设计)</li></ul>特点:<br />1.相似度高(一般继承核心的基础模板,不同模块开发者可以相互开发)<br />2.高效(结构清晰,不需要费太多心思去想怎么独立实现,不清楚还可以借鉴其他模块)<br />3.基于核心提供的通信机制(模块开发者可以不需要理会核心的具体实现,<br /> 并且可以基于核心提供的通信机制完成所有通信类问题)<br />4.模块通信的message结构决定了能够将一个封装好的动作指令传递到其他模块<br /> 其他模块在接受到信息后可以不需要重新组织而直接调用相关指令方法<br />
  31. 31. 解决模块内部的通信问题--------SubModule( 订阅模块)<br />通信管理机制<br />模块一般是一个mvc结构<br />这也意味着一个模块将会有多个界面组成,但功能模块的唯一性.<br />由此而导致的问题是<br /> 1.怎么在模块的某些子界面里调用模块的通信接口进行通信<br /> 2.模块在接受到别的模块发送的信息时如果要求该模块下某个组成部分进行操作时,怎么进行通知.<br />SubModule的创建就是为了解决,这两个实际开发中经常遇到的问题而产生的.它的工作原理如下.<br />这里边我的解决方案是采用订阅的方式,通过模块管理器对模块进行订阅式处理.将一个SubModule挂钩到一个模块后, SubModule会通过模块管理器将其注册到该模块下,并在接受信息的接口方法里遍历其所有注册的SubModule(订阅模块)进行信件广播.而SubModule(订阅模块也可以自身的注册信息通过模块管理器查找到该所属的模块并调用该模块的方法进行信件发送)等操作.不需要使用时只要在该模块移除该订阅模块即可.<br />
  32. 32. 对象管理机制<br />1.游戏核心架构设计<br />对象管理机制<br />
  33. 33. WEBGAME 可视对象结构:<br />对象管理机制<br />
  34. 34. 游戏中的可视化对象管理<br />对象管理机制<br />基于统一基类:IBaseSprite<br />1.实现可视对象的事件行为,心跳行为的统一注册管理等.<br />2.所有信息存放于实现统一接口的信息体(IBaseVo)中,用于实现数据与界面分离. <br />3.能实现实例进行的独立完整御载及销毁.<br />图形化管理.<br />1. webgame一般尽量使用位图序列作为呈现对象,具体根据项目要求.<br />2.灵活使用catchAsBitmap<br />(当可视对象渲染频率较少时,或只移动时,MovieClip类时间轴对象对帧画面进行独立catch而不要对整个进行catch)<br />3.矢量对象素材能减少加载的内存消耗,但增加cpu负担(一般做法是加载时用矢量,运行后使用catchAsBitmap转换为位图)<br />Ui组件库<br />1.创建自己的轻量级组件库<br />2.Fl组件包<br />第三方组件库AsWing,<br />FlexSpark 组件框架<br />
  35. 35. 游戏中的对象优化<br />鼠标事件的替代方案--动态4叉树的应用<br />1.解决点击事件中因对象上之上深度的可视对象的存在而阻碍事件的触发.<br />2.实现高效制定范围的对象搜索<br />3.减少深度排序的对象列表数<br />4.用于怪物的简单ai搜索行为<br />5.用户动态绕行阻碍.<br />减少cpu的消耗及内存的使用<br />1.对于非交互类可视对象禁用mouseEnabled及mouseChildren<br />2.addChild(),addChildAt()等方法消耗巨大(排序类操作最好验证判断后使用)<br />3.尽量少用滤镜(消耗较大,创建了两份内存)<br />4.避免大消耗方法使用<br />如:<br />Array.push() <Ayray.unshift ()<Array. splice()<br />Array.pop()<ArrArray.shift()< Array. splice()<br />(数据添加后排序)<br />5.少用Alpha与混合模式<br />6.尽量public替代seter()与geter(), 消耗相当于方法的调用<br />7.尽量使用函数嵌套.<br /> 8.实例数越少越好,脚本越多效率越差(虚拟机的反射遍历)<br />
  36. 36. 资源管理机制<br />资源管理<br />1.游戏核心架构设计<br />
  37. 37. 资源管理机制<br />统一的资源加载,能对加载的资源进行队列,优先级别加载<br />实现素材的共享,最大限度的减少内存的开销.<br />能对不同资源进行分类加载管理解释;<br />能携带相关加载信息.<br />加载器跟提取器分离,资源加载请求加载完毕后要对加载器的请求进行销毁回收.防止因为应用链状关系复杂而导致实际操作中对象的回收失败.<br />
  38. 38. 资源管理流程:<br />Target<br />请求<br />资源提取<br />管理等<br />派发加载事件<br />销毁请求<br />
  39. 39. OTHER--算法及辅助工具<br />3.辅助应用工具<br />2.游戏算法与优化<br />
  40. 40.
  41. 41. 四叉树<br />作为一种数据结构,同样广泛应用于游戏中,(3d游戏)以预先或动态<br />建树的方式达到快速遍历次,减速遍历次数等数据查询工作.<br />用途: <br />1.指定范围内搜索对象<br />2.替代点击事件<br />3.实现简单的AI;<br />4.优化排序,A*等高消耗算法的<br />遍历对象数目<br />……….<br />缺点:<br />需要在初始化时进行一次建树;<br />面积越大耗时越久,<br />注意:<br />不是每个对象更改了就遍历一次树,<br />每次遍历的消耗是巨大的.<br />只需对象位置变化时修改对应的节点即可<br />
  42. 42. 原理<br />公式:<br />rectWidth = Width / (4^(n-1))<br />rectHeight = Height / (4^(n-1))<br />逸代过程中:矩形大小变化与建树节点数目的关系:<br />W_1=10000 <br />1<br />W_2=10000 / 4 = 2500 Sn=4<br />2<br />W_3=10000 / 4*4 = 10000 / 16 = 625 Sn=20<br />3<br />W_5=10000 / 4*4*4 = 10000 / 64 = 156.25 Sn=84<br />4<br />W_6=10000 / 4*4*4*4 = 10000 / 256 = 39.0625 sn=340<br />5<br />W_6=10000 / 1024 = 9.765625 sn=1364<br />6<br />W_6=10000 / 4096 = 2.44140625 Sn=6460<br />7<br />W_7=10000/16384=0.6103515625 sn=21844<br />:<br />每次逸代的节点个数为:(4^)<br />10000像素高宽,逸代6次总节点个数:<br />4+16+256+1024+4096=<br />(4-4096*4)/(1-4)=6460<br />效率影响因素:精度及深度<br />精度:最底层矩形的大小<br />深度:逸代的次数<br />
  43. 43. 45度深度排序<br />【 Function : getOnlyDepthFunc(target:DisplayObject,source:Array):Object】<br />target --物品列表中的某一物品。<br />source --物品列表(包含target)<br />这个条件方法的最终结果是要返回当前某一物品在一个物品列表中的 唯一确定深度 【itemDepth】以及除去了 target 的剩余物品列表【residualSource】。(可以不需考虑其他物品的深度变化,因为这里只关心target的深度,而事实上因为每次确定一个物品的深度时都有可能导致剩余物品的深度变化所以也是不需要考虑其他物品深度变化的)<br />好,先不要问这个方法怎么实现,具体实现下边会提到。下边说说我的这个算法的设想<br />假如现在有一个长度为n的物品列表 【sourceN:Array】,因为假设的已知条件方法【getOnlyDepthFunc】可以返回某一物品在物品列表中的确定深度,我们是否可以<br />通过逸代这个【getOnlyDepthFunc】方法 并且 参数target 以每次执行完后得到的剩余物品列表【residualSource】的某一个物品,source 则以每次执行完后得到的剩余物品列表【residualSource】去赋值,并且把每次得到的在该片段物品列表中target的唯一确定深度 【itemDepth】储存并整理还原为原物品列表 【sourceN:Array】所对应的物品深度,那么我们就应该可以得到最总我们想要的深度已经排好序的物品新数组了。<br />上边就是我的设想,这里为了方便大家理解,这里再点一下要注意的一些地方。方法【getOnlyDepthFunc】返回的深度只是参数source列表里的确定深度,但由于每次逸代的<br />剩余物品列表【residualSource】是总物品列表【sourceN】的剩余片段列表,所以他们存在一个耦合性。<br />处理上我是这么做的,在排序我前先声明一个跟【sourceN】一样长度的空数组【rebackSource】;然后从第一次开始,以第一次得到的深度为索引 ,将索引对应的物品赋值给【rebackSource】数组对应的位上。然后逸代下一次。因为第2次开始已经是剩余物品列表。所以得出的深度【itemDepth】只是相对于每次返回的剩余物品列表<br />【residualSource】的对应唯一深度。但正因为是剩余物品列表,所以我们可以通过从开始项到得到的深度索引【itemDepth】项,不为undefiend的项数,来得到在总列表中的位置。也就是【residualSource】列表的具体项。然后把这次的target赋值给该位置。逸代一共执行品列表 【sourceN:Array】长度次。不用考虑效率,因为每次都是剩余列表的长度都在减少,而且不用排序,是一个高效的嵌套循环。<br />
  44. 44. C-C<br />B-R<br />B-L<br />C-L<br />B-C<br />T-L<br />[B-L]  [B-C] [B-R]  [C-L]<br />[C-C]<br />[C-R]  [T-L]  [T-C]  [T-R]<br />公式:<br />item.sideR=(target.[B].y-item.[L].y)<br />item.sideL=(item.[B].y-target.[L].y)<br />item.sideB=(target.[T].x-item.minZ.[L].x)<br />item.sideT=(item.[T].x-target.[L].x)<br />当item.sideR<0时,item于target的右边;<br />当item.sideL<0时,item于target的左边;<br />当item.sideT<0时,item于target的上边;<br />当item.sideB<0时,item于target的下边;<br />当item.sideL<0且item.sideT<0时,item于target的左上边;<br />当item.sideL<0且item.sideB<0时,item于target的左下边;<br />当item.sideR<0且item.sideT<0时,item于target的右上边;<br />当item.sideR<0且item.sideB<0时,item于target的右下边;<br />当上边4值任意为-1时,target于item的对应边界<br />012345678<br />T-C<br />C-R<br />T-R<br />
  45. 45. 辅助性工具的开发 -------45度地图编辑器<br />1.根据实际需求开发.够用就好.慢慢优化.<br />2.要人性化,符合使用者的使用习惯.<br />3.开发时考虑好编辑器的效率<br />a.不要以可视对象为单位进行编辑<br />b.地图编辑显示时使用游戏中常用的动态显示方式.<br />c.数据存储方式(自定义)<br />
  46. 46. 其他<br />简单角色编辑器:<br />Bitmapdata.<br />Bytearray<br />File<br />图形处理工具<br />(FLJ s-- Flash 文档对象模型 (DOM)<br />场景操作<br />Document 对象<br />Timeline 对象<br />Layer 对象<br />库操作<br />library 对象<br />Item 对象<br />混淆器:<br />加密器:<br />组件封装:<br />
  47. 47. 小结:<br />三.游戏算法<br />A.排序算法 –冒泡排 序,快速排序,深度排序<br />B.寻路算法--广度最优(启发式寻路)<br />C.搜索算法--深度最优(数据结构,2叉树,4叉树,8叉树)<br />D.碰撞算法—图形碰撞,数据碰撞<br /> <br />二.图形处理<br />A存储<br />B效果<br />C渲染<br />D性能<br />四.UI组件<br />A.基本组件<br />B 功能组件<br />C.Aswing<br />D.flexFrameWork<br />一.系统构架<br /> <br />A.通信机制<br /> (模块式通信)<br />C.心跳机制<br />(集约式管理分派事件机制)<br />C.事件机制<br />(指令式通信事件模式)<br />D.资源管理<br />(各自加载统一管理,数据共享)<br />五.功能工具:<br />A.地图编辑器<br />B.Avatar编辑器<br />C.加密/混淆器<br />D.其他<br />六.扩展<br />Alchemy<br />Ant---DailyBuild<br />Jsfl<br />七.其他<br />单元测试<br />----FlexUnit<br />QTP<br />
  48. 48. 谢谢 !<br />

×