Skip to content

接入文档

一、接入流程

1、SDK介绍

建议使用模板工程方式接入 动能广告SDK提供广告、付费等能力给客户端集成。

DANGER

重要提示:Wb.zip 代码基于 Creator 2.4.5 版本开发,高版本 Creator 可能出现兼容性问题,需要修改代码以适配。

Creator2.x版本模板工程: https://gui.vigame.cn/CP/Creator/CreatorDemoAndroid/CreatorDemoAndroid.zip

Creator3.x版本模板工程: https://gui.vigame.cn/CP/Creator/CreatorDemoAndroid/CreatorDemoAndroid-3.8.0.zip

Creator插件下载:https://gui.vigame.cn/CP/Creator/WbPlugin/Wb.zip

Demo包下载:https://gui.vigame.cn/CP/Creator/CreatorDemo/CreatorDemo.apk

2、SDK接入流程

2.1 准备

模板工程、Wb插件、引擎导出的assets等资源、App Icon。

2.2 接入流程

2.2.1 在项目中assets下添加Wb插件

将文档附件中的Wb插件下载并解压至项目的assets目录下

javascript
//Wb插件导入代码示例
//以Scripts目录下的test.ts为例
import Wb from "../Wb/Define";

//打开广告
Wb.Ad.openAd("banner", null);

2.2.2 替换assets资源

将Cocos Creator引擎导出的资源替换至模板工程内(将模版工程中对应文件删除),如下图:

引擎导出的资源目录:

模板工程资源存放目录:

2.2.3 替换libs下.so库

根据项目本身需要的abi支持导出对应的.so文件并替换至模板工程libs目录下:

2.2.4 修改游戏icon和名称

二、常用接口

基础(必接)

获取应用属性

javascript
//获取应用属性
let android = Wb.Core.getAndroidId();
let pname = Wb.Core.getPackageName();
let prjid = Wb.Core.getPrjid();
let imsi = Wb.Core.getImsi();
let imei = Wb.Core.getImei();
let lsn = Wb.Core.getLsn();
let appid = Wb.Core.getAppid();
let channel = Wb.Core.getChannel();
let vername = Wb.Core.getVerName();

隐私政策和用户协议(必接)

游戏内的隐私政策和用户协议响应,需替换为sdk的接口。如果游戏内没有相关按钮,可跳过该步骤

javascript
// 隐私政策
openPrivacyPolicy(): void;
// 用户协议
openUserAgreement(): void;

// 调用示例
Wb.Core.openPrivacyPolicy();
Wb.Core.openUserAgreement();

广告(必接)

本地广告配置

可以拷贝模板工程 ADPositions.xml 中的配置添加游戏使用的广告位(广告位不可是中文等特殊字符),添加到游戏工程资源目录测试。

xml
<?xml version="1.0" encoding="utf-8"?>
<appid>10001</appid><!------- 限定调试包使用,请勿修改参数 ----->
<channel>baibao</channel><!------- 限定调试包使用,请勿修改参数 ----->
<adlist>
    <ad>
        <type>splash</type> 
        <positions>splash,game_awaken</positions>
    </ad>
    <ad>
        <type>banner</type> 
        <positions>banner</positions>
    </ad>
    <ad>
        <type>plaque</type> <!------- 插屏 ----->
        <positions>pause,exit_game</positions>
    </ad>
    <ad>
        <type>video</type> <!------- 视频 ----->
        <positions>home_mfzs,level_win_mfzs</positions>
    </ad>
    <ad>
        <type>msg</type> 
        <positions>game_msg,yuans,load_msg,tx_msg</positions>
    </ad>
    <ad>
        <type>icon</type>
        <positions>mini_video,chouj</positions>
    </ad>
</adlist>

2.1 打开普通广告(插屏/视频/横幅/开屏)

javascript
/// <param name="adName">广告位</param>
/// <param name="callback">回调</param>
openAd(adName: string, callback: Function = null): void;

示例:

javascript
//打开banner广告
Wb.Ad.openAd("banner", null);

//打开插屏
Wb.Ad.openAd("inter", function (result: boolean, adParam: Map<string, string>) {
    //打开广告回调
    if(result){
        //打开插屏广告成功
    }
});

