美文网首页小游戏大魅力
QQ玩一玩广告与音效使用总结

QQ玩一玩广告与音效使用总结

作者: Javen205 | 来源:发表于2018-12-10 09:06 被阅读104次

    QQ玩一玩广告与音效使用总结

    1、经常遇到的问题

    • 观看视频广告时背景音乐没有关闭
    • 视频广告看完背景音乐重叠
    • 游戏回到后台再回到前台时背景音乐重叠

    开发环境

    • CocosCreator V2.0.5
    • 手Q版本 V7.9.0.3820(目前市场中最新版本)
    • qqPlayCore.js buildTime:'Fri Nov 09 2018 13:20:45 GMT+0800 (GMT+08:00)'上出现,此版本的qqPlayCore.js也是最新能正常使用的版本。

    顺便提一下,最新版本的qqPlayCore.js buildTime:'Wed Nov 21 2018 15:26:39 GMT+0800 (GMT+08:00)' 使用时会出现 “Canvas fillStyle 传入不合法数据”的警告弹窗但不影响其他接口的使用。

    解决方案:

    1、qqPlayCore.js 回退到之前最新版本 buildTime:'Fri Nov 09 2018 13:20:45 GMT+0800 (GMT+08:00)’
    2、如果非要使用新版本可以设置不显示错误弹框,默认显示错误弹框。 BK.Script.errorAlertOpen = false

    2、音频使用封装

    游戏启动页(Home场景下)设置GlobalAudio 为常驻节点并挂载音效脚本组件

    全局音效常驻节点

    音效脚本组件 AudioClip.js

    这里播放音效直接使用的是CocosCreator引擎提供的 AudioEngine 组件

    /**
     * @author Javen 
     * @copyright 2018-10-31 16:24:42 javendev@126.com 
     * @description  音效与背景音乐组件
     */
    var Global = require("./Global");
    cc.Class({
      extends: cc.Component,
      properties: {
    
        onClickAudio: {
          default: null,
          tooltip: "按钮点击音效",
          type: cc.AudioClip,
        },
    
        bgmAudio: {
          default: null,
          tooltip: "背景音效",
          type: cc.AudioClip
        },
    
      },
    
      playClickAudio() {
        if (Global.isAudio) {
          cc.audioEngine.play(this.onClickAudio, false, 1);
        }
    
      },
    
      playBgmAudio() {
        if (Global.isAudio && (!this.bgmAudioId || this.getState(this.bgmAudioId) != cc.audioEngine.AudioState.PLAYING)) {
          cc.audioEngine.play(this.bgmAudio, true, 1);
        }
      },
    
      //暂停现在正在播放的所有音频
      pauseAll() {
        cc.audioEngine.pauseAll();
      },
      //恢复播放所有之前暂停的所有音频
      resumeAll() {
        cc.audioEngine.resumeAll();
      },
      stopAll() {
        cc.audioEngine.stopAll();
      },
      getState(id) {
        return cc.audioEngine.getState(id);
      },
      // onLoad() {},
      // start () {},
    
      // update (dt) {},
    });
    

    那么问题来了,全局如何使用?

    我们来自定义一个组件CustomComponent.js,其他的组件如果要使用到音效就继承此组件。具体实现如下

    /**
     * @author Javen 
     * @copyright 2018-10-26 16:13:11 javendev@126.com 
     * @description 自定义组件
     */
    
    cc.Class({
        extends: cc.Component,
        start() {
            try {
                //查询WebSocket节点并获取音效组件WebSocket
                this._webSocket = cc.find("WebSocket").getComponent("WebSocket");
                //查询GlobalAudio节点并获取音效组件AudioClip
                this._audioClip = cc.find("GlobalAudio").getComponent("AudioClip");
            } catch (error) {}
        },
        //下面的方法可要可无,只是为了方便在其他组件中调用,不用写重复的代码。
        playClickAudio: function () {
            if (this._audioClip) {
                this._audioClip.playClickAudio();
            }
        },
        playBgmAudio: function () {
            if (this._audioClip) {
                this._audioClip.playBgmAudio();
            }
        },
    });
    

    使用案例

    /**
     * @author Javen 
     * @copyright 2018-12-07 15:51:19 javendev@126.com 
     * @description QQ玩一玩示例 
     */
    
    let customComponent = require("./common/CustomComponent");
    
    cc.Class({
        extends: customComponent,//继承至自定义的组件 customComponent
    
        properties: {},
        
        btnClick(event, data) {
            this.playClickAudio(); //CustomComponent 父类中的方法
        }
    
        // onLoad () {},
    
        start() {
            this._super();//切忌不要忘记 否者playBgmAudio、playClickAudio 这些父类的方法执行时会提示没有定义
            this.playBgmAudio();//CustomComponent 父类中的方法
        },
    
        // update (dt) {},
    });
    

    3、视频广告以及banner广告封装

    注意看注释,上面提到的前两个问题可以完美的解决

    封装的代码已开源-封装源码地址-使用案例源码地址

    /**
     * 展示广告 Global.videoAd.show();
     * 预加载视频广告
     */
    function loadVideoAd() {
        if (!Global.videoAd && cc.sys.platform == cc.sys.QQ_PLAY) { //如果没有广告资源就加载新的视频广告
            let videoAd = BK.Advertisement.createVideoAd();
            videoAd.onError(function (err) {
                //加载失败
                log("BKTools onError code:" + err.code + " msg:" + err.msg);
                Global.viewAdLoadCount += 1;
                if (Global.viewAdLoadCount < 4) {
                    loadVideoAd();
                }
            });
    
            videoAd.onPlayFinish(function () {
                //播放结束
                log("BKTools onPlayFinish...");
                Global.videoAd = undefined;
            });
            videoAd.onClose(function () {
                //播放结束
                log("BKTools onClose...");
                Global.videoAd = undefined;
            });
    
            videoAd.onLoad(function () {
                //加载成功
                log("BKTools onLoad");
                Global.videoAd = videoAd;
                Global.videoAdLoadCount = 0;
            });
        } else {
            log("BKTools 已存在广告资源 或者 非QQ玩一玩平台....");
        }
    }
    
    /**
     * 展示广告 Global.bannerAd.show();
     * 预加载banner广告
     */
    function loadBannerAd(viewId) {
        if (!viewId) {
            viewId = 1001;
        }
        if (!Global.bannerAd && cc.sys.platform == cc.sys.QQ_PLAY) { //如果没有广告资源就加载新的视频广告
            let bannerAd = BK.Advertisement.createBannerAd({
                viewId: viewId,
            });
            bannerAd.onError(function (err) {
                //加载失败
                log("BKTools onError code:" + err.code + " msg:" + err.msg);
                Global.bannerAdLoadCount += 1;
                if (Global.bannerAdLoadCount < 4) {
                    loadBannerAd(viewId);
                }
            });
            bannerAd.onLoad(function () {
                //加载成功
                log("BKTools onLoad");
                Global.bannerAd = bannerAd;
                Global.viewAdLoadCount = 0;
            });
        } else {
            log("BKTools 已存在banner资源 或者 非QQ玩一玩平台....");
        }
    }
    
    function showBannerAd() {
        if (Global.bannerAd) {
            Global.bannerAd.show();
        } else {
            log("BKTools 不存在banner资源....");
            loadBannerAd();
        }
    }
    
    function hideBannerAd() {
        if (Global.bannerAd) {
            Global.bannerAd.hide();
            Global.bannerAd = undefined;
            loadBannerAd();
        } else {
            log("BKTools 不存在banner资源无法关闭....");
        }
    }
    

    使用案例

    case "adVideo":
        let videoAd = Global.videoAd;
        if (videoAd) {
            videoAd.show();//展示视频广告
            videoAd.onPlayStart(function () {
                BKTools.log("video ad onPlayStart...");
                //QQ玩一玩或者是引擎的bug 播放广告时没有关闭背景音效需要手动处理
                if (Global.isAudio) {
                    //this._audioClip.pauseAll();
                    this._audioClip.stopAll();
                }
            }.bind(this));
            videoAd.onPlayFinish(function () {
                //播放结束
                BKTools.log("video ad onPlayFinish...");
                //业务逻辑处理.....
            }.bind(this));
            videoAd.onClose(function () {
                BKTools.log("video ad  onClose...");
                if (Global.isAudio) {
                    //this._audioClip.resumeAll();
                    this._audioClip.playBgmAudio();//恢复背景音效
                }
            }.bind(this));
        } else {
            BKTools.log("暂无广告资源.....");
            BKTools.loadVideoAd();//加载视频广告
        }
        break;
    case "banner":
        BKTools.showBannerAd(1002);//显示banner广告
        break;
    case "hideBanner":
        BKTools.hideBannerAd();//隐藏banner广告
        break;
    

    好了,到此已解决了前两个问题。游戏回到后台再回到前台时背景音乐重叠的问题如何解决呢? 此时你可能会想到游戏是否有提供游戏生命周期的回调呢?

    翻翻文档不难发现是有提供的 —— 最新版本的生命周期函数文档

    4、QQ玩一玩生命周期函数事件监听

    在CocosCreator中如何实现QQ玩一玩生命周期函数事件监听?最后一个问题的解决方案注意看注释

    这里可以使用常驻节点来实现,具体实现如下

    生命周期函数事件监听常驻节点设置
    /**
     * @author Javen 
     * @copyright 2018-10-22 15:04:24 javendev@126.com 
     * @description QQPlay 事件监听
     */
    
    let BKTools = require("./BKTools");
    let Utils = require("./Utils");
    let Global = require("./Global");
    let CustomComponent = require("./CustomComponent");
    cc.Class({
        extends: CustomComponent,
    
        // properties: {},
    
        // onLoad () {},
    
        start() {
            this._super();
            if (cc.sys.platform == cc.sys.QQ_PLAY) {
                BKTools.log('QQPlayerEvent QQ玩一玩平台');
                this._onQQPlayEvent();
            } else {
                BKTools.log('QQPlayerEvent 非QQ玩一玩平台');
            }
        },
        _enterForegroundListener() {
            BKTools.log('进入前台');
            this._audioClip.playBgmAudio();//重新播放音效
        },
        _enterBackgroundListener() {
            BKTools.log('退出前台');
            //this._audioClip.pauseAll();
            this._audioClip.stopAll();//测试发现有时候背景音效不会重叠,为了彻底解决此问题就停止所有音效。缺点是在恢复播放时需要单独处理播放进度问题 可以通过 getCurrentTime 获取当前的播放时间, 在恢复时setCurrentTime再调用play
        },
        _gameCloseListener() {
    
            //上报操作
            let score = Utils.getRandomInt(0, 100);
            BKTools.log('关闭游戏:' + score);
            BKTools.uploadScore(score, function (errorCode) {
                if (errorCode == 0) {
                    BKTools.log("数据上报成功......");
                } else {
                    BKTools.log("数据上报失败......");
                }
            });
        },
        _maximizeListener() {
            BKTools.log('最大化');
        },
        _minimizeListener() {
            BKTools.log('最小化');
        },
        _onNetworkChangeListener(data) {
            BKTools.log(data);
            if (data.state == BK.NetworkState.NoneToMobileNetwork) {
                BKTools.log('从无网络到移动网络');
            } else if (data.state == BK.NetworkState.NoneToWifi) {
                BKTools.log('无网络到WiFi网络');
            } else if (data.state == BK.NetworkState.MobileNetworkToWifi) {
                BKTools.log('移动网络到WiFi网络');
            } else if (data.state == BK.NetworkState.MobileNetworkToNone) {
                BKTools.log('移动网络到无网络');
            } else if (data.state == BK.NetworkState.WifiToNone) {
                BKTools.log('WiFi到无网络');
            } else if (data.state == BK.NetworkState.WifiToMobileNetwork) {
                BKTools.log('WiFi到移动网络');
            }
        },
        _onShareCompleteListener(data) {
            //shareDest 0为QQ 1为QZone 2为微信 3为朋友圈  isFirstShare永远为true
            BKTools.log("分享完成: retCode:" + data.retCode + ',isFirstShare:' + data.isFirstShare + ',dest:' + data.shareDest);
        },
        _onShareListener() {
            BKTools.log("调用分享接口时回调,分享了...");
            //无法自定义分享
        },
        _onQQPlayEvent() {
            BK.onEnterForeground(this._enterForegroundListener.bind(this));
            BK.onEnterBackground(this._enterBackgroundListener.bind(this));
            BK.onGameClose(this._gameCloseListener.bind(this));
            BK.onMaximize(this._maximizeListener.bind(this));
            BK.onMinimize(this._minimizeListener.bind(this));
            BK.onNetworkChange(this._onNetworkChangeListener.bind(this));
            BK.onGameShareComplete(this._onShareCompleteListener.bind(this));
            BK.onGameShare(this._onShareListener.bind(this));
        },
    
    
        // update (dt) {},
    });
    

    5、 源码

    CocosCreator开发小游戏示例: Brickengine_Guide

    • QQPlay为旧版本QQ玩一玩示例
    • QQPlay_New为新版本QQ玩一玩示例

    到这里就介绍完了,个人能力有限如有错误欢迎指正,如有遗漏欢迎补充。如有疑问欢迎留言一起交流讨论。

    相关文章

      网友评论

        本文标题:QQ玩一玩广告与音效使用总结

        本文链接:https://www.haomeiwen.com/subject/syvhhqtx.html