当前位置: 首页 > article >正文

bilibili 哔哩哔哩小游戏SDK接入

小游戏的文档 简介 · bilibili小游戏bilibili小游戏具有便捷、轻量、免安装的特点。游戏包由云端托管,在哔哩哔哩APP内投放和运行,体验流畅,安全可靠。icon-default.png?t=O83Ahttps://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判断当前宿主是否支持跳转侧边栏:​

  • 返回字段isExist=true时,展示奖励入口,进入步骤二​
  • 返回字段isExist=false时,不展示奖励入口​

步骤二:

奖励展示

1. 用户点击奖励入口时,通过获取bl.onShow最新启动状态,判断当前用户是否从侧边栏启动:​

  • 侧边栏启动:奖励按钮显示「领取奖励」​
  • 非侧边栏启动:奖励按钮显示未完成,进入第2步​

【判断是否从侧边栏启动时,应使用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	哔哩哔哩漫画	


http://www.kler.cn/a/465154.html

相关文章:

  • Fabric部署-docker安装
  • JAVA:Spring Boot 集成 Quartz 实现分布式任务的技术指南
  • Jdk动态代理源码缓存优化比较(JDK17比JDK8)
  • 《深入浅出HTTPS​​​​​​​​​​​​​​​​​》读书笔记(24):椭圆曲线密码学
  • web漏洞之文件包含漏洞
  • 23. 【.NET 8 实战--孢子记账--从单体到微服务】--记账模块--预算
  • 黑马商城:RabbitMQ基础
  • 在K8S中,Pod请求另一个Pod偶尔出现超市或延迟,如何排查?
  • 试题转excel;word转excel;大风车excel(1.1更新)
  • Linux 系统常见问题
  • sklearn_pandas.DataFrameMapper的用法
  • [算法] [leetcode-215] 数组中的第K个最大元素
  • wx015基于springboot+vue+uniapp的经济新闻资讯的设计与实现
  • 虚拟电厂搭建指南:绿虫仿真设计软件的助力
  • 【MySQL】什么是事务?MVCC?
  • Ceph对象存储接口的路线
  • 直观解读 JuiceFS 的数据和元数据设计(一)
  • LWM2M---Wakaama源码对接华为云平台
  • 推荐几个 docker 镜像加速地址
  • 【Vue】Composition API 钩子
  • vim、watch、cp和mv
  • df.replace({‘b‘: r‘\s*(\.)\s*‘}, {‘b‘: r‘\1ty‘}, regex=True)
  • vue中的h
  • CES Asia 2025:科技盛宴引领未来,BESTAR声学创新备受瞩目
  • 时间关系推理:利用大型语言模型检测股票投资组合崩溃
  • FFmpeg 4.3 音视频-多路H265监控录放C++开发二十一.4,SDP协议分析