cocosjs 模态窗口及窗口管理器设计
模态窗口及窗口管理器设计
游戏中大多数情况会将画面内容以窗口的形式呈现,也就是常说的弹窗,弹窗的方式和处理有多种需求:,一般如:
- 二级弹窗,甚至多级弹窗
- 窗口弹出时带有动作,如从上往下进入,从左侧往右侧飞入,由小变大
- 事件处理,刚弹出时,动作结束时,被隐藏时,被销毁时
- 缓存,某些窗口内容比较大,创建比较耗时,创建后要缓存起来
- 窗口背景有些要蒙版效果,有些要透明效果
- 拦截触摸事件往下传递
- 触摸屏幕任意位置关闭窗口
如以上所提到的各种需求,看起来比较多比较繁琐,如果每开发一个窗口都需求处理这些需求,简单是件让人心烦意燥的事情。下面就来看看如何比较好的处理这些事情。
我们将这一模块分成四部分来设计,通过组合来使用,提高灵活性:
窗口管理器:WindowManager.js,管理模态窗口
窗口基类:WindowBase.js,窗口基类
蒙版层:Mask.js,拦截触摸事件
窗口Action:WindowAction.js,窗口动作
窗口管理器:内部维护两个列表,用于存储模态窗口,需要注意的是不是窗口,模态窗口由一个Window和一个Mask组合而成,两个是独立的,为什么这么设计,主要是能够灵活组合和单独处理逻辑,如设计成一个整体,那么在使用Action时,如由小变大,会看到窗口后面的灰色蒙版也跟着一起由小变大,显示一个模态窗口时,先addChild一个Mask,再addChild一个Window,这样Mask会拦截触摸事件往下传递,而不会拦截Window的触摸事件,再者WindowAction作用在Window上,不会影响Mask,都是单独的,可以组合起来使用;
WindowManager的对外的接口有:
showWindow:显示窗口
hideWindow:隐藏窗口
hideTopWindow:隐藏顶窗口
hideAllWindow:隐藏所有窗口
removeWindow:移除窗口
removeTopWindow:移除顶窗口
removeAllWindow:移除所有窗口
窗口基类:主要是生命周期函数,由子类实现,由窗口管理器调用
onShowNotify:窗口显示时被调用
onShow:窗口显示动作结束时调用
onHideNotify:窗口隐藏时被调用
onHide:窗口隐藏动作结束时调用
onRemoveNotify:窗口移除时被调用
onRemove:窗口移除动作结束被调用
onCover:窗口被新窗口遮挡时被调用
onResume:窗口恢复显示时被调用
蒙版层:分为透明层和带灰度层,继承自LayerColor,有三个生命周期函数
onShow:窗口显示时被调用,注册触摸事件
onHide:窗口隐藏时被调用,反注册触摸事件
onRemove:窗口移除时被调用,反注册触摸事件
窗口Action:提供多个接口获取对应的action
下面来看下简要的调用流程:
调用WindowManager.showWindow(window, windowShowAction, bShowGreyMask, windowZOrder,, maskTouchedCallBack, root),
window:继承 WindowBase 的对象(必填)
windowShowAction:显示时使用的 action(可不填)
bShowGreyMask:是否显示灰色蒙版(可不填)
windowZOrder:窗口显示层级(可不填)
maskTouchedCallBack:蒙版触摸回调(可不填)
root:window 的父节点(可不填)
从隐藏列表中查找模态窗口
如果有,从隐藏列表中移除,加到显示列表中,显示窗口
如果没有,从显示列表中查找模态窗口
如果有,显示窗口
如果没有,创建蒙版,与窗口组合成模态窗口,加到显示列表中
显示窗口时,
addChild Mask,
addChild Window,
Mask.onShow(),
Window.onShowNotify(),
如果有action,则runAction,动作结束时调用Window.onShow()
隐藏窗口时同显示窗口
移除窗口时同显示窗口
具体的子类重写对应的生命周期函数处理对应的逻辑就行了,无需关注具体的调用时机,同时也可组合多种action,支持触摸屏幕任意位置关闭窗口等等需求。
Github地址:https://github.com/malloyz/windowManager