QQ玩一玩廣告與音效使用總結

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 [email protected] 
 * @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) {
      cc.audioEngine.play(this.bgmAudio, true, 1);
    }
  },

  //暫停現在正在播放的所有音頻
  pauseAll() {
    cc.audioEngine.pauseAll();
  },
  //恢復播放所有之前暫停的所有音頻
  resumeAll() {
    cc.audioEngine.resumeAll();
  },
  stopAll() {
    cc.audioEngine.stopAll();
  },

  // onLoad() {},
  // start () {},

  // update (dt) {},
});

那麼問題來了,全局如何使用?

我們來自定義一個組件CustomComponent.js,其他的組件如果要使用到音效就繼承此組件。具體實現如下

/**
 * @author Javen 
 * @copyright 2018-10-26 16:13:11 [email protected] 
 * @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 [email protected] 
 * @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 [email protected] 
 * @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玩一玩示例

到這裏就介紹完了,個人能力有限如有錯誤歡迎指正,如有遺漏歡迎補充。如有疑問歡迎留言一起交流討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章