状态同步的大厅子游戏 MVC框架 设计

一、说明

现公司的游戏项目都是游戏大厅加各种不同子游戏的结构,走超级APP路线。

搞懂公司的游戏业务代码框架之后,搞新的子游戏时想把一些设计上的东西融入到目前的框架中。

目前最大的问题是框架没有很强的规范性,基础结构只提供了联网,协议解释等功能,保持了相对自由。但代价是每个人的风格不统一,如果上一任的程序不注意,很容易搞出强耦合的代码。

这里想做的第一点优化是在现有代码结构上融入MVC,这样至少能保证做到表现和数据分离,对理解代码,分析问题都可以起到不错的效果。

 

二、设计的UML示意图

 

 

 


三、设计细节

 

1. game_obj是游戏对象,在游戏大厅里,一个子游戏就是一个game_obj,生命周期从游戏开始而开始,退出返回大厅而结束。

2. logic_net管理子游戏的全局事件。game_info是全局model。logic_net是一个全局单例,即使不在游戏中,子游戏仍然需要和大厅交互,这些交互由logic_net来完成。例如选场、匹配界面,与大厅交互的部分(成就,游戏邀请等等),进出游戏等,由logic_net管理。

3. room_controller负责管理游戏玩法,是玩法的核心类。正式开始游戏后,进入的新场景称为游戏房间,所以叫room_controller。logic_net创建并持有room_controller。

4. room_controller的初始化过程:

  1. 创建游戏事件管理器game_event_manager
  2. 创建数据类model_room_info
  3. 创建表现类panel
  4. 利用panel创建网络回调监听,实际监听的代码还是在controller,底层的代码实现了将网络事件与panel绑定时,panel销毁可以自动注销事件注册(这也是代码耦合的万恶之源)。
  5. 创建panel和panel_component的ui回调监听,实际监听的代码是在controller。
  6. 在controller创建其他全局回调监听。

5. room_controller的角色:一切玩法相关功能的入口,读写数据,刷新ui,收发协议等等。注意相关的功能方法放到一起,方便以后对controller进行功能分拆。包括:

(1) 入口方法——主要是各种回调,网路,ui(panel和component分开放),上层其他回调。

(2) 发送协议方法。

(3) 动作管理方法,涉及比较多组件的,或需要更改游戏数据的复杂动作,统一使用动作队列,放到controller集中管理。

6. panel及panel_component负责view及view model的功能。view model的数据及操作方法尽量也放到一起,方便之后抽离view_model层。

ui回调本来考虑放到controller,达到所有程序入口统一管理的目的。考虑到不符合普遍的代码习惯,而且很难做到想象中那么直观,还是放到对应的view里面,统一在_initSelfCallBack()处理。ui回调分为两类:

(1) 纯view的改变或者简单动作,直接在view实现,用cocos自带动作做。

(2) 如果涉及多组件改动,或发送网络请求,或需要读取改变数据,则通过游戏事件管理器,发送信号到controller去做。

总之,比较复杂的ui回调处理,还是由controller处理,达到controller是一切玩法入口的目的。

 

7.一般的交互流程是:

(1) controller收到回调。

(2) controller操作model,进行数据更新。

(3) model完成更新之后,封装表现命令对象

(4) controller操作panel,将表现命令对象传入

(5) panel解释表现命令,并加入指令队列中,在合适的时间进行表现。

 这里用了类似命令模式的方法来进行UI渲染,主要是为了UI的表现能够按顺序进行,在网络波动时对大量积压的网络协议能够有序处理,不会使得表现看起来过于凌乱。

 

8.代码实现过程中,v层和m层都会有很多下级对象。这里要注意一个原则,下级对象不可直接访问上级对象,所有信息只能由上级对象告诉下级对象。

例如引用关系是controller_room -> model_room_info -> model_player。

如果玩家数据类需要知道UI层一些信息,不可以在model_player增加对controller或者view的引用,只能由controller_room调用view的接口获取,然后传到model_room_info, 再到model_player。

这样虽然看似不太方便,但看代码时会比较方便,不会对数据变量的来历感到疑惑,出bug的时候也比较好查是哪一层出的问题。

而最上层的controller_room ,只持有一个总的model和一个总的view对象,这样有利于简化controller_room 的复杂度。

唯一不好处理的地方是用户输入在UI层,逻辑处理是UI层的上级。这里的处理方法是UI层抛事件到controller。

 


四、优劣点及后续优化的一些想法


1对于网络游戏而言,代码功能的入口往往由两部分组成:网络回调及UI回调,UI回调包括用户输入及定时事件。

代码入口统一到 room_controller ,有助于增强代码的可读性,需要了解某个功能,从room_controller开始着手就可以了。

缺点是room_controller 职责过重,代码量逐渐增加。

目前的改善方法主要还是减轻controller的逻辑代码,分到model和view层去处理。

接下来的优化思路是将controller分层,一部分负责逻辑处理,另一部分负责输入(服务端数据和用户输入)输出(发消息到服务端)。

 

posted @ 2021-03-21 22:36  枫林晚月  阅读(262)  评论(0编辑  收藏  举报