小游戏的文档 简介 · bilibili小游戏bilibili小游戏具有便捷、轻量、免安装的特点。游戏包由云端托管,在哔哩哔哩APP内投放和运行,体验流畅,安全可靠。https://miniapp.bilibili.com/small-game-doc/guide/intro/
没想过接入这个sdk比ios还难,ios不让用插屏广告与原生广告,被打回来了一次,去掉就行,还有截图必须是当前游戏的,不要糊弄。
哔哩哔哩官方目前的api还是有点乱的,官方自己都还在整合中。
必接项目如下:
1.检查并添加游戏启动埋点,否则可能无法通过审核。
上报小游戏启动成功埋点。 需要在游戏首页成功渲染时调用。【不是每个版本都需要调用这个接口】
laya 从 v2.6 - v2.13 版本,可以通过 layaIDE 支持直接导出 bilibili 小游戏,无需其他修改。
其他的引擎不同版本还是根据官方API修改。
2.小游戏配置 game.json 分包也在这里,后面还有那个实名认证。
{
"version": "1.0.0",
"appId": "biligameccxxxxxxxxxxxxxxa4",
"deviceOrientation": "portrait",
"networkTimeout": {
"request": 5000,
"connectSocket": 5000,
"uploadFile": 5000,
"downloadFile": 5000
},
"subpackages": [
{
"name": "Scene",
"root": "res/Scene/"
}
]
}
3.音频必须做适配 切换前后台 音频的中断与恢复,被打回过
//背景音乐脚本
export default class GameSoundManager {
//播放
static playMusic(musicName) {
if (window.bl) {
if (!GameSoundManager.bgm) {
GameSoundManager.bgm = bl.createInnerAudioContext();
}
// GameSoundManager.bgm.stop();
GameSoundManager.bgm.src = "Sound/" + musicName + ".mp3";
GameSoundManager.bgm.autoplay = true;
GameSoundManager.bgm.loop = true;
GameSoundManager.bgm.play();
} else {
Laya.SoundManager.playMusic("Sound/" + musicName + ".mp3", 0);
}
}
//暂停
static pauseMusic() {
if (window.bl) {
if (!GameSoundManager.bgm) {
GameSoundManager.bgm = bl.createInnerAudioContext();
}
GameSoundManager.bgm.pause();
}
}
}
音效没必要的,主要针对背景音乐。在合适的地方调用,cocos的话,放在常驻节点上。
if (window.bl) {
bl.onShow(res => {
GameSoundManager.playMusic("BGM");
});
bl.onHide(res => {
GameSoundManager.pauseMusic();
});
}
4.侧边栏 必接
侧边栏礼包必须每天都可领取,同游戏内签到礼包。
先看看官方的API,侧边栏、桌面快捷方式等都会用到场景值。
小游戏开发者可以在 bl.getLaunchOptionsSync 和 bl.onShow 中获取上述场景值
场景值 | 类型 | 含义 |
10001 | string | 我的(首页Tab)-小游戏中心 |
10002 | string | 手机设备桌面快捷入口 |
10003 | string | 各分享渠道 |
021036 | string | 从侧边栏进入小游戏 |
侧边栏的步骤:
步骤 | 解释 |
步骤一: 启动监听,判断是否展示奖励入口 | 1. 游戏启动时通过bl.onShow监听启动信息; 【请确保在游戏启动时机(game.js运行时机)同步监听bl.onShow,若时机太晚收不到回调,会导致用户按操作从侧边栏返回游戏后,无法领取到奖励,造成用户客诉!】 2. 通过bl.checkScene判断当前宿主是否支持跳转侧边栏:
|
步骤二: 奖励展示 | 1. 用户点击奖励入口时,通过获取bl.onShow的最新启动状态,判断当前用户是否从侧边栏启动:
【判断是否从侧边栏启动时,应使用bl.onShow的最新返回值,否则用户从侧边栏热启动小游戏时,会由于返回值未更新而无法领取到奖励,造成用户客诉!】 2. 自动跳转侧边栏:可增加一个跳转按钮,按钮点击回调事件设置为:关闭当前奖励界面并调用bl.navigateToScene(能力已全量开放,无需配置白名单)。用户点击按钮时会自动跳转到侧边栏。 【平台强烈建议接入「自动跳转侧边栏」能力,可大幅度降低用户跳出小游戏后的流失率。】 |
步骤三: 测试,上线 | 开发者需在测试环境下完整跑通从侧边栏启动后领取奖励的链路,测试通过确认无误后发布上线。 |
第一步:监听是否可以显示桌面侧边栏按钮,这个与抖音api差不多
bl.onShow(res => {
//兼容 与基础版本做对比 CompareVersion()这个方法就不写了,以前文章应该有的
if (SdkUtil.CompareVersion(bl.getSystemInfoSync().SDKVersion, '3.99.5') >= 0) {
console.log("检测版本号");
bl.checkScene({
scene: "sidebar",
success: (res) => {
if (res.isExist) {
//显示入口有奖按钮
this.goldButton.visible = true;
} else {
//隐藏入口有奖按钮
this.goldButton.visible = false;
}
},
fail: (res) => {
//隐藏入口有奖按钮
this.goldButton.visible = false;
}
});
} else {
//隐藏入口有奖按钮
this.goldButton.visible = false;
}
});
第二步:监听场景值是否从侧边栏进入。getUserData这个是我的读取本地存储的方法。
bl.onShow(res => {
const scene = res.scene;
if (scene == '021036' || bl.getLaunchOptionsSync().scene === "021036") {
// 记住,合适的地方移除这个本地存储.
// Laya.LocalStorage.removeItem("sidebar");
// 从侧边栏进入,显示侧边栏奖励界面的领奖按钮
Laya.LocalStorage.setItem("sidebar", "sidebar");
if (this.enterPanel.visible) {
//侧边栏奖励领取时间,在这里初始化一下,方便在其他地方调用到
this.offlineSliderTime = PlayerData.getUserData("rewardSliderDate");
this.offlineSliderTime = Date.now() - this.offlineSliderTime;
this.offlineSliderTime = this.offlineSliderTime / 1000;
const sidebar = Laya.LocalStorage.getItem("sidebar");
if (sidebar) {
this.getBtn.visible = true;//领奖按钮
this.enterBtn.visible = false;//侧边栏跳转按钮
} else {
this.getBtn.visible = false;//领奖按钮
this.enterBtn.visible = true;//侧边栏跳转按钮
}
}
}
});
//当打开侧边栏界面的时候,打开侧边栏按钮事件。
openSiderBarPanel(){
this.enterPanel.visible = true;
//侧边栏奖励领取时间,在这里初始化一下,方便在其他地方调用到
this.offlineSliderTime = PlayerData.getUserData("rewardSliderDate");
this.offlineSliderTime = Date.now() - this.offlineSliderTime;
this.offlineSliderTime = this.offlineSliderTime / 1000;
const sidebar = Laya.LocalStorage.getItem("sidebar");
if (sidebar) {
this.getBtn.visible = true;//领奖按钮
this.enterBtn.visible = false;//侧边栏跳转按钮
} else {
this.getBtn.visible = false;//领奖按钮
this.enterBtn.visible = true;//侧边栏跳转按钮
}
}
第二步:跳转侧边栏,按钮事件
navigateToScene() {
if (window.bl) {
bl.navigateToScene({
scene: "sidebar",
success: (res) => { },
fail: (res) => { },
});
}
}
第三步:领取奖励,按钮事件
getReward(){
if (this.offlineSliderTime < 60 * 60 * 24) {
SdkUtil.ShowToast("今日奖励已经领取");
return;
}
//保存领取奖励时间
var offlineSliderTime = this.getDayZeroTime();
PlayerData.setUserData("rewardSliderDate", offlineSliderTime);
//保存用户领取的奖励
PlayerData.setUserData("gold", PlayerData.getUserData("gold") + 2000);
PlayerData.saveData();
//弹窗提示
SdkUtil.ShowToast("获取金币 +200");
this.enterPanel.visible = false;
//刷新你的奖励
this.refreshXXX();//刷新界面
}
//13位时间戳,用于对比领奖时间
getDayZeroTime() {
var nowDay = new Date();
nowDay.setHours(0);
nowDay.setMinutes(0);
nowDay.setSeconds(0);
nowDay.setMilliseconds(0);
var nowDayTime = nowDay.getTime();
return nowDayTime;
}
至于实名认证与桌面快捷方式的每日领奖,可以按着上面来写。
5.分包 哔哩哔哩工具上传的是zip的压缩包
整个小游戏所有分包大小不超过 20M
单个分包/主包大小不能超过 4M
也就是不压缩的实际包体吗,一般情况下,不用考虑远程问题。
6.实名认证 必接 只支持安卓
根据规定,所有游戏用户必须完成实名认证才能继续访问和参与游戏。
属性 | 类型 | 默认值 | 必填 | 说明 |
title | string | 是 | 提示的标题 | |
content | string | 是 | 提示的内容 | |
giftImgUrl | string | 否 | 提示的礼包图片(支持gif) | |
cancelText | string | '取消' | 否 | 取消按钮的文字,最多 5 个字符 |
confirmText | string | '确定' | 否 | 确认按钮的文字,最多 5 个字符 |
giftImgUrl我使用的站内图片地址,后台会配置好的,官方也给了远程的API,本地的不知道能用不,没尝试。
7.激励视频埋点上报,官方没说是否必须,放置万一吧。
// 用户点击观看视频广告时上报
bl.reportScene({sceneId:1007});
rewardedVideoAd.load().then(() => {
return rewardedVideoAd.show();
});
8.添加到桌面礼包「必接」。 侧边栏打开礼包「必接」上方写过了
按钮事件调用,主要是针对ios的,被打回过。
if (window.bl) {
if (SdkUtil.CompareVersion(bl.getSystemInfoSync().SDKVersion, '3.99.4') >= 0) {
//bl.checkShortcut接口只支持android平台
if (bl.getSystemInfoSync().platform.toLowerCase().indexOf("android") != -1) {
//检测桌面快捷方式是否存在
bl.checkShortcut({
success(res) {
console.log("检查快捷方式"), console.log(res.status);
if (res.status.exist) {
//弹窗桌面礼包奖励界面
UIManager.ShowUIPanel("Desk", false);
} else {
bl.addShortcut({
success() {
console.log("添加桌面成功");
}, fail(err) {
SdkUtil.ShowToast("从桌面ICON进入领取每日奖励");
console.log("添加桌面失败", err.errMsg);
},
});
}
},
fail(res) {
SdkUtil.ShowToast("从桌面ICON进入领取每日奖励");
console.log("检查快捷方式失败", res.errMsg);
},
});
} else {
//从手机设备桌面快捷入口启动的场景值
if (bl.getLaunchOptionsSync().scene === "10002" || this.open_desk === true) {
//弹出桌面礼包奖励页面
UIManager.ShowUIPanel("Desk", false);
} else {
bl.addShortcut({
success() {
SdkUtil.ShowToast("从桌面ICON进入领取每日奖励");
console.log("添加桌面成功");
}, fail(err) {
SdkUtil.ShowToast("从桌面ICON进入领取每日奖励");
console.log("添加桌面失败", err.errMsg);
},
});
}
}
} else {
SdkUtil.ShowToast("请升级最新版本");
}
}
//场景值吗,在两个地方可以拿到,最好还是判断一下
bl.onShow(res => {
if (scene == '10002') {
this.open_desk = true;
}
});
9.埋点上报【主要防止万一】
bl.reportScene({});
sceneId | 说明 |
7 | 游戏可玩,比如进入游戏大厅 |
10 | 游戏新手教程完成 |
1007 | 激励视频广告,用户点击看广告 |
10.首屏渲染 index.js中,这个只正对哔哩哔哩小游戏,其它小游戏不要用【API中看到的】
var testRender = function () {
var GameConfig = {};
GameConfig.width = 640;
GameConfig.height = 1136;
GameConfig.scaleMode = "fixedwidth";
GameConfig.screenMode = "none";
GameConfig.alignV = "top";
GameConfig.alignH = "left";
Laya3D.init(GameConfig.width, GameConfig.height);
Laya["Physics"] && Laya["Physics"].enable();
Laya["DebugPanel"] && Laya["DebugPanel"].enable();
Laya.stage.scaleMode = GameConfig.scaleMode;
Laya.stage.screenMode = GameConfig.screenMode;
Laya.stage.alignV = GameConfig.alignV;
Laya.stage.alignH = GameConfig.alignH;
var logoSprite = new Laya.Sprite();
Laya.stage.addChild(logoSprite);
logoSprite.y = 300;
var handler = Laya.Handler.create(null, function () {
logoSprite.removeSelf();
});
logoSprite.loadImage("First/logo.png", handler);
var tTestText = new Laya.Text();
tTestText.autoSize = true;
tTestText.text = "正在努力加载中 ...";
tTestText.bold = true;
tTestText.font = "Microsoft YaHei";
tTestText.color = "#FFFFFF";
tTestText.fontSize = 20;
tTestText.x = 300;
tTestText.y = 700;
Laya.stage.addChild(tTestText);
//合理时间移除
setTimeout(() => {
tTestText.removeSelf();
}, 2000);
};
testRender();
11.分享功能
自定义图片路径,支持 PNG 及 JPG。建议图片分辨率 750*750
1、小游戏包内相对路径
2、blfile:// 协议路径
3、https:// 网络图片路径(暂不支持非 bilibili 图片服务器资源地址)
//SDK初始化时候调用
bundleShareActive() {
if (window.bl) {
bl.onShareAppMessage(() => {
return {
title: '啊啊啊啊',
subTitle: '啊啊啊啊啊',
imageUrl: 'XXXX'
};
});
}
}
//分享按钮点击时候调用
bl.shareAppMessage({
title: '啊啊啊啊',
subTitle: '啊啊啊啊啊',
imageUrl: 'xxxxxxxxxxxxx',
biliContent: '一款超好玩得小游戏,快来和我一起玩吧!',
success() {
console.log('分享视频成功');
if (callback != null) {
callback(1);
callback = null;
}
},
fail(e) {
console.log('分享视频失败' + JSON.stringify(e));
if (callback != null) {
callback(0);
callback = null;
}
}
}
12.录制视频,暂时不需要接入,存在问题,也非必须。被打回过。
不用接入,视频分享存在问题,以后可能会必须接入,像抖音一样。
13.如果存在输入 需要敏感词检测
bl.sensitiveWordCheck(Object object)
14.震动
bl.vibrateShort({})
15.版权是必要的
16.隐私协议等,非必须。
其他一些api
bl.showLoading({
title: '加载中',
})
setTimeout(function () {
bl.hideLoading()
}, 2000)
bl.showModal({
title: '提示',
content: '这是一个模态弹窗',
success(res) {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
bl.exitMiniProgram({})
bl.getSystemInfoSync() 异步
bl.getAppBaseInfo
0 哔哩哔哩
1 高能通
2 哔哩哔哩漫画