修改历史
时间 | 版本 |
2024/2/26 | 1.0.0 |
2024/3/22 | 1.0.1 |
2024/7/12 | 1.0.2 |
2024/10/23 | 1.0.3 |
接入流程(基于Laya 2.x)
1.将我们提供的2个SDK配置文件放入项目的bin目录下,两个文件分别为 minigame-config.json, minigame.json 。
2.在index.html载入minigame.js文件。
<script src="https://sdk.minigame.vip/js/1.1/minigame.js"></script>
3.在Main.ts里面初始化并启动minigame sdk,由于初始化是异步的,所以必须等初始化成功后,再启动sdk。
onConfigLoaded(): void {
// @ts-ignore
if (typeof minigame !== 'undefined') {
let that = this;
//初始化 minigame sdk
// @ts-ignore
minigame.initializeAsync()
.then(function () {
console.log("FB initializeAsync");
that.onLoadRes();
});
}
// 资源加载
private onLoadRes() {
...
// 资源加载完毕后再启动SDK
this.startMiniGameSDK();
}
// 启动minigame sdk
private startMiniGameSDK() {
// @ts-ignore
if (typeof minigame !== 'undefined') {
//@ts-ignore
minigame.setLoadingProgress(100);
//@ts-ignore
minigame.startGameAsync()
.then(function () {
//加载IDE指定的场景,这里假定第一个场景名称是startScene
GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
})
.catch(function (e) {
console.info("startGameAsync error: " + e);
});
}
}
sdk启动后就可以调用广告相关的接口了。接入成功后,调用广告相关接口,laya编译后,就可以直接运行看效果。
注意:必须确保广告接口的调用必须在startGameAsync返回成功后。
当游戏结束加载,进入主场景后,在主场景初始化的时候调用
setGameReadyAsync
minigame.setGameReadyAsync();
接口
广告相关接口
广告功能推荐使用微游SDK提供的广告接口(MiniGameAds)进行接入,对于熟悉FBIG接口的游戏开发者,也可以直接使用FBIG兼容的广告接口进行接入,推荐使用MiniGameAds。
showInterstitial(): Promise<void>
作用:展示插屏广告
示例:
// @ts-ignore
MiniGameAds.showInterstitial().then(()=>{
console.info("====> show interstitial success");
}).catch(e => {
console.error("====> show interstitial error: " + e.message);
});
注意:由于插屏广告默认第一次播放需要30秒后,才能播放,后面播放每次时间间隔40秒,如果cp测试的时候觉得时间太长,可以把minigame.json里fb_ad_delay_for_first_interstitial和fb_interstitial_refresh_interval字段改小。
showRewardedVideo(): Promise<void>
作用:展示激励广告
示例:
// @ts-ignore
MiniGameAds.showRewardedVideo().then(()=>{
console.info("====> show RewardedVideo success");
}).catch(e => {
console.error("====> show RewardedVideo error: " + e.message);
});
isAdRadical(): boolean
作用:激进版广告开关
返回:true为激进版激励广告,需要展示激进版UI,false为普通版激励广告,需要展示普通版UI。
激进版:包含误点击、诱导点击的广告策略,类型比如:
默认勾选:默认勾选看激励视频双倍,且勾选项字眼过小。
延迟提示:不看激励广告的字眼,让用户以为只有一个选项。
普通版:没有激进版的误点击和诱导点击的广告策略。
注意:倘若游戏中存在激进型激励广告,需要做两套处理:一套按照原本的激进版处理,还需做一套普通版的,
通过在minigame.json中添加字段"isAdRadical“字段可以控制isAdRadical()的返回值,
”isAdRadical“:true则isAdRadical() === true,”isAdRadical“:false则isAdRadical() === false
示例:
const isAdRadical = MiniGameAds.isAdRadical();
// 根据isAdRadical来决定是显示激进版UI还是普通版UI
minigame.json具体配置如下:
{
"platform": "minigame",
"sdk": "https://sdk0.minigame.vip/js/1.0/minigame-debug-sdk.js",
"instance": "FBInstant",
"gameName": "minigame",
"features": {
"ads": {
"enabled": false, // 广告开关
"isBannerEnabled": true, // banner开关
"isTest": true, // 是否是广告本地测试环境
"isAdRadical": true, // 是否为激进版激励广告
"config": {
"interstitial": "4864743603539728_5070034729677280",
"banner": "4864743603539728_5082905605056859",
"rewarded_video": "4864743603539728_5070034119677341",
"rewarded_interstitial": "4864743603539728_5070034119677341"
},
"options": {
"fb_max_ad_instance": 3,
"fb_init_ad_count": 3,
"fb_banner_refresh_interval": 40,
"fb_interstitial_refresh_interval": 40,
"fb_rewarded_video_refresh_interval": 0,
"fb_max_banner_error": 1,
"fb_max_interstitial_error": 3,
"fb_max_rewarded_video_error": 3,
"fb_auto_load_on_play": true,
"fb_auto_reload_delay": 1,
"fb_ad_delay_for_first_banner": 0,
"fb_ad_delay_for_first_interstitial": 30,
"fb_ad_delay_for_first_rewarded_video": 0
}
},
"leaderboard": {
"enabled": true
},
"ga": {
"enabled": true,
"isDefault": true,
"config": {
"gid": "UA-226110216-21"
}
}
}
}
showBanner(): Promise<void>
作用:展示横幅广告
示例:
// @ts-ignore
MiniGameAds.showBanner().then(()=>{
console.info("====> show banner success");
}).catch(e => {
console.error("====> show banner error: " + e.message);
});
hideBanner(): Promise<void>
参数:无
示例:
// @ts-ignore
MiniGameAds.hideBanner().then(()=>{
console.info("====> hide banner success");
}).catch(e => {
console.error("====> hide banner error: " + e.message);
});
游戏统计(有需要才接入)
onGameEvent
/**
* @param eventName 事件名称
* @param label 事件标签
*/
public onGameEvent (eventName: string, label: string): void
调用实例:
// 账号登录
// @ts-ignore
MiniGameAnalytics.onGameEvent("login", "自定义标签");
内购支付(有需要才接入)
内购接口
onReady(callBack: Function): void
设置一个回调,callback在支付可用时,会被触发,onReady一般在进入游戏后调用,callback里面可以先处理下补单的操作。
Examples:
minigame.payments.onReady(function () {
// 先获取未消耗的订单
minigame.payments.getPurchasesAsync().then(function(purchases) {
console.log(purchases);
// 遍历订单
purchases.forEach((purchase) => {
// 消耗订单
minigame.payments.consumePurchaseAsync(purchase.purchaseToken)
.then(function () {
// 消耗成功
// 游戏发送奖励给玩家
});
})
});
});
getCatalogAsync(): Promise<Product[]>
获取游戏的产品目录
Examples:
minigame.payments.getCatalogAsync().then(function (catalog) {
console.log(catalog); // [{productID: '12345', ...}, ...]
});
purchaseAsync(purchaseConfig: PurchaseConfig): Promise<Purchase>
开始特定产品的购买流程, productID在接入的时候,我们会进行提供。
Examples:
minigame.payments.purchaseAsync(
{ productID: '12345',
developerPayload: 'foobar'
}).then(function (purchase) {
console.log(purchase);// {productID: '12345', purchaseToken: '54321', developerPayload: 'foobar', ...}
});
getPurchasesAsync(): Promise<Purchase[]>
获取玩家未消费的所有购买商品
Examples:
minigame.payments.getPurchasesAsync().then(function (purchases) {
console.log(purchase);
// [{productID: '12345', ...}, ...]
});
consumePurchaseAsync(purchaseToken: string): Promise<void>
消费当前玩家拥有的特定购买商品
Examples:
minigame.payments.consumePurchaseAsync('54321').then(function () {
// 消耗成功
// 游戏发送奖励给玩家
});
注意purchaseAsync支付成功后,需要马上调用消耗接口才能发放奖励,例如:
minigame.payments.purchaseAsync({
productID: '12345',
developerPayload: 'foobar',
}).then(function (purchase) {
minigame.payments.consumePurchaseAsync(purchase.purchaseToken)
.then(function () {
// 消耗成功
// 游戏发送奖励给玩家
});
});
2.类型定义
支付参数:
export interface PurchaseConfig {
/**
* 产品id
*/
productID: string;
/**
* 可选参数,开发人员指定的内容,将包含在返回的购买签名请求里。
*/
developerPayload?: string;
}
商品信息:
export interface Product {
/**
* 产品的名称
*/
title: string;
/**
* 产品的游戏指定id
*/
productID: string;
/**
* 产品的描述
*/
description?: string;
/**
* 产品相关图片的链接
*/
imageURI?: string;
/**
* 产品的价格
*/
price: string;
/**
* 产品的货币代码,字符串类型
*/
priceCurrencyCode: string;
/**
* 产品的价格,数字类型
*/
priceAmount: number;
}
支付返回:
export interface Purchase {
/**
* 可选参数,开发人员指定的内容,将包含在返回的购买签名请求里。
*/
developerPayload?: string;
/**
* 购买的当前状态,如“收费”或“退款”
*/
paymentActionType: string;
/**
* 购买交易的标识符
*/
paymentID: string;
/**
* 产品id
*/
productID: string;
/**
* 包含与所购买项目关联的本地金额和货币
*/
purchasePrice: string;
/**
* 发生购买时的Unix时间戳
*/
purchaseTime: string;
/**
* 代表可用于消费者购买时的token
*/
purchaseToken: string;
/**
* 购买请求的服务器签名编码
*/
signedRequest: string;
}
添加桌面快捷方式(置顶)(有需要才接入)
canCreateShortcutAsync(): Promise<boolean>;
是否可以准备可以创建快捷方式createShortcutAsync( ): Promise<void>; !!
创建快捷方式
Examples:
minigame.canCreateShortcutAsync()
.then(function(canCreateShortcut) {
// 如果可以创建
if (canCreateShortcut) {
// 尝试创建快捷方式
minigame.createShortcutAsync()
.then(function() {
// Shortcut created
console.info("call createShortcutAsync done");
})
.catch(function(error) {
// Shortcut not created
console.info("call createShortcutAsync fail: ", error);
});
}
})
.catch(function(error) {
console.info("canCreateShortcut fail: ", error);
});
注意: 必须先判断是否准备好,可以创建的情况才创建快捷方式
分享(有需要才接入)
shareAsync(payload: SharePayload): Promise<void>
Examples:
minigame.shareAsync({
image: base64Picture,
text: 'X is asking for your help!',
data: { myReplayData: '...' },
switchContext: false,
}).then(function() {
// success to share, continue with the game.
})
.catch(function(error) {
// share fail
});
参数定义:
interface SharePayload {
/**
* 表示共享的目标, 7.1已经删除,用问号兼容老版本
* Indicates the intent of the share.
* "INVITE" | "REQUEST" | "CHALLENGE" | "SHARE"
*/
intent?: string;
/**
* 要分享的图像,使用 base64 编码
* A base64 encoded image to be shared.
*/
image: string;
/*
* gif 或者 video
*/
media?: MediaParams;
/**
* 要分享的文字
* A text message to be shared.
*/
text: string;
/**
* 一个附加到分享上的数据。
* 所有从这个分享启动的游戏都可以通过 FBInstant.getEntryPointData() 方法获取到该数据。
* A blob of data to attach to the share.
*/
data?: Object;
/**
* 在共享对话框中设置共享目的地的可选数组。如果没有指定,将显示所有可用的共享目的地。
*/
shareDestination?: string[],
/**
* 指示是否将用户切换到共享时创建的新上下文的标志
*/
switchContext?: boolean,
}
语言
getLocale(): string;
const lang = minigame.getLocale(); // "假设当前是美国英语环境, 返回en_US"
// 判断语言是否为英语
if (lang.includes("en")){
console.info("current language is en");
}
// 或
if (lang.substr(0, 2) === "en"){
console.info("current language is en");
}
邀请
inviteAsync(payload: InvitePayload ): Promise<void>;
minigame.inviteAsync({
image: base64Picture,
text: {
default: 'X just invaded Y\'s village!',
localizations: {
ar_AR: 'X \u0641\u0642\u0637 \u063A\u0632\u062A ' +
'\u0642\u0631\u064A\u0629 Y!',
en_US: 'X just invaded Y\'s village!',
es_LA: '\u00A1X acaba de invadir el pueblo de Y!'
}
},
data: { myReplayData: '...' }
}).then(function() {
// continue with the game.
}).catch(function(error){
console.error("invite error: ", error);
})
参数定义:
interface InvitePayload {
/* 一个以base64编码的图像,用于分享。*/
image: string;
/* 文本消息,或者一个包含默认文本作为'default'值以及将语言区域键映射到翻译的另一个对象作为'localizations'值的对象。*/
text: string | LocalizableContent;
/*
* 可选的呼叫动作按钮文本。默认情况下,我们将使用本地化的“Play”作为按钮文本。如果要提供自己的呼叫动作的本地化版本,请传递一个对象,将默认cta作为'default'值,并将语言区域键映射到翻译作为'localizations'值。
*/
cta?: string | LocalizableContent;
/* 要附加到分享的数据块。从分享启动的所有游戏会话都可以通FBInstant.getEntryPointData()访问此数据块。*/
data?: Object;
/* 要应用于建议的一组筛选器。可以应用多个筛选器。如果应用筛选器时没有返回结果,将生成没有筛选器的结果*/
filters?: Array<InviteSection>;
/*
* 包含在对话框中的一组部分。每个部分可以分配一个要返回的最大结果数(最多为10个)。如果未包含最大值,将应用默认最大值。部分将按照它们在数组中列出的顺序包括。最后一个部分将包括较大的最大结果数,如果提供了maxResults,它将被忽略。如果此数组为空,将使用默认部分。
*/
sections?: Array<InviteSection>;
/* 可选的标题,显示在邀请对话框的顶部,而不是通用标题。此参数不作为消息的一部分发送,但仅在对话框标题中显示。标题可以是字符串,也可以是一个对象,将默认文本作为'default'值,并将语言区域键映射到翻译作为'localizations'值。 */
dialogTitle?: string | LocalizableContent;
}
interface InviteSectionType {
/** 这包含组上下文,例如来自组线程的上下文。 */
GROUPS: string;
/** 这包含个人用户,例如朋友或 1:1 线程。 */
USERS: string;
}
interface LocalizationsDict {
[key: string]: string;
}
/** 表示具有本地化和可依赖的默认值的字符串。 */
interface LocalizableContent {
/** 当查看者的区域设置不是本地化对象中的键时要使用的字符串的默认值。 */
default: string;
/** 指定每个区域设置中查看器使用的字符串。 有关支持的区域设置值的完整列表 */
localizations: LocalizationsDict;
}
interface InviteSection {
/** 要包含在 informAsync 对话框中的部分的类型 */
sectionType: InviteSectionType;
/** 该部分中包含的可选最大结果数。该值不能高于 10。最后一部分将忽略该值,该部分将包含尽可能多的结果。如果未包含,则将使用该部分类型的默认最大结果数。 */
maxResults: number;
}
数据存储(必接)
数据保存
setDataAsync (data: Object): Promise<void>
minigame.player
.setDataAsync({
achievements: ['medal1', 'medal2', 'medal3'],
currentLife: 300,
})
.then(function() {
console.log('data is set');
});
获取数据保存
minigame.player
.getDataAsync(['achievements', 'currentLife'])
.then(function(data) {
console.log('data is loaded');
var achievements = data['achievements'];
var currentLife = data['currentLife'];
});
本地测试环境
需要在游戏根目录启动一个web服务器,创建web服务器的方式有很多,比如node.js的http-server,Serve等模块,python的SimpleHTTPServer等等,具体使用什么库,由开发者自行决定。
这里以Node.js的http-server为例:
1.将minigame.json的isTest设置为true 。
2.在游戏根目录启动web服务器,执行指令: http-server -o -c-l,这样会自动打开浏览器,并打开 http://127.0.0.1:8080/,接下来就可以直接测试广告了 。
模拟线上环境
步骤:
1.打开https://minigamecloud.com/testgame 。
2.将minigame.json中的isTest设置为false
。
3.将接入SDK后的本地游戏链接,放进页面的地址栏中。
4.点击开始测试后,就可以模拟线上环境测试。
------------------------------------------------------ END ---------------------------------------------------------------------------