//打开视频
Wb.Ad.openAd("video", function (result: boolean, adParam: Map<string, string>) {
    //打开广告回调
    if(result){
        //播放成功且有效 可处理发奖逻辑等等
    } 
});

2.2 打开原生广告

javascript
/// <param name="adName">广告位</param>
/// <param name="width">显示区域宽</param>
/// <param name="height">显示区域高</param>
/// <param name="x">以屏幕的左上角为原点的x</param>
/// <param name="y">以屏幕的左上角为原点的y</param>
/// <param name="callback">回调</param>
openYsAd(adName: string, width: number, height: number, x: number, y: number, callback: Function): void;

示例:

javascript
//坐标系转换部分可供参考或忽略
let size = this.testbtn.node.getContentSize();//panel的坐标转为屏幕坐标
let width = size.width;
let height = size.height;
//屏幕分辨率
let canvasSize = cc.view.getCanvasSize();
//scene的设计分辨率
let desiginSize = cc.view.getDesignResolutionSize();
//Fit width适配方案,以width作为缩放基准
let sW = (canvasSize.width / desiginSize.width);
//计算panel在屏幕中的尺寸
width = sW * width;
height = sW * height;
//转为世界坐标    
let worldPos =  Wb.Pos.localConvertWorldPointAR(this.testbtn.node);
let outPos = cc.v2();
//设置scene的camera
this.camera.getWorldToScreenPoint(worldPos, outPos);
//x,y即屏幕坐标,creator的坐标原点在坐下,Android的在左上,需要做个转换。x轴不变,y轴画布高减去y对应比例的值即为屏幕y坐标。(宽高都以sW为比例计算)
let x = (outPos.x * sW) - (width / 2);
let y = canvasSize.height - (outPos.y * sW) - (height / 2);

Wb.Ad.openYsAd(this.posName, width, height, x, y, function (result: boolean) {
    //打开回调
});

2.3 查看广告是否就绪

javascript
/// <summary>
/// 广告是否准备好
/// </summary>
/// <param name="adName">广告位</param>
isAdReady(adName: string): boolean;

2.4 关闭广告

javascript
/// <summary>
/// 关闭广告
/// </summary>
/// <param name="adName">广告位</param>
closeAd(adName: string): void;

2.5 获取视频限制次数

javascript
// 获取视频限制次数
getVideoLimitOpenNum(): number;

2.6 某关卡是否出现广告

javascript
/// <summary>
/// 关卡是否可以打开该广告
/// </summary>
/// <param name="adName">广告位</param>
/// <param name="level">关卡</param>
isAdBeOpenInLevel(adName: string, level: number): boolean;

统计(必接)

3.1 自定义统计

javascript
/// <summary>
/// 单独事件上报
/// </summary>
/// <param name="eventId">事件id,可根据统计文档填写</param>
tJCustomEvent(eventId: string): void;

/// <summary>
/// 携带标签上报
/// </summary>
/// <param name="eventId">事件id,可根据统计文档填写</param>
/// <param name="label">label内容</param>
tJCustomEventLabel(eventId: string, label: string): void;

/// <summary>
/// 多属性上报
/// </summary>
/// <param name="eventId">事件id,可根据统计文档填写</param>
/// <param name="attributes">attributes</param>
tJCustomEventHashMap(eventId: string, attributes: string): void;

app_loading_show和app_home_show需要必接,以便于分析启动漏斗转化

事件名称事件ID触发时机附加参数
游戏loading页面app_loading_show游戏引擎初始化后就触发上报
游戏内首页app_home_show主页展示时

3.2 关卡统计(必接)

javascript
/// <summary>
/// 关卡开始
/// </summary>
/// <param name="level">关卡id</param>
startLevel(level: string): void;

/// <summary>
/// 关卡胜利
/// </summary>
/// <param name="level">关卡id</param>
finishLevel(level: string, score: string): void;

/// <summary>
/// 关卡失败
/// </summary>
/// <param name="level">关卡id</param>
failLevel(level: string, score: string): void;

3.3 示例代码

javascript
import Wb from "./Wb/Define"

export default class SampleTj{

    //进入游戏loading页面
    public static LoadingShow()
    {
        Wb.Tj.tJCustomEvent("app_loading_show");        
    }

