Cocos Creator 2.0 实现场景过渡效果(各种颜色渐隐渐显)

发布于 2019-05-10  3638 次阅读


问题

Cocos Creator 没有提供场景过渡效果的 API(至少到我写这篇文章的时候还没有)

实现思路

创建一个预制资源(Prefab),作为两个场景之间的中间“场景”(从 Prefab 中实例化出的新节点),当下一个场景预加载完毕后,先过渡到中间“场景”,待中间“场景”动画效果完成之后立即过渡到下一场景。

注:其实中间“场景”有两个,一个渐出,一个渐入,两个拼接在一起就形成了过渡

效果图(669KB)

效果图

具体实现

在 Cocos Creator 中创建一个预制资源(下面统称为 fade-mask

  1. 在任意场景中的任意位置创建渲染节点 Sprite(单色)
  2. 为 Sprite 添加 UI 组件 Widget,并设置上下左右边距为 0(适配不同的分辨率)
  3. 拖拽 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 的颜色就能得到不同颜色的渐隐渐显效果了,或者你也可以试一试使用背景图,会有不一样的效果哦

例子下载

提取码 oic8


千里之行始于足下