声明:此篇文章不介绍如何使用cocos2dx制作游戏。站在架构师的角度如果制作游戏。
以我多年的游戏开发经验,和其他技术积累, 市面的所谈的一些软件架构模式都不太适合游戏软件。
我指的架构模式,MVC、MVP、MVVM、MVI。 他们只适合应用软件里,以数据为主导的,显示为辅的功能性软件里。
web应用如 淘宝,或者某某管理后台, 都是数据为主导,有一堆商品数据,用户信息数据。网页上做的事情基本上概括为增删改查,
大部分应该没有这样需求吧, 10个按钮中,可以随意拖动按钮,然后下次进入时,在按照用户拖动后顺序显示出来。
假定拖动是在一个小容器中,那么推动的过程还需要检测位置信息然后进行设置位置信息。 一个物体的变化,引起周边UI的变化。
我举这个例子,是想强调大部分WEB应用都不是UI强交互型的。包括大部分软件。
应用型软件上属于功能性软件,比如拍照,记事本,聊天。
游戏软件特性特点:
需要和用户实时交互,UI渲染,核心主要界面表现层和游戏玩法上,而游戏玩法成千上万
游戏玩法往往和界面紧密相连,比如麻将游戏,手上有14张牌,玩家打了一张牌,如何知道玩家打的是什么什么牌,
我相信百分九十游戏程序员,应该会直接 ui.cardValue 类似这样的方式吧。
再比如创建房间面板,
经过一堆选项设置之后,你如何清楚的知道用户选择的是什么。不可否认,这个可以按照MVC或者MVP模式或其他来设计。
但是你经常需要思考,Model是里面有哪些数据,应该有哪些行为。 控制器会有几十事件监听,view可以交给cocos studio工具,但是也需要定义很多状态改变的东西。
游戏软件基本上属于交互式软件。经常操作手机屏幕控制UI显示。
我总结了几个游戏开发中经常需要解决的几个点:
1,某个事件产生时,UI当前的数据
2,某个事件产生时,UI在当前场景的位置
3,某个事件产生时,UI相对其他UI的位置。
4,重启场景,需要完全恢复愿状态,如何设计【重启APP】
5,某个事件产生,记录所有UI的状态 【点击创建创建,保存用户选择,下一次进入该面板,直接上一次退出时状态】
5,一个UI操作变化,引起周边UI联动变化 【某个英雄发动技能,身边怪物都掉血或者死亡】
cocos2dx 引擎提供功能
声音引擎
渲染引擎
网络工具库
物理引擎
其他一些小工具库,xml, json等等
我现在抛开声音,网络,小工具等这些不谈,只讲渲染引擎。 因为这才是核心。 当然一个游戏,不仅只有显示。
几个基础: Node,Scene,Layer
我抽象了引擎,总结就几句话
while(!isStop){
发送事件
绘制scene
}
没错,这是核心。咱们写的游戏逻辑,基本上上都是绘制scene里完成的。包括js和lua逻辑的执行(声音,网络请求,下载等除外)
遍历该scene下的所有节点,然后绘制。
游戏引擎本身是UI驱动的, 有的人,非要按照MVC,MVP等非UI交互型的模式,这无疑增加了工作量,也不便于理解。
搞不好一个新招的同事,为了快速完成任务,直接把这个模式给玩砸了。
我不否认,这些模式其实都是比较好的,但用在游戏开发真心不合适。
现在我只谈cocos2dx-lua的开发架构模式.
我把scene当作是一个虚拟机。 实现了一个观察者模式 用来通知其他layer层,或者所有layer层。
有一个限制,禁止layer:addChild( layer ). 虽然引擎支持这种。 所有layer都是兄弟姐妹的关系,不存在父亲儿子。
如果要实现那种点击一个按钮,弹出一个界面的功能, 这个界面不应该做成node或UIPanel节点,因为可能要屏蔽事件的。
虽然两者都支持,为了统一管理和逻辑实现,统一layer。
runScene 相当于启动一个虚拟机。很显而易见,同一时刻,只能运行一个scene,这是引擎的特性。
全局的事件中心用引擎提供的功能。
function onEvent(event)
end
我的软件结构里
views
scenes
LoginScene.lua
MainScene.lua
GameScene.lua
layers
LoginbgLayer.lua
LoginLayer.lua
CommonDialog.lua
nodes
headNode.lua
自己实现一个
Game.Layer(csbFileName). 他继承cc.Layer.create()
Game.Scene(). 他继承 cc.Scene.create() 并实现一个观察者模式的简单模型。
这个模式并非游戏全局,仅仅供layer层直接传递信息。 runScene("xxxScene")是产生。
一切逻辑都写在layer, 此layer是cc.Layer.create()子类。
----
20190406补充:
才发现我想描述的其实的就是ECS架构。 原来早就有了,才发现这个架构。
看来我也不用继续在描述了