    //进入游戏主界面
    public static HomeShow()
    {
        Wb.Tj.tJCustomEvent("app_home_show");        
    }

    //广告位曝光
    /// <param name="ad_pos">广告位名称</param>
    public static VideoReady(ad_pos:any){
        var ps =
        {
            "ad_pos": ad_pos,
        };
        Wb.Tj.tJCustomEventHashMap("ad_video_ready", JSON.stringify(ps));
    }

    //进入关卡统计
    /// <param name="level">当前关卡ID</param>
    /// <param name="type">进入关卡的方式</param>   play,video(直接进入,看视频进入)
    /// <param name="RainbowJolt">是否使用彩虹</param>
    /// <param name="ThunderJolt">是否使用闪电</param>
    public static LevelStarted(level:number, type:any, RainbowJolt:boolean, ThunderJolt:boolean)
    {
        var ps =
        {
            "level": level,
            "type": type,
            "RainbowJolt": RainbowJolt?"1":"0",
            "ThunderJolt":ThunderJolt?"1":"0"
        };
        Wb.Tj.tJCustomEventHashMap("self_levelstarted", JSON.stringify(ps));
    }

    //结束关卡统计
    /// <param name="level">当前关卡ID</param>
    /// <param name="pass">是否通关</param>
    /// <param name="score">结束时的分数</param>
    /// <param name="star">结束时的星星数</param>
    /// <param name="bubble">剩余泡泡数</param>
    public static LevelCompleted(level:number, pass:boolean, score:number, star:number,bubble:number)
    {
        var ps =
        {
            "level": level,
            "pass": pass?"1":"0",
            "score": score,
            "star":star,
            "bubble":bubble
        };
        Wb.Tj.tJCustomEventHashMap("self_levelcompleted", JSON.stringify(ps));
    }

    //签到统计
    /// <param name="day">当前签到天数</param>
    /// <param name="type">签到方式</param>   collect,doublecollect(单倍领取,双倍领取)
    public static Sign(day:number, type:any)
    {
        var ps =
        {
            "day": day,
            "type": type
        };
        Wb.Tj.tJCustomEventHashMap("self_sign", JSON.stringify(ps));
    }

    //卡片收集统计
    /// <param name="name">卡片名字</param>   Tools,IceCream,Flowers.......
    /// <param name="number">数量</param>
    public static Card(name:any, number:number)
    {
        var ps =
        {
            "name": name,
            "number": number
        };
        Wb.Tj.tJCustomEventHashMap("self_card", JSON.stringify(ps));
    }

    //购买成功--新手特惠包
    public static Beginner(){
        Wb.Tj.tJCustomEvent("self_Beginner");  
    }

    //购买成功--初级射手包
    public static Shooter(){
        Wb.Tj.tJCustomEvent("self_Shooter");  
    }

    //购买成功--超级冲关包
    public static Super(){
        Wb.Tj.tJCustomEvent("self_Super");  
    }

    //购买成功--高手超值包
    public static Mega(){
        Wb.Tj.tJCustomEvent("self_Mega");  
    }

    //购买成功--巨星划算包
    public static Giant(){
        Wb.Tj.tJCustomEvent("self_Giant");  
    }

    //购买成功--传奇王者包
    public static Legend(){
        Wb.Tj.tJCustomEvent("self_Legend");  
    }    

    //购买成功--金币20
    public static coin20(){
        Wb.Tj.tJCustomEvent("self_coin20");  
    } 

    //购买成功--金币50
    public static coin50(){
        Wb.Tj.tJCustomEvent("self_coin50");  
    }    

    //购买成功--金币100
    public static coin100(){
        Wb.Tj.tJCustomEvent("self_coin100");  
    }   

    //购买成功--金币240
    public static coin240(){
        Wb.Tj.tJCustomEvent("self_coin240");  
    }       

    //购买成功--金币500
    public static coin500(){
        Wb.Tj.tJCustomEvent("self_coin500");  
    }  

    //购买成功--金币1100
    public static coin1100(){
        Wb.Tj.tJCustomEvent("self_coin1100");  
    }  

    //关卡统计
    //进入关卡
    /// <param name="level">关卡ID</param>
    public static StartLevel(level:number){
        Wb.Tj.startLevel(level.toString());   
    }

