| 版本 | 修改内容 |
|---|---|
| v1.0.0 | |
| v1.0.1 | 新增game-vivo-config.js配置项 |
- 若游戏页使用iframe在详情页内嵌打开,查看目录二、目录三
- 若游戏页使用一个新的webview打开,查看目录二、目录四
├── index.html # 游戏详情页
├── detal/ # 游戏详情页静态资源
│ ├── xxx.js
│ └── xxxx.css
├── manifest.json # 配置项(配置说明见2.3)
├── game-vivo-config.js # 同manifest.json(若同manifest与本身项目配置冲突,可以改用这个)
├── icon.png # 游戏icon(需要替换)
├── sdkAds.js # 广告通信和API初始化(需自行实现广告逻辑)
├── game.html # 游戏页面(需要替换)
└── game.js # 游戏静态资源(游戏页面相关静态资源可在根目录创建game文件进行管理)
// mainifest.json
{
"iframeOpen": true, // 游戏页使用iframe内嵌,更多查看目录三
"gameInfo": {
"gameLink": "game.html?a=xxxx", // 根目录的game.html,后面可根据需要拼接参数
"gameName": "游戏名称",
"icon": "icon.png", // 请替换根目录下的icon
"adsenseAccountId": "ca-pub-xxxxxxxxxxx",
"gameDesc": "游戏介绍",
"score": 4.30,
"adList": [ "广告1号位", "广告2号位" ],
"recommendList": [
// 8个游戏推荐
{
"gameLink": "https://xxxxxx", // 游戏完整链接
"gameName": "游戏名称",
"icon": "游戏icon链接"
}
]
}
}
manifest.json配置"iframeOpen": true
function postMessageToParent(params) {
window.parent.postMessage(
JSON.stringify(params),
"https://xxxxxxx" // 父window的域名
);
}
window.addEventListener("message", (e) => {
// 根据消息是否来自父window的域名,判断是否过滤
if (e.origin !== "https://xxxxxxx") {
console.warn("其他消息(来自:" + e.origin + ")");
return;
}
console.log(e, "从父window发过来的消息");
try {
const paramsFromParent = JSON.parse(e.data);
// 根据methon类型,执行不同逻辑
} catch (error) {
console.log(error);
}
});
为了便于平台分析游戏页面加载性能并进行优化,请在游戏首屏加载完成(例如:首个可交互画面展示)调用getPerformanceTrack() 方法,并将性能数据通过postMessage上报给父页面。
由于父窗口无法准确获取 iframe 内页面的性能指标,因此需要在 游戏页面内部执行该方法 并主动上报
async function reportGameLoading() {
const performanceData = await getPerformanceTrack();
postMessageToParent({
method: "gameLoadingCompleted",
data: performanceData,
});
}
getPerformanceTrack方法添加到你的项目中:function getPerformanceTrack() {
return new Promise((resolve) => {
let count = 0;
function check() {
if (window.performance && window.performance.timing) {
const timing = window.performance.timing;
// 等待 loadEventEnd 产生
if (timing.loadEventEnd === 0) {
if (count++ > 100) {
resolve({});
return;
}
setTimeout(check, 100);
return;
}
const paints = performance.getEntriesByType("paint");
const fcp = paints?.find((paint) => paint.name === "first-contentful-paint");
const fp = paints?.find((paint) => paint.name === "first-paint");
const calc = (end, start) => {
return end > 0 && start > 0 && end >= start ? end - start : 0;
};
const {
navigationStart,
responseStart,
domContentLoadedEventEnd,
loadEventEnd,
domainLookupEnd,
domainLookupStart,
connectEnd,
connectStart,
secureConnectionStart,
domComplete,
domLoading,
domInteractive,
} = timing;
const effectiveLoadEventEnd =
loadEventEnd > 0
? loadEventEnd
: domComplete > 0
? domComplete
: Date.now();
resolve({
ttfb: calc(responseStart, navigationStart),
wst: calc(responseStart, navigationStart),
tti: calc(domInteractive, navigationStart),
ready: calc(domContentLoadedEventEnd, navigationStart),
load: calc(effectiveLoadEventEnd, navigationStart),
dns: calc(domainLookupEnd, domainLookupStart),
tcp: calc(connectEnd, connectStart),
ssl:
secureConnectionStart > 0
? calc(connectEnd, secureConnectionStart)
: 0,
dom: calc(domComplete, domLoading),
fpt: fp ? Math.max(0, parseInt(fp.startTime.toFixed())) : 0,
fcp: fcp ? Math.max(0, parseInt(fcp.startTime.toFixed())) : 0,
});
} else {
resolve(null);
}
}
check();
});
}
自行在sdkAds.js中实现广告通信以及Ad Placement API初始化
广告详细参数介绍请参考谷歌参数用法:https://developers.google.com/ad-placement/apis/adbreak?hl=zh-cn
<script :src="`https://sdk.vivofungame.com/${version}/index.min.js`"></script>
按照1.2目录的版本号修改version,目前最新版是v1.0.1
在
标签中配置<script>
window.vivoSDKConfig = {
adConfig: {
adTest: true, // 启用Adsense测试模式,若想启用正式模式请删掉该字段
adFrequencyHint: '', // 广告展示频次,默认120s
adClient: "ca-pub-xxxxx"
}
}
</script>
请务必把这个方法加到游戏首屏加载完成的时候,上报游戏页面的加载时长数据,便于后续的分析优化
window.vivoSDK.gameLoadingCompleted('game', options)
自行实现Ad Placement API广告相关逻辑
设置路径:Google AdSense—广告—编辑管理自动广告—重叠式广告格式—锚定广告—高级设置
(1)不勾选:允许折叠式锚定广告等
(2)选择锚定广告位置:仅限底部
参考如下图1:
设置路径:Google AdSense—广告—编辑管理自动广告—重叠式广告格式—穿插广告—高级设置
(1)穿插广告展示频次:2分钟
(2)不勾选:允许为穿插广告启用额外触发条件等
参考如下图2: