微信小步调和抖音小步调的分享和广告接入代码

嚴華  论坛元老 | 2024-10-8 02:29:49 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1779|帖子 1779|积分 5337

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x

开发完成小步调或者小游戏之后,我们为什么要接入分享和广告视频功能,主要原因有以下几个方面。
微信小步调和抖音小步调接入分享和广告功能主要基于以下几个原因:

  • 用户获取与增长:分享功能可以资助用户将小步调内容传播给更多人,从而扩大用户底子。通过社交网络的分享,能够吸引更多潜在用户使用小步调。
  • 加强用户互动:分享功能可以提升用户之间的互动,增加用户粘性。用户在分享内容时,往往会带来新的使用场景和体验,这样可以促进用户的积极参与。
  • 商业变现:广告功能为小步调提供了一种商业变现的方式。通过广告,开发者可以得到收入,从而支持小步调的持续运营与发展。
如今大部门小步调和小游戏都是靠广告变现,所以接入广告的代码是所有开发者必不可少的环节了,下面给各人解说一下怎样参加分享和广告接入的代码。
文章末了整合了一个工具类,有需要的朋友可以直接复制使用.
微信小步调

分享功能


  • 在页面逻辑中设置分享:


  • 在小步调的页面代码中,使用 onShareAppMessage 函数设置分享内容:
    1. Page({  
    2.   onShareAppMessage: function () {  
    3.     return {  
    4.       title: '分享标题',  
    5.       path: '/pages/example/example?id=123',  
    6.       imageUrl: '/images/share.png' // 可选  
    7.     };  
    8.   }  
    9. });
    复制代码
    2. 用户触发分享:
  • 可以在页面中添加一个分享按钮,使用 wx.showShareMenu 表现分享菜单:
    1. wx.showShareMenu({  
    2.   withShareTicket: true // 可选,是否使用带分享票据的分享  
    3. });
    复制代码
    广告接入

  • 1,接入广告组件:

    • 在小步调的页面中引入广告组件,例如 banner 广告:
      1. <ad unit-id="你的广告位ID" />
      复制代码
      由于广告如今是各大平台的主要收入来源,所以微信和抖音都是花了很大的力气让开发者尽可能地简朴接入广告代码。就这样一句代码,加到你的小步调内里,他就会源源不断地输送广告。
    • 输送的广告完全是依靠大数据,你喜欢看什么,就给你推什么广告。

        
2,初始化广告:


  • 在对应的 JavaScript 文件中,您可以监控广告加载变乱:
    1. const adInstance = wx.createBannerAd({  
    2.   adUnitId: '你的广告位ID',  
    3.   style: {  
    4.     left: 0,  
    5.     top: 0,  
    6.     width: 300  
    7.   }  
    8. });  
    9. adInstance.onLoad(() => {  
    10.   console.log('广告加载成功');  
    11. });  
    12. adInstance.onError((err) => {  
    13.   console.error('广告加载失败', err);  
    14. });
    复制代码
    抖音小步调

    分享功能
  • 在页面中设置分享行为:

    • 在 页面 的 JS 文件中,使用 onShareAppMessage:
      1. Page({  
      2.   onShareAppMessage: function () {  
      3.     return {  
      4.       title: '抖音小程序分享',   
      5.       path: '/pages/example/example?id=123',  
      6.     };  
      7.   }  
      8. });
      复制代码
      2.主动分享:
    • 通过按钮或其他触发变乱调用 my.share 方法:
      1. my.share({  
      2.   title: '分享标题',  
      3.   url: '分享链接',  
      4.   success: (result) => {  
      5.     console.log(result);  
      6.   },  
      7.   fail: (error) => {  
      8.     console.error(error);  
      9.   }  
      10. });
      复制代码
      广告接入
    • 引入广告组件:

      • 在页面的 HTML 代码中添加广告组件:
        1. <ad unit-id="你的广告位ID" />
        复制代码
        广告初始化和监控:
        通过 JavaScript 控制广告的加载和监控
        1. const ad = my.createBannerAd({  
        2.   adUnitId: '你的广告位ID',  
        3.   style: {  
        4.     top: 0,  
        5.     left: 0,  
        6.     width: '100%',  
        7.   },  
        8. });  
        9. ad.onLoad(() => {  
        10.   console.log('广告加载成功');  
        11. });  
        12. ad.onError((err) => {  
        13.   console.error('广告加载失败', err);  
        14. });
        复制代码


固然看起来非常简朴,但是实际上开发起来还是不方便,所以我写了一套完备的小游戏开发的工具类,满足了各大平台的要求.包括登录,分享,插屏广告,鼓励广告,banner广告,抖音侧边栏功能.
  1. /**
  2. * 小游戏平台SDK工具封装,目前只支持微信和抖音平台
  3. */
  4. export namespace MiniGameSdk {
  5.     interface ISize {
  6.         width: number;
  7.         height: number;
  8.     }
  9.     export interface IPosition {
  10.         top: number;
  11.         left: number;
  12.     }
  13.     export function isWechat(): boolean {
  14.         //@ts-ignore
  15.         return window.wx !== null && window.wx !== undefined;
  16.     }
  17.     export function isBytedance(): boolean {
  18.         //@ts-ignore
  19.         return window.tt !== null && window.tt !== undefined;
  20.     }
  21.     // 支付宝平台
  22.     export function isAli(): boolean {
  23.         //@ts-ignore
  24.         return window.my !== null && window.my !== undefined;
  25.     }
  26.     function getSysWinSize(): ISize {
  27.         let sys: any;
  28.         if (isWechat()) {
  29.             // @ts-ignore
  30.             sys = wx.getSystemInfoSync();
  31.         } else if (isBytedance()) {
  32.             // @ts-ignore
  33.             sys = tt.getSystemInfoSync();
  34.         }
  35.         let size: ISize = { width: 0, height: 0 };
  36.         if (sys) {
  37.             size.width = sys.windowWidth;
  38.             size.height = sys.windowHeight;
  39.         }
  40.         return size;
  41.     }
  42.     /**
  43.      * 插屏广告。微信抖音都支持!
  44.      */
  45.     class ADInterstitial {
  46.         private _adUid: string;
  47.         private _interstitial: any;
  48.         get aduid() {
  49.             return this._adUid;
  50.         }
  51.         constructor(adUid: string) {
  52.             this._adUid = adUid;
  53.         }
  54.         show() {
  55.             // @ts-ignore
  56.             if (isWechat() && !wx.createInterstitialAd) {
  57.                 console.warn('wechat unsupport interstitial AD!');
  58.                 this._interstitial = null;
  59.                 return;
  60.             }
  61.             // @ts-ignore
  62.             if (isBytedance() && !tt.createInterstitialAd) {
  63.                 console.warn('bytedance unsupport interstitial AD!');
  64.                 this._interstitial = null;
  65.                 return;
  66.             }
  67.             if (this._interstitial) {
  68.                 this._interstitial.load();
  69.             } else {
  70.                 if (isWechat()) {
  71.                     // @ts-ignore
  72.                     this._interstitial = wx.createInterstitialAd({ adUnitId: this._adUid });
  73.                 } else if (isBytedance()) {
  74.                     // @ts-ignore
  75.                     this._interstitial = tt.createInterstitialAd({ adUnitId: this._adUid });
  76.                 } else {
  77.                     this._interstitial = null;
  78.                 }
  79.                 this._interstitial?.onLoad(() => {
  80.                     console.log('load interstitial ad success');
  81.                     this._interstitial.show().catch((err: any) => {
  82.                         console.log('catch interstitial ad error:', err);
  83.                     });
  84.                 });
  85.                 this._interstitial?.onError((err: any) => {
  86.                     console.log('interstitial ad on error:', err);
  87.                 });
  88.             }
  89.         }
  90.         destory() {
  91.             this._interstitial?.destroy();
  92.         }
  93.     }
  94.     class ADBanner {
  95.         private _adUid: string;
  96.         private _banner: any;
  97.         get aduid() {
  98.             return this._adUid;
  99.         }
  100.         /**
  101.          * 抖音和微信都支持
  102.          * 横幅广告。预估宽度默认为300,预估高度为140。如果你不确定就按默认值来。
  103.          * @param adUid 广告UID,后端配置
  104.          * @param isTop 是否在屏幕顶部展示。内部会自动居中计算位置。
  105.          * @param bannerWidth 横幅广告的预估宽度。默认300
  106.          * @param autoShow 广告加载完成后是否立刻显示,默认为不显示
  107.          */
  108.         constructor(adUid: string, param: boolean | IPosition, bannerWidth: number = 300, autoShow: boolean = false) {
  109.             this._adUid = adUid;
  110.             this.create(autoShow, bannerWidth, param); // 默认300比较合适
  111.         }
  112.         private create(autoShow: boolean, bannerWidth: number, param: boolean | IPosition) {
  113.             if (!isWechat() && !isBytedance()) {
  114.                 this._banner = null;
  115.                 return;
  116.             }
  117.             this.destroy();
  118.             let winSize = getSysWinSize();
  119.             let height = bannerWidth * 0.4;
  120.             let top = 0, left = 0;
  121.             if (typeof param === "boolean") {
  122.                 left = (winSize.width - bannerWidth) / 2
  123.                 top = param ? 5 : (winSize.height - height);
  124.             } else {
  125.                 left = param.left;
  126.                 top = param.top;
  127.             }
  128.             let params = {
  129.                 adUnitId: this._adUid,
  130.                 adIntervals: 30,// 自动刷新频率不能小于30秒
  131.                 style: { left: left, top: top, width: bannerWidth }
  132.             }
  133.             if (isWechat()) {
  134.                 // @ts-ignore
  135.                 this._banner = wx.createBannerAd(params);
  136.             } else if (isBytedance()) {
  137.                 // @ts-ignore
  138.                 this._banner = tt.createBannerAd(params);
  139.             } else {
  140.                 this._banner = null;
  141.             }
  142.             this._banner?.onError((err: any) => {
  143.                 console.log('ad banner error:', err);
  144.             });
  145.             this._banner?.onLoad(() => {
  146.                 autoShow && this._banner.show();
  147.             });
  148.         }
  149.         show() {
  150.             this._banner?.show();
  151.         }
  152.         hide() {
  153.             this._banner?.hide();
  154.         }
  155.         destroy() {
  156.             this._banner?.destroy();
  157.         }
  158.     }
  159.     class ADCustom {
  160.         private _adUid: string;
  161.         private _adCustom: any;
  162.         get aduid() {
  163.             return this._adUid;
  164.         }
  165.         /**
  166.          * 由于原生模板广告在微信服务后端可以定制宽度大小,个数,缩放比例等,所以位置调整要根据设置的宽度来定。抖音不支持!
  167.          * @param adUid 广告UID,后端配置
  168.          * @param top 从左上角开始,距离屏幕顶部的距离。注意:这个数据为设备屏幕宽度width。如果需要获取屏幕的像素,需要乘以设备像素比Pixel-Ratio,例如iPhone 13 Pro的Pixel-Ratio为3,像素为Width*3。
  169.          * @param left 从左上角开始,距离屏幕最左边的距离。注意:这个数据为设备屏幕宽度width。如果需要获取屏幕的像素,需要乘以设备像素比Pixel-Ratio,例如iPhone 13 Pro的Pixel-Ratio为3,像素为Width*3。
  170.          * @param scale 原生模板广告的尺寸,默认为1,即100%。此值在微信服务后端广告中获得,默认为100%,目前有100%,90%,80%三种,一般情况不用修改。若有修改,记得传入值,例如90%就传入0.9。
  171.          */
  172.         constructor(adUid: string, top: number = 0, left: number = 0, scale: number = 1.0) {
  173.             this._adUid = adUid;
  174.             this.createCustomAd(top, left, scale);
  175.         }
  176.         private createCustomAd(top: number, left: number, scale: number) {
  177.             if (!isWechat()) { // only wechat support custom ad
  178.                 this._adCustom = null;
  179.                 console.log('Only wechat support Custom Ad');
  180.                 return;
  181.             }
  182.             this.destroy();
  183.             // 原生模板5个应用宽度为375,若设置了缩放比例,则宽度也需要设置
  184.             // let width = 375 * this._scale;
  185.             // let newLeft = (sys.windowWidth - width) / 2;
  186.             // let newTop = sys.windowHeight / 2; // 120是预估高度
  187.             // @ts-ignore
  188.             this._adCustom = wx.createCustomAd({
  189.                 adUnitId: this._adUid,
  190.                 style: { left: left, top: top, fixed: true }
  191.             });
  192.             this._adCustom?.onError((err: any) => {
  193.                 console.log('ad custom error:', err);
  194.             });
  195.         }
  196.         show() {
  197.             this._adCustom?.show();
  198.         }
  199.         hide() {
  200.             this._adCustom?.hide();
  201.         }
  202.         destroy() {
  203.             this._adCustom?.destroy();
  204.         }
  205.     }
  206.     /**
  207.      * 视频广告用户点击行为结果
  208.      */
  209.     export enum EAdVideoResult {
  210.         /**
  211.          * 用户看完了广告,游戏可发放奖励。
  212.          */
  213.         ACCEPT,
  214.         /**
  215.          * 用户中途关闭了广告,即未看完状态。不可发放奖励。
  216.          */
  217.         REJECT,
  218.         /**
  219.          * 广告组件内部发生了错误。不可发放奖励。
  220.          */
  221.         ERROR,
  222.     }
  223.     class ADVideo {
  224.         private _adUid: string;
  225.         private _adVideo: any = null;
  226.         get aduid() {
  227.             return this._adUid;
  228.         }
  229.         constructor(adUid: string) {
  230.             this._adUid = adUid;
  231.         }
  232.         /**
  233.          * 由于微信和抖音视频广告机制不同,微信可以看的视频广告个数只有0和1个,抖音平台则可以看0~maxVideoCount
  234.          * @param onResult 两个参数:第一个res是EAdVideoResult定义,第二count是用户看了多少个视频广告。
  235.          * @param target onResult的拥有者
  236.          * @param maxVideoCount 可以连续看最大视频个数,可最大化商业效率。默认为3个。
  237.          * @returns
  238.          */
  239.         show(onResult: (res: EAdVideoResult, count: number) => void, target?: any, maxVideoCount: number = 3): void {
  240.             let callback = (state: EAdVideoResult, count: number) => {
  241.                 onResult?.call(target, state, count);
  242.             }
  243.             if (!isWechat() && !isBytedance()) {
  244.                 callback(EAdVideoResult.ACCEPT, 1);
  245.                 this._adVideo = null;
  246.                 return;
  247.             }
  248.             let onAdVideoClosed = (res: any) => {
  249.                 this._adVideo?.offClose(onAdVideoClosed);
  250.                 if (isWechat()) {
  251.                     if (res && res.isEnded || res === undefined) {
  252.                         callback(EAdVideoResult.ACCEPT, 1);
  253.                     } else {
  254.                         callback(EAdVideoResult.REJECT, 0);
  255.                     }
  256.                 } else if (isBytedance()) {
  257.                     let resConverted = res as { isEnded: boolean, count: number };
  258.                     if (resConverted && resConverted.count > 0) {
  259.                         callback(EAdVideoResult.ACCEPT, resConverted.count);
  260.                     } else {
  261.                         callback(EAdVideoResult.REJECT, 0);
  262.                     }
  263.                 }
  264.             }
  265.             this._adVideo?.offClose(onAdVideoClosed);
  266.             if (isWechat()) {
  267.                 // @ts-ignore
  268.                 this._adVideo = wx.createRewardedVideoAd({
  269.                     adUnitId: this._adUid
  270.                 });
  271.             } else if (isBytedance()) {
  272.                 // @ts-ignore
  273.                 this._adVideo = tt.createRewardedVideoAd({
  274.                     adUnitId: this._adUid,
  275.                     multiton: true,
  276.                     multitonRewardMsg: ['多1次奖励', '再多一次奖励', '再多一次奖励'],
  277.                     multitonRewardTimes: maxVideoCount,
  278.                 });
  279.             } else {
  280.                 this._adVideo = null;
  281.             }
  282.             this._adVideo?.onLoad(() => {
  283.                 console.log('Ad load success');
  284.             });
  285.             this._adVideo?.onError((err: { errMsg: string, errCode: number }) => {
  286.                 console.log('Ad video error:', err);
  287.                 callback(EAdVideoResult.ERROR, 0);
  288.             });
  289.             this._adVideo?.onClose(onAdVideoClosed);
  290.             console.info("广告2");
  291.             this._adVideo?.show().catch(() => {
  292.                 this._adVideo?.load().then(() =>
  293.                     this._adVideo?.show()).catch((err: { errMsg: string, errCode: number }) => {
  294.                         console.log('Catch video ad error:', err);
  295.                         callback(EAdVideoResult.ERROR, 0);
  296.                     });
  297.             });
  298.         }
  299.         destory() {
  300.             this._adVideo?.destory();
  301.         }
  302.     }
  303.     export enum EAdBannerLocation {
  304.         /**
  305.          * 屏幕顶部
  306.          */
  307.         TOP,
  308.         /**
  309.          * 屏幕底部
  310.          */
  311.         BOTTOM,
  312.     }
  313.     export class AdvertManager {
  314.         private static _instance: AdvertManager;
  315.         static get instance(): AdvertManager {
  316.             if (!AdvertManager._instance) {
  317.                 AdvertManager._instance = new AdvertManager();
  318.             }
  319.             return AdvertManager._instance;
  320.         }
  321.         private _video: ADVideo;
  322.         private _interstitial: ADInterstitial;
  323.         private _banner: ADBanner;
  324.         private _customs: Record<string, ADCustom> = {};
  325.         private constructor() {
  326.         }
  327.         /**
  328.          * 预加载横幅广告,不会显示。只有你在调用showBanner时才会显示。
  329.          * 可重复调用,但是会销毁上一次的实例。一般情况,全局有一个就行了,太多占用内存,而且没必要。
  330.          * @param adUid 广告UID
  331.          * @param location 位置有两种情况:1、可以传入枚举值,默认上方; 2、可以自定义位置传入IPosition,注意IPosition中的top和left跟平台的top,left是一致(没有乘以设备像素比ratio),需要开发者自己调试位置
  332.          * @param scale 默认为跟屏幕一样的宽度,可以通过设置缩放比例来调整大小。当然,平台有规定最大或最小宽度,函数内部会自动计算。
  333.          */
  334.         public loadBanner(adUid: string, location: EAdBannerLocation | IPosition = EAdBannerLocation.TOP, scale: number = 1.0) {
  335.             this._banner?.destroy();
  336.             let size: ISize = getSysWinSize();
  337.             // 当 style.width 小于 300 时,会取作 300。 当 style.width 大于屏幕宽度时,会取作屏幕宽度。
  338.             let width = size.width * scale;
  339.             width = width < 300 ? 300 : width; // 最小值矫正
  340.             width = width > size.width ? size.width : width; //最大值矫正
  341.             this._banner = typeof location === 'number' ? new ADBanner(adUid, location === EAdBannerLocation.TOP, width, false) : new ADBanner(adUid, location, width, false);
  342.         }
  343.         /**
  344.          * 显示横幅广告
  345.          */
  346.         public showBanner() {
  347.             if (this._banner) {
  348.                 this._banner.show();
  349.             } else {
  350.                 console.warn('MiniGameSDK: banner is null, you must call loadBanner(...) first!');
  351.             }
  352.         }
  353.         /**
  354.          * 隐藏横幅广告
  355.          */
  356.         public hideBanner() {
  357.             this._banner?.hide();
  358.         }
  359.         /**
  360.          * 弹出插屏广告
  361.          * @param adUid 广告单元id
  362.          */
  363.         public showInterstitial(adUid: string) {
  364.             if (this._interstitial && this._interstitial.aduid === adUid) {
  365.                 this._interstitial.show();
  366.             } else {
  367.                 this._interstitial?.destory();
  368.                 this._interstitial = new ADInterstitial(adUid);
  369.                 this._interstitial.show();
  370.             }
  371.         }
  372.         /**
  373.          * 加载原生模板广告,不会显示。只有你在调用showCustom时才会显示。
  374.          * 由于原生模板广告在微信服务后端可以定制宽度大小,个数,缩放比例等,所以位置调整要根据设置的宽度来定。抖音不支持本函数,会调用无效!
  375.          * @param adUid 广告ID
  376.          * @param location 位置有两种情况:1、可以传入枚举值,默认上方; 2、可以自定义位置传入IPosition,注意IPosition中的top和left跟平台的top,left是一致(没有乘以设备像素比ratio),需要开发者自己调试位置
  377.          * @param scale 缩放比例,默认是1,即不缩放。这个缩放并不是自己填,而是根据微信MP后台你配置的原生模板广告的缩放比例填,目前有100%,90%,80%三种,一般情况不用修改。若有后台修改,记得传入值,例如90%就传入0.9。
  378.          */
  379.         public loadCustom(adUid: string, location: IPosition = { top: 0, left: 0 }, scale: number = 1) {
  380.             // this._custom?.destroy();
  381.             // this._custom = new ADCustom(adUid, location.top, location.left, scale);
  382.             if (this._customs[adUid]) {
  383.                 console.log(`${adUid} has been loaded.`);
  384.                 return;
  385.             }
  386.             this._customs[adUid] = new ADCustom(adUid, location.top, location.left, scale);
  387.         }
  388.         /**
  389.          * 显示自定义广告。
  390.          * @param adUid 广告的唯一标识符。使用此标识符来查找和显示特定的自定义广告。
  391.          *
  392.          * 此方法尝试根据提供的adUid显示一个自定义广告。如果给定的adUid对应的自定义广告已加载,
  393.          * 则调用该广告的显示方法。如果广告未加载,则在控制台输出警告信息。
  394.          */
  395.         public showCustom(adUid: string) {
  396.             if (this._customs[adUid]) {
  397.                 this._customs[adUid].show();
  398.             } else {
  399.                 console.warn(`You have not load ${adUid} of Custom AD, can not show!`);
  400.             }
  401.         }
  402.         /**
  403.          * 隐藏指定的自定义广告单元
  404.          *
  405.          * 此方法用于隐藏通过广告单元标识符(adUid)指定的自定义广告。如果指定的广告单元已加载并显示,
  406.          * 则将其隐藏;如果广告单元未加载,则在控制台输出警告信息。
  407.          *
  408.          * @param adUid 广告单元标识符,用于唯一标识一个自定义广告单元。
  409.          */
  410.         public hideCustom(adUid: string) {
  411.             if (this._customs[adUid]) {
  412.                 this._customs[adUid].hide();
  413.             } else {
  414.                 console.warn(`You have not load ${adUid} of Custom AD, can not hide!`);
  415.             }
  416.         }
  417.         /**
  418.          * 由于微信和抖音视频广告机制不同,微信可以看的视频广告个数只有0和1个,抖音平台则可以看0~maxVideoCount
  419.          * @param adUid 广告ID。如果与上一次UID不同,则内部会重新创建实例。开发者完全不用关心这个细节。
  420.          * @param onVideoResult 两个参数:第一个res是EAdVideoResult定义,第二count是用户看了多少个视频广告。
  421.          * @param target onVideoResult的拥有者
  422.          * @param maxVideoCount 最大视频个数。默认是3,仅对抖音平台生效。微信平台看完视频count的结果永远是1或0
  423.          */
  424.         public showVideo(adUid: string, onVideoResult: (res: EAdVideoResult, count: number) => void, target?: any, maxVideoCount: number = 3) {
  425.             
  426.             
  427.             
  428.             if (this._video && this._video.aduid === adUid) {
  429.                 console.info('show','进来了');
  430.                 this._video.show(onVideoResult, target, maxVideoCount);
  431.             } else {
  432.                 this._video?.destory();
  433.                 this._video = new ADVideo(adUid);
  434.                 this._video.show(onVideoResult, target, maxVideoCount);
  435.             }
  436.         }
  437.         /**
  438.          * 销毁内部所有实例,清空内存
  439.          */
  440.         public destroyAll() {
  441.             this._banner?.destroy();
  442.             this._banner = null;
  443.             this._interstitial?.destory();
  444.             this._interstitial = null;
  445.             this._video?.destory();
  446.             this._video = null;
  447.             if (this._customs) {
  448.                 for (let val in this._customs) {
  449.                     this._customs[val]?.destroy();
  450.                 }
  451.                 this._customs = {};
  452.             }
  453.         }
  454.     }
  455.     export enum EGameClubIcon {
  456.         /** 绿色图标 */
  457.         GREEN = 'green',
  458.         /** 红色图标 */
  459.         WHITE = 'white',
  460.         /** 有黑色圆角背景的白色图标 */
  461.         DARK = 'dark',
  462.         /** 有白色圆角背景的绿色图标 */
  463.         LIGHT = 'light'
  464.     }
  465.     export class GameClub {
  466.         private static _instance: GameClub;
  467.         static get instance(): GameClub {
  468.             if (!this._instance) {
  469.                 this._instance = new GameClub();
  470.             }
  471.             return this._instance;
  472.         }
  473.         private _club: any;
  474.         private constructor() {
  475.         }
  476.         /**
  477.          * 创建游戏圈按钮
  478.          * @param icon
  479.          * @param position
  480.          * @param size
  481.          * @param openLink
  482.          */
  483.         create(icon: EGameClubIcon = EGameClubIcon.GREEN, position: IPosition = { top: 0, left: 0 }, size: ISize = { width: 40, height: 40 }, openLink?: string) {
  484.             if (isWechat()) {
  485.                 // @ts-ignore
  486.                 this._club = wx.createGameClubButton({
  487.                     icon: icon,
  488.                     style: {
  489.                         left: position.left,
  490.                         top: position.top,
  491.                         width: size.width,
  492.                         height: size.height
  493.                     },
  494.                     openlink: openLink
  495.                 });
  496.             }
  497.         }
  498.         show() {
  499.             this._club?.show();
  500.         }
  501.         hide() {
  502.             this._club?.hide();
  503.         }
  504.         destory() {
  505.             this._club?.destroy();
  506.         }
  507.     }
  508.     /**
  509.      * 振动类型
  510.      */
  511.     export enum EVirbrateType {
  512.         /**
  513.          * 短振动
  514.          */
  515.         SHORT,
  516.         /**
  517.          * 长振动
  518.          */
  519.         LONG
  520.     }
  521.     /**
  522.      * 平台常用API合集
  523.      */
  524.     export class API {
  525.         private static _loginCode: string = null;
  526.         private static _loginAnonymousCode: string = null;
  527.         private static _hasInitWechatCloudFunction: boolean = false;
  528.         /**
  529.          * 分享app给朋友,微信小游戏分享是没有onSuccess回调的。
  530.          * @param title 标题
  531.          * @param description 细节描述信息
  532.          * @param imageUrl 图片地址
  533.          * @param query 查询信息
  534.          * @param onSuccess 抖音会回调,微信不会回调
  535.          */
  536.         static shareAppToFriends(title: string, description: string = '', imageUrl?: string, query?: string, onSuccess?: () => void) {
  537.             if (isWechat()) {
  538.                 try {
  539.                     //@ts-ignore
  540.                     wx.shareAppMessage({
  541.                         title: title,
  542.                         imageUrl: imageUrl,
  543.                         query: query,
  544.                     });
  545.                 } catch (err) {
  546.                     console.log(`share faild: ${err}`);
  547.                 }
  548.             }
  549.             if (isBytedance()) {
  550.                 //@ts-ignore
  551.                 console.info('字节分享方法');
  552.                 tt.shareAppMessage({
  553.                     title: title,
  554.                     desc: description,
  555.                     imageUrl: imageUrl ?? '',
  556.                     query: query ?? '',
  557.                     success(res: any) {
  558.                         console.log('share success:', res);
  559.                         onSuccess?.();
  560.                     },
  561.                     fail(res: any) {
  562.                         console.log('share fail:', res);
  563.                     }
  564.                 });
  565.             }
  566.         }
  567.         /**
  568.          * 显示提示信息
  569.          * @param title 标题
  570.          * @param duration 时长(单位:秒)
  571.          * @returns
  572.          */
  573.         static showToast(title: string, duration: number = 2) {
  574.             if (isWechat()) {
  575.                 // @ts-ignore
  576.                 wx.showToast({
  577.                     title: title,
  578.                     icon: 'success',
  579.                     duration: duration * 1000
  580.                 });
  581.             }
  582.             if (isBytedance()) {
  583.                 //@ts-ignore
  584.                 tt.showToast({
  585.                     title: title,
  586.                     duration: duration * 1000,
  587.                     success(res: any) {
  588.                         console.log(`${res}`);
  589.                     },
  590.                     fail(res: any) {
  591.                         console.log(`showToast调用失败`);
  592.                     },
  593.                 });
  594.             }
  595.         }
  596.         /**
  597.          * 设备震动效果,默认为短震动。注意:可能一些机型不会生效,具体看平台方的说明
  598.          * @param type MiniGameSdk.API.EVirbrateType
  599.          */
  600.         static vibrate(type: EVirbrateType = EVirbrateType.SHORT) {
  601.             if (isWechat()) {
  602.                 switch (type) {
  603.                     case EVirbrateType.SHORT:
  604.                         //@ts-ignore
  605.                         wx.vibrateShort({
  606.                             success(res: any) {
  607.                                 console.log('vibrate success:', res);
  608.                             },
  609.                             fail(res: any) {
  610.                                 console.log('vibrateShort failed', res);
  611.                             },
  612.                         });
  613.                         break;
  614.                     case EVirbrateType.LONG:
  615.                         //@ts-ignore
  616.                         wx.vibrateLong({
  617.                             success(res: any) {
  618.                                 console.log('vibrate success', res);
  619.                             },
  620.                             fail(res: any) {
  621.                                 console.log(`vibrateLong failed`, res);
  622.                             },
  623.                         });
  624.                         break;
  625.                     default:
  626.                         break;
  627.                 }
  628.             }
  629.             if (isBytedance()) {
  630.                 switch (type) {
  631.                     case EVirbrateType.SHORT:
  632.                         //@ts-ignore
  633.                         tt.vibrateShort({
  634.                             success(res: any) {
  635.                                 console.log('vibrate success:', res);
  636.                             },
  637.                             fail(res: any) {
  638.                                 console.log('vibrateShort failed', res);
  639.                             },
  640.                         });
  641.                         break;
  642.                     case EVirbrateType.LONG:
  643.                         //@ts-ignore
  644.                         tt.vibrateLong({
  645.                             success(res: any) {
  646.                                 console.log('vibrate success', res);
  647.                             },
  648.                             fail(res: any) {
  649.                                 console.log(`vibrateLong failed`, res);
  650.                             },
  651.                         });
  652.                         break;
  653.                     default:
  654.                         break;
  655.                 }
  656.             }
  657.         }
  658.         /**
  659.          * 重启小游戏
  660.          */
  661.         static reboot() {
  662.             if (isWechat()) {
  663.                 //@ts-ignore
  664.                 wx.restartMiniProgram({
  665.                     success: () => {
  666.                         console.log('restart success');
  667.                     },
  668.                     fail: () => {
  669.                         console.log('restart failed');
  670.                     }
  671.                 })
  672.             }
  673.             if (isBytedance()) {
  674.                 try {
  675.                     // @ts-ignore
  676.                     tt.restartMiniProgramSync();
  677.                 } catch (error) {
  678.                     console.log(`restartMiniProgramSync`, error);
  679.                 }
  680.             }
  681.         }
  682.         /**
  683.          * 退出小游戏
  684.          */
  685.         static exit() {
  686.             if (isWechat()) {
  687.                 //@ts-ignore
  688.                 wx.exitMiniProgram({
  689.                     success: () => {
  690.                         console.log('exit success');
  691.                     },
  692.                     fail: () => {
  693.                         console.log('exit failed');
  694.                     }
  695.                 });
  696.             }
  697.             if (isBytedance()) {
  698.                 // @ts-ignore
  699.                 tt.exitMiniProgram({
  700.                     success(res: any) {
  701.                         console.log("exit success:", res?.data);
  702.                     },
  703.                     fail(res: any) {
  704.                         console.log("exit fail:", res?.errMsg);
  705.                     },
  706.                 });
  707.             }
  708.         }
  709.         /**
  710.          * 显示转发按钮。通常在刚进入游戏的时候调用。
  711.          * 主要是打开平台“...”这个按钮里面的分享菜单,一般默认是关闭的,需要调用这个函数打开。可以让用户分享你的游戏入口。
  712.          */
  713.         static showShareMenu() {
  714.             if (isWechat()) {
  715.                 //@ts-ignore
  716.                 wx.showShareMenu({
  717.                     withShareTicket: true,
  718.                     menus: ['shareAppMessage', 'shareTimeline'],
  719.                     success: () => { },
  720.                     fail: () => { },
  721.                     complete: () => { }
  722.                 });
  723.             }
  724.             if (isBytedance()) {
  725.                 //@ts-ignore
  726.                 tt.showShareMenu({
  727.                     success(res: any) {
  728.                         console.log("show menu is showing");
  729.                     },
  730.                     fail(err: any) {
  731.                         console.log("showShareMenu:", err.errMsg);
  732.                     },
  733.                     complete(res: any) {
  734.                         console.log("showShareMenu complete");
  735.                     },
  736.                 });
  737.             }
  738.         }
  739.         /**
  740.          * 微信小游戏:跳转到另外一款小游戏
  741.          * 抖音小游戏:跳转到指定的视频界面
  742.          * @param targetId 微信小游戏appid或者视频界面
  743.          */
  744.         static navigateTo(targetId: string, onSuccess?: () => void) {
  745.             if (isWechat()) {
  746.                 // @ts-ignore
  747.                 wx.navigateToMiniProgram({
  748.                     appId: targetId,
  749.                     extraData: {
  750.                         foo: 'bar'
  751.                     },
  752.                     envVersion: 'develop',
  753.                     success(res: any) {
  754.                         onSuccess?.();
  755.                     }
  756.                 });
  757.             }
  758.             if (isBytedance()) {
  759.                 // @ts-ignore
  760.                 tt.navigateToVideoView({
  761.                     videoId: targetId,
  762.                     success: (res: any) => {
  763.                         onSuccess?.();
  764.                     },
  765.                     fail: (err: any) => {
  766.                         console.log("bytedance navigateToVideoView fail", err);
  767.                     },
  768.                 });
  769.             }
  770.         }
  771.         /**
  772.          * 小游戏平台登录功能。微信返回code,抖音返回code和anonymousCode。用于登录的凭证,需要把这个code传回你的服务器程序中去调用code2Session
  773.          * @param callback (code, anonymousCode) 第一个参数为code,微信和抖音都支持;第二个参数为匿名设备ID,仅抖音支持,失败都返回null
  774.          */
  775.         static login(callback: (code: string, anonymousCode: string) => void) {
  776.             let loginPlatform = () => {
  777.                 if (isWechat()) {
  778.                     //@ts-ignore
  779.                     wx.login({
  780.                         success: (res: { code: any; errMsg: any; }) => {
  781.                             if (res.code) {
  782.                                 API._loginCode = res.code;
  783.                                 API._loginAnonymousCode = null;
  784.                                 callback?.(API._loginCode, API._loginAnonymousCode);
  785.                             } else {
  786.                                 console.log('login error:', res.errMsg)
  787.                             }
  788.                         },
  789.                         fail: () => {
  790.                             API._loginCode = null;
  791.                             API._loginAnonymousCode = null;
  792.                             callback?.(API._loginCode, API._loginAnonymousCode);
  793.                             console.log('login fail')
  794.                         }
  795.                     });
  796.                 } else if (isBytedance()) {
  797.                     //@ts-ignore
  798.                     tt.login({
  799.                         force: true,
  800.                         success(res: any) {
  801.                             console.log(`login ${res.code} ${res.anonymousCode}`);
  802.                             if (res.code) {
  803.                                 API._loginCode = res.code?.toString();
  804.                                 API._loginAnonymousCode = res.anonymousCode?.toString();
  805.                                 callback?.(API._loginCode, API._loginAnonymousCode);
  806.                             } else {
  807.                                 console.log('login error:', res.errMsg)
  808.                             }
  809.                         },
  810.                         fail(res: any) {
  811.                             API._loginCode = null;
  812.                             API._loginAnonymousCode = null;
  813.                             callback?.(API._loginCode, API._loginAnonymousCode);
  814.                             console.log(`login fail`, res);
  815.                         },
  816.                     });
  817.                 } else {
  818.                     API._loginCode = null;
  819.                     API._loginAnonymousCode = null;
  820.                     callback?.(API._loginCode, API._loginAnonymousCode);
  821.                     console.log('not mini game platform, login codes are all null');
  822.                 }
  823.             }
  824.             if (!API._loginCode) {
  825.                 loginPlatform();
  826.             } else {
  827.                 if (isWechat()) {
  828.                     //@ts-ignore
  829.                     wx.checkSession({
  830.                         success() {
  831.                             console.log(`session is valid, use current code:`, API._loginCode);
  832.                             callback?.(API._loginCode, API._loginAnonymousCode);
  833.                         },
  834.                         fail() {
  835.                             console.log(`session expired`);
  836.                             loginPlatform();
  837.                         }
  838.                     });
  839.                 } else if (isBytedance()) {
  840.                     //@ts-ignore
  841.                     tt.checkSession({
  842.                         success() {
  843.                             console.log(`session is valid, user current code: ${API._loginCode}, ${API._loginAnonymousCode}`);
  844.                             callback?.(API._loginCode, API._loginAnonymousCode);
  845.                         },
  846.                         fail() {
  847.                             console.log(`session expired`);
  848.                             loginPlatform();
  849.                         },
  850.                     });
  851.                 } else {
  852.                     console.log('not mini game platform, login null');
  853.                     callback?.(null, null);
  854.                 }
  855.             }
  856.         }
  857.         /**
  858.          * 调用微信云函数。由于参数需要自定义,所以为any,需要自行解释。函数只完成通道和处理一场的作用
  859.          * @param callback 返回云函数调用结果。需要检查返回参数是否为空,失败的时候为空
  860.          * @param name 云函数的名字
  861.          * @param data 云函数的内容
  862.          */
  863.         static callWechatCloudFunction(callback: (res: any) => void, name: string, data: {}) {
  864.             if (!isWechat()) {
  865.                 console.log('Not wechat platform, not support callWechatCloudFunction');
  866.                 return;
  867.             }
  868.             this.login((code: string, anonymousCode: string) => {
  869.                 if (!API._hasInitWechatCloudFunction) {
  870.                     //@ts-ignore
  871.                     wx.cloud.init();
  872.                     API._hasInitWechatCloudFunction = true;
  873.                 }
  874.                 //@ts-ignore
  875.                 wx.cloud.callFunction({
  876.                     name: name,
  877.                     data: data,
  878.                     success: (res: any) => callback?.(res),
  879.                     fail: (err: any) => {
  880.                         console.log('wechat cloud function error:', err);
  881.                         callback?.(null);
  882.                     }
  883.                 });
  884.             });
  885.         }
  886.         /**
  887.          * 存储用户信息,数据量不能大。可以考虑用于分数排行榜。用户之间可共享排行数据。
  888.          * @param key
  889.          * @param value
  890.          */
  891.         static setUserCloudStorage(key: string, value: string) {
  892.             if (isWechat()) {
  893.                 // @ts-ignore
  894.                 wx.setUserCloudStorage({
  895.                     KVDataList: [{ key: key, value: value }],
  896.                     success: () => console.log(`set cloud storage success:${key}, value:${value}`),
  897.                     fail: (err: any) => console.log('set cloud storage error:', err)
  898.                 });
  899.             }
  900.             if (isBytedance()) {
  901.                 // @ts-ignore
  902.                 tt.setUserCloudStorage({
  903.                     KVDataList: [{ key: key, value: value, }],
  904.                     success: () => console.log(`set cloud storage success:${key}, value:${value}`),
  905.                     fail: (err: any) => console.log('set cloud storage error:', err)
  906.                 });
  907.             }
  908.         }
  909.     }
  910.     /**
  911.      * 抖音侧边栏专属接口
  912.      */
  913.     export class BytedanceSidebar {
  914.         /**
  915.          * 本游戏在抖音环境下启动监控,需要放在全局环境中,保证能第一时间启动。因为可能监听抖音失败(抖音小游戏官方的说明)!
  916.          * @param onResult 包含一个boolean参数的函数
  917.          * @param target 上述函数的拥有者,如果是类的成员函数,需要传入this。普通或匿名函数忽略即可。
  918.          */
  919.         static listenFromSidebar(onResult: (success: boolean) => void, target?: any) {
  920.             if (!isBytedance()) {
  921.                 onResult?.call(target, false);
  922.                 return;
  923.             }
  924.             // @ts-ignore
  925.             tt.onShow((res: any) => {
  926.                 console.log('onShow launch res:', res);
  927.                 if (res.scene === '021036') {
  928.                     onResult?.call(target, true);
  929.                     console.log('launch from sidebar');
  930.                 } else {
  931.                     onResult?.call(target, false);
  932.                     console.log('NOT launch from douyin sidebar!');
  933.                 }
  934.             });
  935.             // @ts-ignore
  936.             let options = tt.getLaunchOptionsSync();
  937.             if (options && options.scene === '021036') {
  938.                 onResult?.call(target, true);
  939.             }
  940.         }
  941.         /**
  942.          * 检测抖音侧边栏是否存在
  943.          * @param onResult 包含一个boolean参数的函数
  944.          * @param target 上述函数的拥有者,如果是类的成员函数,需要传入this。普通或匿名函数忽略即可。
  945.          * @returns
  946.          */
  947.         static checkSideBar(onResult: (success: boolean) => void, target?: any) {
  948.             if (!isBytedance()) {
  949.                 onResult?.call(target, false);
  950.                 return;
  951.             }
  952.             //@ts-ignore
  953.             tt.checkScene({
  954.                 scene: "sidebar",
  955.                 success: (res: any) => {
  956.                     console.log("check scene success: ", res.isExist);
  957.                     onResult?.call(target, <boolean>res.isExist);
  958.                 },
  959.                 fail: (res: any) => {
  960.                     console.log("check scene fail:", res);
  961.                     onResult?.call(target, false);
  962.                 }
  963.             });
  964.         }
  965.         /**
  966.          * 跳转到抖音侧边栏
  967.          * @param onResult 包含一个boolean参数的函数
  968.          * @param target 上述函数的拥有者,如果是类的成员函数,需要传入this。普通或匿名函数忽略即可。
  969.          * @returns
  970.          */
  971.         static navigateToSidebar(onResult: (success: boolean) => void, target?: any) {
  972.             if (!isBytedance()) {
  973.                 console.log("not douyin platform!");
  974.                 onResult?.call(target, false);
  975.                 return;
  976.             }
  977.             // @ts-ignore
  978.             tt.navigateToScene({
  979.                 scene: "sidebar",
  980.                 success: () => {
  981.                     console.log("navigate success");
  982.                     onResult?.call(target, true);
  983.                 },
  984.                 fail: (res: any) => {
  985.                     console.log("navigate failed reason:", res);
  986.                     onResult?.call(target, false);
  987.                 },
  988.             });
  989.         }
  990.     }
  991. }
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表