    //关卡成功
    /// <param name="level">关卡ID</param>
    /// <param name="score">分数</param>
    public static FinishLevel(level:number,score:number){
        Wb.Tj.finishLevel(level.toString(),score.toString());   
    }

    //关卡失败
    /// <param name="level">关卡ID</param>
    /// <param name="score">分数</param>
    public static FailLevel(level:number,score:number){
        Wb.Tj.failLevel(level.toString(),score.toString());   
    }

}

支付(有支付必接)

支付流程参考:支付流程

1.1 支付参数说明

参数名类型说明
idstring商品ID
pricestring商品价格(单位:分)
payCodestring商品编码
payDescstring商品描述

4.1 发起支付(必接)

javascript
/**
 * 内购统计支付
 * @param isUse 是否使用计费点配置,false不使用、true使用
 * @param info 支付参数
 * @param func 回调
 */
orderPay6(isUse: boolean, info: Object, func: Function): void

4.1.1 不使用计费点配置支付示例

javascript
//支付参数 (后方未注释必填的可不填)
let obj = {
    "id":"test1", //必填 若无定义可直接填giftId
    "price":"100", // 必填 单位:分
    "payCode":"testcode",  // 必填
    "payDesc":"珍贵宝箱", // 必填
    "giftId":"giftId", // 必填 若无定义可直接填id 字段
    "custom":"custom", // 自定义类型参数(可根据需要传递)
    "giftType":"giftType", // 选填
    "giftNum":"1", // 选填
    "levelId":"levelId", // 选填
    "tokenType":"1", // 选填
    "extParams": { // // 选填 此参数统计事件中会携带
        "value1":"1",
        "value2":"2" 
    }
};
 Wb.Pay.orderPay6(false, obj, (ret, payId, userData, orderId)=>
    {
        console.log("支付(不用计费配置) ret = " + ret);
        if (ret == 1) {
            Wb.T.show("支付成功");
            console.log("PayManager 内购统计支付(不用计费配置) 成功 payId = " + payId + ", userData = " + userData + ", orderId = " + orderId);
            var rand = 1 + Math.round(Math.random() * 99);
            console.log("PayManager 内购统计支付(不用计费配置) pay_token_change 购买前代币数量 before_token = " + rand);
            console.log("PayManager 内购统计支付(不用计费配置) pay_token_change 购买后代币数量 before_token = " + (rand + 1000));
            var obj = {
                "appid":Wb.Core.getAppid(),
                "pid": Wb.Core.getPrjid(),
                "level_id": "1",
                "token_type": "1",
                "before_token": "" + rand,
                "after_token": "" + (rand + 1000),
                "add_reduce": "1000",
                "reason": "1001"
            };
            Wb.Tj.tJCustomEventHashMap("pay_token_change", JSON.stringify(obj));
            console.log("PayManager 内购统计支付(不用计费配置) pay_on_account 上报 orderId = " + orderId);
            Wb.Tj.tJPayOnAccount(orderId);
        } else if (ret == 0){
            Wb.T.show("支付失败");
        } else if (ret == 2){
            Wb.T.show("支付取消");
        } else {
            Wb.T.show("网络错误,需做补单处理");
        }
    });

4.1.2 使用计费点配置支付示例

javascript
//支付参数
//price、payCode、payDesc字段在使用计费点配置时可不传
let obj = {
    "id":"1001",
    "giftId":"giftId",
    "giftType":"giftType",
    "giftNum":"1",
    "levelId":"levelId",
    "tokenType":"1",
    "userdata":"userdata",
    "custom":"custom",
    "extParams": {
        "value1":"自定义参数1",//自定义参数
        "value2":"自定义参数2" //自定义参数
    }
好l};

Wb.Pay.orderPay6(true, obj, (ret, payId, userData, orderId)=>{
        console.log("支付ret = " + ret);
        if (ret == 1) {
            Wb.T.show("支付成功");
            console.log("PayManager 内购统计支付(用计费配置)成功 payId = " + payId + ", userData = " + userData + ", orderId = " + orderId);
            var rand = 1 + Math.round(Math.random() * 99);
            console.log("PayManager 内购统计支付(用计费配置) pay_token_change 购买前代币数量 before_token = " + rand);
            console.log("PayManager 内购统计支付(用计费配置) pay_token_change 购买后代币数量 before_token = " + (rand + 1000));
            var obj = {
                "appid":Wb.Core.getAppid(),
                "pid": Wb.Core.getPrjid(),
                "level_id": "1",
                "token_type": "1",
                "before_token": "" + rand,
                "after_token": "" + (rand + 1000),
                "add_reduce": "1000",
                "reason": "1001"
            };
            Wb.Tj.tJCustomEventHashMap("pay_token_change", JSON.stringify(obj));
            console.log("PayManager 内购统计支付(用计费配置) pay_on_account 上报 orderId = " + orderId);
            Wb.Tj.tJPayOnAccount(orderId);
        } else if (ret == 0) {
            Wb.T.show("支付失败");
        } else if (ret == 2){
            Wb.T.show("支付取消");
        } else {
            Wb.T.show("网络错误,需做补单处理");
        }
    });

4.2 支付成功后上报事件(必接)

服务器发奖不用接入,需接入后端消单接口。

javascript
/**
* 内购统计充值到账上报
* @param tradeId 订单id
*/
tJPayOnAccount(tradeId: string): void;

4.3 设置补单回调(必接)

javascript
// 设置补单监听回调
setInventoryCallBack(func: Function): void;

//示例
Wb.Pay.setInventoryCallBack((isSuc, payId, userData, orderId)=>{
    if (isSuc) {
        console.log("补单成功 payId = " + payId + ", userData = " + userData + ", orderId = " + orderId);
        var rand = 1 + Math.round(Math.random() * 99);
        console.log("pay_token_change 购买前代币数量 before_token = " + rand);
        console.log("pay_token_change 购买后代币数量 before_token = " + (rand + 1000));
        var obj = {
            "appid":Wb.Core.getAppid(),
            "pid": Wb.Core.getPrjid(),
            "level_id": "1",
            "token_type": "1",
            "before_token": "" + rand,
            "after_token": "" + (rand + 1000),
            "add_reduce": "1000",
            "reason": "1001"
        };
        Wb.Tj.tJCustomEventHashMap("pay_token_change", JSON.stringify(obj));
        console.log("PayManager setInventoryCallBack pay_on_account 上报 orderId = " + orderId);
        Wb.Tj.tJPayOnAccount(orderId);
    } else {
        console.log("PayManager setInventoryCallBack 补单失败 payId = " + payId + ", userData = " + userData + ", orderId = " + orderId);
    }
});

商店联运

本部分不再需要游戏接入

调用退出(必接)

注意!!调用SDK中的设置监听退出键回调即可,不要调用Cocos引擎本身提供的监听方案

javascript
// 设置监听退出键回调
setKeyBackLisitener(fun: Function): void;
// 该市场是否支持退出
isSupportExit(): boolean;
// 退出接口
openExitGame(): void;

//示例
Wb.Core.setKeyBackLisitener(()=>{
    if (Wb.Pay.isSupportExit())
    {
        Wb.Pay.openExitGame();
        return;
    } else {
        //无退出界面,由游戏方自己实现
    }
})

反馈邮箱(推荐)

在设置界面显示邮箱信息,获取到数据就显示,没有就不显示。可以在ConfigVigame.xml中配置客服邮箱信息。

接口

javascript
// 根据key获取ConfigVigame.xml中value
getConfigVigameValue(key: string): string;

配置示例

C#
<Email>123321@gmail.com</Email>

示例

javascript
//get email config from ConfigVigame.xml
let ret = Wb.Core.getConfigVigameValue("Email");
if (ret.length == 0)
{
   //not have the Email config
}
else
{
    // have the Email config show the config on Setting.

}

更多精彩(必接)

先判断是否显示更多精彩按钮结果返回true才显示

是否显示更多精彩按钮

javascript
/// <summary>
/// 否显示更多精彩按钮
/// </summary>
isMoreGameBtn(): boolean

打开更多精彩

javascript
/// <summary>
/// 打开更多精彩
/// </summary>
openMoreGame()

示例

javascript
//否显示更多精彩按钮
Wb.Pay.Instance.isMoreGameBtn();
//打开更多精彩
Wb.Pay.Instance.openMoreGame();

