CocosCreator跨平台优雅的集成广告SDK

377 阅读4分钟

前言

原来开发游戏可能仅需考虑安卓(GooglePlay)和苹果(AppStore),后来国内各大厂商也开始要求接入自己的sdk,现在又有一堆的小游戏平台,要编写跨平台代码,我们可能需要各种适配。一些跨平台的游戏,可能最常见的代码就是

if(Android原生) {
} else if(ios原生) {
} else if(微信小游戏) {
}
...

这种ifelse多层结构非常影响到代码的可读性,得益于CocosCreator产品的优秀跨平台能力,我们可以减轻很多适配的工作量。但是对于广告SDK这种百花齐放的产品,可能Cocos官方也应顾不暇,那我们程序员该如何跨平台呢?

Flag: 后期我将开源整合各家原生广告的DEMO

flag能不能实现,暂且不说,其实按照下面这种方式集成,后期非常容易聚合各类广告平台。

基本步骤

  1. 参考微信小游戏的api实现我们自己的api
  2. 在cocos里借助.d.ts代码实现代码提示
  3. 在build-templage里面实现各平台的调用

定义api

下面我们以激励视频api为例,实现我们的api

CCC已经支持ES6了,如果没有跨引擎的需求,也可以直接使用ES6语法来写

    var RewardedVideoAd = function () {
        this.load = function () { }
        this.show = function () { }
        this.destroy = function () { }
        this.onLoad = function () { }
        this.offLoad = function (callback) { }
        this.onError = function (callback) { }
        this.offError = function (callback) { }
        this.onClose = function (callback) { }
        this.offClose = function (callback) { }
    }
    var zz = {};
    zz.createRewardedVideoAd = function (object) { }

总得来说,可以理解成我们把wx换成了zz(任何一个你喜欢的变量都行,只要你保证这个字段不冲突,比如cc就不行了)

定义.d.ts文件

这一步并不是必须的,但是对于ts开发而言,有代码提示简直是另一个天地。

class RewardedVideoAd {
    load(): Promise;
    show(): Promise;
    destroy(): void;
    onLoad(): void;
    offLoad(callback: () => void): void;
    onError(callback: (res: { errCode?: number, errMsg: string }) => void): void;
    offError(callback: Function): void;
    onClose(callback: (res: { isEnded: boolean }) => void): void
    offClose(callback: Function): void
}
declare namespace zz {
    export function createRewardedVideoAd(object: { adUnitId: string, multiton?: boolean }): RewardedVideoAd;
}

实现跨平台代码

小游戏平台的代码

我们这里以微信为例接入

因为我们的api就是参考微信官方的,相对编写就比较简单了,等于是复写了一遍api而已~

(function () {
    let zz = {};
    zz.createRewardedVideoAd = function (object) {
        return wx.createRewardedVideoAd(object);
    }
    window.zz = zz;
})();

这里直接替换也是可以的,但是这样写的方便后期我们的扩展,比如新增的api版本判断等。

原生平台的代码

这里我们以安卓平台及穿山甲为例

脚本调用,主要是js与原生调用,比如创建激励视频

jsb.reflection.callStaticMethod('com/xyzzlky/test/BU', 'createRewardedVideoAd', '(Ljava/lang/String;)Z', adUnitId);

以及各种回调接收事件,比如加载结果

    zz.loadRVResult = function (adUnitId, res) {
        if (res) {
            rvAd[adUnitId].loadResolve && rvAd[adUnitId].loadResolve();
        } else {
            rvAd[adUnitId].loadReject && rvAd[adUnitId].loadReject();
        }
    }

集成SDK的代码,穿山甲官方都有文档,这一块涉及游戏的内容不多,我就不再赘述,如有需求,请直接参考我的demo。

将代码引入

避免破坏项目工程,我们不要将这些文件放到工程里,而且如果平台较多,看着也不优雅,借助build-templates的平台定制(也可以自行写脚本实现),我们可以针对平台进行脚本加入。

  1. 微信平台引入

我们在game.js中引入我们的脚本即可

// 这里推荐通过插件写入,达到跨引擎版本的作用
require('zz-ccc.js');
  1. 原生平台的引入在main.js中引入
require('src/zz-ccc.js');

如果不是在src、jsb-adapter、res文件夹下,则你需要在gradle中写好移动语句,参考官方的写法

 copy {
            from "${sourceDir}/res"
            into "${outputDir}/res"
        }

调用

脚本调用

        // 因为每个平台的广告id不一样,推荐这里使用虚拟的广告位id,在各个平台通过后台换取真实adUnitId,当然也可以设置成object,区分各个平台的adUnitId
        this.ad = zz.createRewardedVideoAd({ adUnitId: '代码位' });
        this.ad.load().then(() => {
            console.log('加载成功');
            this.ad.show().then(() => {
                console.log('显示成功');
            }).catch(() => {
                console.log('显示失败');
            });
        }).catch(() => {
            console.log('加载失败');
        });

调试问题

当为调试模式,则可以添加一个调试文件,让该文件仅在调试期间作用

if (CC_PREVIEW) { 
    // ...
    window.zz = zz;
}

可以通过对话框的形式,模拟加载和显示

var r = confirm('广告是否加载成功');

调试效果

如此一来,我们的代码就不必顾忌平台的差异了,如果增加了平台对我们而言可能就是加一个js文件而已,而且请注意这些代码都是跨项目通用的哦。

END

细心的小伙伴可能发现了,这种集成方式,跟我以前介绍的小游戏快速转制APP的方法非常相像,没错,其实就是用的那套原理,只是这里针对的是单一的广告对接。so,如果你将微信的api全部在多平台实现一套,那么恭喜你,你的游戏就可以一键发布到原生平台了。如果你还关注了我的【自动化构建】,那么只要你提交了代码,你就可以构建所有平台的产品了~

本次涉及各个平台代码较多,我这边将需要改动的代码放到了build-templates下面,各位根据需求修改即可。关注公众号,回复[ad]即可获取demo。
wx_gh.jpg