问题
Cocos Creator 没有提供场景过渡效果的 API(至少到我写这篇文章的时候还没有)
实现思路
创建一个预制资源(Prefab),作为两个场景之间的中间“场景”(从 Prefab 中实例化出的新节点),当下一个场景预加载完毕后,先过渡到中间“场景”,待中间“场景”动画效果完成之后立即过渡到下一场景。
注:其实中间“场景”有两个,一个渐出,一个渐入,两个拼接在一起就形成了过渡
效果图(669KB)
具体实现
在 Cocos Creator 中创建一个预制资源(下面统称为 fade-mask
)
- 在任意场景中的任意位置创建渲染节点 Sprite(单色)
- 为 Sprite 添加 UI 组件 Widget,并设置上下左右边距为 0(适配不同的分辨率)
- 拖拽 Sprite 到资源管理器中,生成预制资源(之后删除场景中的 Sprite 即可)
创建脚本(fade.js
)
组件属性
properties: {
fadeMask: {
default: null,
type: cc.Prefab,
tooltip: "渐变遮罩"
}
}
编写渐变效果函数
/**
* 渐隐渐显效果执行函数
* @param {cc.Node} fadeMaskNode Prefab 实例化出的新节点(遮罩节点)
* @param {Number} interval
* @param {Function} callback
*/
fade(fadeMaskNode, interval = .3, callback = () => {}) {
// 判断遮罩节点是否为透明, 是则使用渐显动作, 否则为渐隐
let fadeAction = this.isTransparent(fadeMaskNode) ? cc.fadeIn(interval) : cc.fadeOut(interval);
fadeMaskNode.runAction(
cc.sequence(
fadeAction,
cc.callFunc(() => callback())
)
);
}
/**
* 判断遮罩节点是否透明
* @param {cc.Node} fadeMaskNode Prefab 实例化出的新节点(遮罩节点)
* @returns {Boolean}
*/
isTransparent(fadeMaskNode) {
// 0 透明 1-255 不透明
return Boolean(!fadeMaskNode.opacity);
}
其实渐隐渐显的原理就是白色背景从透明变为不透明,从不透明变成透明,这样相当于实现了一个过渡效果,就像 Pr
中的转场效果一样,下面就来编写转场函数
编写转场函数
/**
* 附带效果(渐隐或渐显)转场
* @param {cc.Node} fadeMaskNode Prefab 实例化出的新节点(遮罩节点)
* @param {Number} interval
* @param {String} nextScene
*/
loadScene(fadeMaskNode, interval = .3, nextScene = "") {
if (nextScene) {
cc.director.preloadScene(nextScene, () => {
this.fade(fadeMaskNode, interval, () => {
cc.director.loadScene(nextScene);
});
});
} else {
this.fade(fadeMaskNode, interval);
}
}
这个函数主要做的事情是预先加载了下一场景,等到下一场景预加载完毕之后,调用 fade
函数进入过渡动画,动画结束后执行回调函数(加载下一场景)
编写白色渐显渐隐函数
有了转场函数之后,我们就可以编写渐显渐隐函数函数了,之后我们会在其它脚本中调用这两个函数,达到场景过渡的效果
/**
* 渐隐为白色并转场
* @param {String} nextScene
* @param {Number} interval
*/
fadeIntoWhite(nextScene, interval) {
// 从 Prefab 实例化出新节点并设置节点的 opacity 属性
let fadeMaskNode = cc.instantiate(this.fadeMask);
fadeMaskNode.opacity = 0;
// 将节点添加到当前的场景中并执行转场 ①
this.node.addChild(fadeMaskNode);
this.loadScene(fadeMaskNode, interval, nextScene);
// 不知道 Cocos 怎么用断点调试, 嘛, 就这样吧...(偷懒)
console.log("fadeIntoWhite");
},
/**
* 当前场景从白色渐显
* @param {Number} interval
*/
fadeFromWhite(interval) {
let fadeMaskNode = cc.instantiate(this.fadeMask);
fadeMaskNode.opacity = 255;
this.node.addChild(fadeMaskNode);
this.fade(fadeMaskNode, interval);
console.log("fadeFromWhite");
}
代码 ① 中“将节点添加到当前场景中”指的是将节点添加到当前场景的 Canvas
画布下,作为画布的子节点。参考“在其它脚本文件中使用”
在其它脚本文件中使用
比如主页场景(home.fire
)的 Canvas
节点(就是最顶层的那一个节点)上添加了用户脚本组件 home.js
(处理 home
场景的逻辑脚本)以及 fade.js
(场景过渡效果脚本),在 home.js
中就可以这样写:
// home.js
this.btn.node.on(cc.Node.EventType.TOUCH_END, () => {
// 使用 getComponent 方法获取脚本组件
this.node.getComponent("fade").fadeIntoWhite("nextScene");
});
然后在跳转到的场景中编写:
// nextScene.js
this.node.getComponent("fade").fadeFromWhite();
这样就可以实现从场景 home
跳转到场景 nextScene
的转场过渡效果了
小提示
只需要改变预制遮罩 fade-mask
的颜色就能得到不同颜色的渐隐渐显效果了,或者你也可以试一试使用背景图,会有不一样的效果哦
Comments | NOTHING