按钮资源

增值功能(选接)

客服中心

javascript
/// <summary>
/// 打开客服中心
/// </summary>
/// <param name="title">标题</param>
/// <param name="loginId">用户id</param>  
openClientCenter(title: string, loginId: string);

获取游戏在线配置

javascript
/// <summary>
/// 获取游戏在线配置
/// </summary>
/// <param name="version">配置版本,写1即可</param>
initGameConfig(version: number);

/// <summary>
/// 游戏在线配置回调
/// </summary>
/// <param name="fun">回调</param>
SetOnNewConfigFectched(fun: Function);

/// <summary>
///  根据key获取参数
/// </summary>
/// <param name="key">关键字</param>
getConfigValue(key: string);

示例

javascript
//先设置回调再调用获取接口
Wb.Core.SetOnNewConfigFectched(function (result: boolean) {
    if (result) {
        console.log("获取成功");
        let ret = Wb.Core.getConfigValue("cp");
        console.log('ret:' + ret);
    } else {
        console.log("获取失败");
    }
});
//获取游戏在线参数
Wb.Core.initGameConfig(1);

第三方登录

javascript
// 登录类型枚举参考
enum LoginType
{
    TYPE_NULL = 0,
    TYPE_WX = 1, // 微信
    TYPE_DY = 1, // 抖音
    TYPE_QQ = 2, // QQ
    TYPE_FACEBOOK = 3, // FaceBook
    TYPE_MSDK = 4, 
    TYPE_AliGame = 5,
    TYPE_Downjoy = 6,
    TYPE_Vivo = 7, // VIVO
    TYPE_AliPay = 8,
    TYPE_Common = 9,
    TYPE_Huawei  = 10, // 华为
    TYPE_Xiaomi  = 11, // 小米
    TYPE_Oppo = 12, // oppo
    CopyRight = 13 // 版号包登录
}

/**
* 获取渠道包登录类型
* vivo 7,huawei 10,xiaomi 11,oppo 12,模拟登录 9,微信登录 1
*/
getLoginType(): number

/// <summary>
///  第三方登录并获取用户信息
/// <param name="type">类型</param>
/// <param name="fun">回调</param>
/// </summary>
/// <param name="version">配置版本</param>
getUserInfo(type: number, fun: Function): void

示例

javascript
var loginType = Wb.Social.getLoginType();
Wb.Social.getUserInfo(loginType, (result, info)=>{
//回调
  var deStr = Utils.Instance.base64_decode(info)
  console.log("SocialManager SetUserInfoCallBack base64 解密 = " + deStr);
  var isSuccess = false;
  if (result == "0") {
     isSuccess = true;
  }
  // 解析成功后的逻辑处理
})

服务器响应示例

javascript
{
  "reason": "登陆成功",
  "openid": "86eb5d1f-ebf2-48a0-9e90-b7aab5210423",
  "nickname": "模拟登陆",
  "retCode": "1",
  "token": "83bf4c31-b37b-4789-aa1d-40bd1b58d04f==",
  "headimgUrl": "https://i.imgs.ovh/2023/09/27/PjNJW.jpeg",
  "playerid": "f7590e24-df9d-438a-881d-c918b99e15f5="
}

兑换码

1 兑换码开关

自定义配置参数 key:dhm

通过游戏在线参数配置 initGameConfig 获取兑换码开关!!!

2. 使用兑换码

javascript
/// <summary>
/// 使用兑换码
/// </summary>
/// <param name="dhm">兑换码id</param>
/// <param name="callFun">回调</param>
useCDKey(dhm: string, fun: Function)

兑换码状态

javascript
* 200 兑换成功
* 401 param is error 参数验证不通过
* 402 无效操作
* 403 兑换码无效
* 404 网络错误
* 405 兑换失败,当前兑换码已经被使用过了
* 406 当前兑换码已经失效
* 407 同一个兑换码只能使用一次
* 408 无法识别该兑换码
* 505 系统繁忙

示例

javascript
* @param status 使用状态
* @param price 价格分
* @param msg 提示文字
Wb.Core.useCDKey("test", (status, price, msg) => {
    console.log("useCDKey status = " + status + " price = " + price + " msg = " + msg);
});