自述
弹框框架,本人已经发过一次贴了,地址,但该文仅仅是介绍该框架的用法,而且当时也的确是为CocosStore准备的一篇介绍,所以没有整体考虑。现在因为我已经考虑整体开源一个开发框架,即上文提到的基于CocosCreator的SCL框架开源白皮书,因此我又重新整理了一系列东西,然后针对该文有些人的评论,我来解释一下。
- 的确是个人第一次做开源项目,经验不足,而且需要整理的地方很多,所以我也描述了,时间比较久,而且不会一次性整理出来。
- 我个人希望这套框架,不单单是解决某个问题,也不仅仅是造一个重复的轮子,而是学会分析问题、解决问题以及归纳问题。
- 开源的意义,除了贡献,另一方面也是想提升自己,以及对框架进行充实,毕竟对个人的力量是有限的,错误也在所难免。
- 在上文中,我也提到了,该框架适合休闲类、轻度游戏使用,毕竟性能、功能都没经历过大型项目历练,但普通合成类、模拟经营类,是有线上运行的项目的,而且用户量在百万以上,应该能胜任。
- 文章中从头至尾没有提到需要关注公众号才能获取,git地址也附在文末,所以我希望各位评论者能稍微看下文章。
- 当然能赞助我一下,比如购买用这个框架开发的小游戏翻棋子游戏,或者关注我的公众号,给我涨粉,那我当然高兴。
正文
弹框的产生
一开始我们面对的需求,可能仅仅只是在游戏中,要最上层显示一个对话框,比如胜利啊、道具提示啊等等,这种需要一个简单的做法就是,在场景中拼了UI界面,然后隐藏起来,然后等需要的时候显示出来,不需要的时候隐藏起来。这样做的好处就是:
- 界面与场景相结合,效果一目了解,
- 使用简单,仅需控制显示隐藏即可,
- 加载完毕后,使用时,几乎没有卡顿等。
但弊端也很明显:
- 如果界面较多,加载较慢
- 都在场景中,不利于维护,特别是多人协作
- 逻辑结构不清楚
这个时候,我们借助prefab,将UI制作成prefab,基本就能解决以上问题了,然而,新的问题就是:
- 每次使用需要实例化
- 层级不好控制
弹框的进化
以上经历,可能每个人都会遇到,当遇到的次数多了,可能每个人都会想到需要设计一个弹框的管理类。现在,我们就来设计一个吧。
首先我们需要管理什么?
其实就是弹框的显示和隐藏,所以我们的弹框应该是(本文代码皆为伪代码)
show(){
let node = instantiate(prefab);
node.parent = parent;
}
hide(node){
node.destroy();
}
那么,我们后续的实现,都是基于这两个方法进行的,继续我们要实现的东西。
- 我们并不需要每次都实例化,可以添加缓存
getNode(name){
if(!this.nodes.get(name)) {
let node = createNode();
this.nodes.set(name, node);
}
return this.nodes.get(name);
}
- 显示新弹框的时候,旧弹框要不要隐藏的控制
show(isKeep){
if(!isKeep) {
hideAllPopup();
}
}
- 有时候,我们有个重要弹框,比如账号弹出提醒,显然,这种弹框是不能覆盖的。
首先,你可以设置两个父节点来控制重要弹框,但这显然脱离了我们的统一控制框架,这里我们使用层级的概念,即低层级的弹框,即使后弹出,也不能覆盖之前弹出的弹框。
show(priority){
if(cur > priority) {
addTempList(node);
return;
}
}
- 传递参数
我们获取node上的节点需要使用
node.getComponent(组件名)
如果每次弹框需要重复调用该方法,并不方便,我们需要考虑集成到show中去,可是组件名每次传递也不方便,所以我们定义一个弹框父类PopupBase
,这样,我们获取该父组件即可。
show(params){
node.getComponent(PopupBase).init(params);
}
我们在这两个方法中,加入我们需要的方法,这样一个完整的弹框管理就出来了。可能就是一个能满足大部分需求的弹框管理了。然后,我们再考虑两个优化:
- 加入弹框动画。
在我的方案中,是在show中,加入一个tween,并预置了两个tween:缩放和渐现。
/**
* 默认的缩放动画
*/
const scaleTween: Tween<Node> = tween().to(0.2, { scale: v3(1.1, 1.1, 1) }).to(0.05, { scale: v3(1, 1, 1) });
/**
* 默认的渐现动画
*/
const fadeTween: Tween<UIOpacity> = tween().to(0.25, { opacity: 255 });
- 放置点击穿透。
在我的方案中,弹框前会先显示一个node,并挂载了拦截组件,当动画播放完毕后,在隐藏。
this.blockInputNode.addComponent(BlockInputEvents);
我们解决了哪些痛点
- 弹框的依次显示队列问题
- 弹框的优先级问题
- 一个prefab可以多次实例化的问题
- 弹出过程中,背景穿透的问题
弹框的后续优化
-
如何自定义弹框效果?
-
如果是多场景方案,需要切换场景,销毁当前场景的弹框,什么方案比较合适?
-
资源如何合理销毁?
如果各位有什么好的方案,欢迎在git上提交~
github: https://github.com/dream93/scl
gitee(同步github):https://gitee.com/dream93/scl
因为目前主推3.0 所以我目前主要在整理3.0的版本,2.0版本请使用旧地址的2.x分支,然后参考3.0的部分优化。
github: https://github.com/dream93/ccc_libs
gitee(同步github): https://gitee.com/dream93/ccc_libs
公众号: