u3d游戏客户端架构

来源:互联网 发布:古罗马 知乎 编辑:程序博客网 时间:2024/04/30 00:42

原文地址(http://blog.csdn.net/xtxy/article/details/8474506)

主要是mvc架构,


M层为数据层,两个用途:1保存数据;2发送数据更新信息;

V层为视图层,两个用途:1接受用户从界面上的操作;2根据M层的数据显示相应的界面;

C层为控制层,两个用途:1处理和界面无关的代码逻辑;2接受和处理网络数据;


继续……


按照自己的经验,游戏中的mvc架构有两种思想,1,以mvc架构为主,整个框架就是一个mvc架构;2,以对象思想为主,对象中使用mvc架构,整个框架使用一个平行结构。先看看使用mvc架构的方式,如下图:



各个模块分为mvc三部分,有些模块可能只有其中一部分,比如只有view,只有model等。不同模块的mvc三部分对于其他模块也是可见的,比如bagview可以访问rolectrl,也许不需要访问,这里只是举例说明,rolectrl对于bagview是可见的。

整个框架的运行流程如下:

A 玩家在界面上操作的情况:

1 玩家的输入在view层处理,比如玩家在包裹面板上使用了一个道具,此道具的作用是给玩家一个buf,操作由bagview处理;

2 bagview将使用道具的操作转换为和界面无关的操作,发送给bagctrl,比如将界面上该道具的位置转换为包裹中的索引位置;

3 bagctrl在收到请求后将操作组装成请求包,通过networkIO发送给服务器;

此时,操作的前半部分就已经结束,操作带来的影响需要服务器处理

4 服务器返回操作结果,比如此时返回了两个协议,通过NetworkIO中对包的协议分析,分别发送给bagctrl处理和rolectrl处理;

5 bagctrl根据包的内容,此处应该是包裹中扣除一个道具,调用bagmodel的方法,扣除指定的道具;

6 bagmodel将数据更新,并发送包裹更新的事件到事件管理器;

7 事件管理器将包裹更新事件广播出来;

8 bagview注册了包裹更新事件的监听,bagview在收到事件后判断是否需要更新界面显示,如果需要,则获取bagmodel的数据,根据数据更新界面;

包裹的处理就已经完成了

9 rolectrl根据包的内容,此处应该是玩家拥有了一个新的buf,调用rolemodel的方法,增加buf;

10 rolemodel将数据更新,并发送玩家信息更新的事件到事件管理器;

11 事件管理器将玩家信息更新事件广播出来;

12 roleview和headview都注册了玩家信息更新事件的监听,

13 roleview根据当前玩家状态决定是否需要更新玩家3d形象,如果需要,则获取rolemodel的数据,做相应更新,比如在头顶加一个特效等;

14 headview根据当前玩家状态决定是否需要更新玩家头像信息,如果需要,则获取rolemodel的数据,做相应更新,比如在面板上加一个buf的图标等;


B 处理网络包的情况,其实就是上面流程中从步骤4开始到最后。


整个流程中需要注意几点:

1 在接受玩家的操作之后,如果没有特殊需求,view不能直接更改显示,显示的更改都要根据model发出的事件来触发;否则,在多个条件影响同一个view时,会出现错误;

2 view不能直接修改model的数据,只能读取,model的修改只能由ctrl来做;否则整个框架在游戏规模变大之后会变得相当混乱;

3model的作用只能是修改自身数据,并且发送事情出来,不能有其他操作;


由于完全开发各个模块各个层之间的可见关系,会将整个框架变为一个很复杂的网状结构,给拆分和扩展带来很大的麻烦,所以在可见性上做以下限制:

1 model层不能调用任何其他模块方法,只能调用事件管理器方法发送事件;

2 control层只能调用自己模块的model层方法;也就是说control层不能修改其他模块model层的数据;如果一个control必须要更改另外一个model的数据,可以通过调用另外一个control的方法来间接修改;

3 control层之间可以相互调用;因为处理网络IO的包时不管怎么样都需要在一个地方处理各个模块之间的交互,所以可以放在control层;

4 view可以调用其他模块的control层,但是不能view调用其他view,如果出现这种情况,一般都是设计不当造成的;


整个框架的调用关系就如下所示:



原创粉丝点击