wxApi.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. // import { EQAPPKEY, EQVERSION, EQAUTH } from '../../../../sdk/eqconf.js';
  2. // import "../../../../sdk/eq.js";
  3. import { Rect, sys, Node, BlockInputEvents, macro, Vec2 } from "cc";
  4. import { MiniGameApiBase, getUserInfoParams, toastParams, loadParams, ModalParams, authorizeParams, loginParams, recordedGameScreenParams } from "./MiniGameApiBase";
  5. import { LayerMgr } from "../Manager/LayerMgr";
  6. import { GameCfg } from "../Config/GameCfg";
  7. export interface WxVideoAd {
  8. // 通过 load 方法主动预加载广告内容。
  9. // 此外,在显示广告出现问题时也可以尝试主动 load 一次。
  10. // 该方法返回一个 Promise,如果广告已经自动拉取成功,调用该方法返回一个 resolved Promise;
  11. load: () => Promise<any>;
  12. // 广告创建后默认是隐藏的,可以通过该方法显示广告。 该方法返回一个 Promise 对象。当广告组件正常获取素材时,该 Promise 对象会是一个 resolved Promise。当广告组件发生错误时,会是一个 rejected Promise,参数与error事件监听器获得的参数相同。
  13. show: () => Promise<any>;
  14. //绑定 load 事件的监听器,用户在手动调用 load 方法后,广告组件会预先加载。 广告组件成功拉取广告素材时会触发load事件的监听器。
  15. //确保监听此事件时,开发者主动调用过 load 方法。
  16. onLoad: (listener: Function) => void;
  17. // 解除绑定 load 事件的监听器。
  18. offLoad: (listener: Function) => void;
  19. //绑定 error 事件的监听器。 广告组件拉取广告素材和其他情况下如果发生错误,会触发error事件的监听器。监听器会获得一个包含errCode和errMsg属性的对象参数。
  20. // errCode 详情
  21. onError: (listener: (error: any) => void) => void;
  22. // 解除绑定 error 事件的监听器。
  23. offError: (listener: Function) => void;
  24. // 绑定 close 事件的监听器。 当用户点击了 Video 广告上的关闭按钮时,会触发close事件的监听器。监听器会获得一个包含isEnded属性的对象参数,表征用户是否完整观看了视频。
  25. onClose: (listener: (res: { isEnded: boolean }) => void) => void;
  26. //解除绑定 close 事件的监听器。
  27. offClose: (listener: Function) => void;
  28. //
  29. destroy(): () => void;
  30. }
  31. // export enum wx_VIDEO_TYPE {
  32. // general,
  33. // level_ulock,
  34. // get_power,
  35. // skin_unlock,
  36. // }
  37. const wx: any = window['wx'];
  38. export default class WxApi extends MiniGameApiBase {
  39. checkScene(successCB?: Function, errorCB?: Function) {
  40. console.log("Method not implemented.");
  41. }
  42. navigateToScene(successCB?: Function, errorCB?: Function) {
  43. console.log("Method not implemented.");
  44. }
  45. // protected m_AppId: string = "wx44456653566a7f94";
  46. protected m_AppId: string = "wx186d8263bd479a17";
  47. protected m_Secret: string = "";
  48. protected m_VideoAdIdIndex: number = 0;
  49. // protected m_VideoAdIdList: string[] = ["adunit-0120ab5292f6496a"];
  50. protected m_VideoAdIdList: string[] = ["adunit-3f18073324ae586f"];
  51. protected m_BannerAdIdIndex: number = 0;
  52. protected m_BannerAdId: string[] = [""];
  53. protected m_InsertAdIdIndex: number = 0;
  54. protected m_InsertAdId: string[] = [""];
  55. protected m_videoAd: WxVideoAd = undefined;
  56. protected m_BannerAd: any = undefined;
  57. /** 录屏管理器 */
  58. protected m_gameRecorder: any = null;
  59. validAppId(): void {
  60. console.log("wx-api-validAppId");
  61. }
  62. ready(): void {
  63. console.log("wx-api-ready");
  64. this.m_gameRecorder = wx.getGameRecorder();
  65. console.log('是否支持录制游戏画面', this.m_gameRecorder.isFrameSupported());
  66. // 目前还未实现,后期可能会支持到
  67. console.log('是否支持录制游戏画面的同时也录制音频', this.m_gameRecorder.isSoundSupported());
  68. }
  69. getUserInfo(params: getUserInfoParams): void {
  70. wx.getUserInfo(params);
  71. }
  72. showToast(params: toastParams): void {
  73. wx.showToast(params);
  74. }
  75. showLoading(params: loadParams): void {
  76. wx.showLoading(params);
  77. }
  78. hideLoading(): void {
  79. wx.hideLoading();
  80. }
  81. showModal(params: ModalParams): void {
  82. }
  83. authorize(params: authorizeParams): void {
  84. params.success && params.success();
  85. }
  86. login(params: loginParams): void {
  87. wx.login(params);
  88. }
  89. // vibrateShort(): void {
  90. // if (!gameConfig.VIDRATION_ENABLE) { return; }
  91. // wx.vibrateShort({
  92. // success: (errMsg) => {
  93. // console.log(errMsg);
  94. // },
  95. // fail: (errMsg) => {
  96. // console.log(errMsg);
  97. // },
  98. // complete: () => { }
  99. // });
  100. // }
  101. getVideoAdId(): string {
  102. const id: string = this.m_VideoAdIdList[this.m_VideoAdIdIndex];
  103. this.m_VideoAdIdIndex++;
  104. if (this.m_VideoAdIdIndex >= this.m_VideoAdIdList.length) {
  105. this.m_VideoAdIdIndex = 0;
  106. }
  107. return id;
  108. }
  109. private reportAnalyticsExplain: string = "null";
  110. loadAndShowVideoAd(successCB: () => void, errorCB: (error: any) => void, completeCB?: () => void, reportAnalyticsExplain?: string): void {
  111. if (this.reportAnalyticsExplain == reportAnalyticsExplain) {
  112. errorCB({ error: "重复播放视频" });
  113. completeCB && completeCB();
  114. return;
  115. }
  116. this.reportAnalyticsExplain = reportAnalyticsExplain;
  117. let videoAdId = this.getVideoAdId();
  118. if (this.m_videoAd == null) {
  119. this.m_videoAd = wx.createRewardedVideoAd({ adUnitId: videoAdId });
  120. }
  121. this.m_videoAd.load().then(() => {
  122. this.m_videoAd.show().then(() => { //播放视频广告完成
  123. }).catch((err) => { //播放视频广告错误
  124. // errorCB('视频显示错误 :' + JSON.stringify(err));
  125. this.m_videoAd.offClose(onClose);
  126. errorCB(err);
  127. completeCB && completeCB();
  128. console.error('视频显示错误', err);
  129. });
  130. });
  131. let onClose = (res) => {
  132. if (res && res.isEnded || res === undefined) {
  133. // 正常播放结束,可以下发游戏奖励
  134. successCB();
  135. console.debug('正常播放结束,可以下发游戏奖励');
  136. } else {
  137. // 播放中途退出,不下发游戏奖励
  138. errorCB('视频中途退出');
  139. console.error('视频中途退出');
  140. }
  141. this.m_videoAd.offClose(onClose);
  142. completeCB && completeCB();
  143. this.reportAnalyticsExplain = "null";
  144. };
  145. this.m_videoAd.onClose(onClose);
  146. this.m_videoAd.onError((err) => {
  147. this.m_videoAd.offClose(onClose);
  148. errorCB(err);
  149. completeCB && completeCB();
  150. console.error('视频错误', err);
  151. this.reportAnalyticsExplain = "null";
  152. });
  153. }
  154. getInsertAdId(): string {
  155. const id: string = this.m_InsertAdId[this.m_InsertAdIdIndex];
  156. this.m_InsertAdIdIndex++;
  157. if (this.m_InsertAdIdIndex >= this.m_InsertAdId.length) {
  158. this.m_InsertAdIdIndex = 0;
  159. }
  160. return id;
  161. }
  162. showInsertAd(onAdClose: () => void, onFailed: () => void): void {
  163. console.log("加载微信 插屏 广告");
  164. const adId = this.getInsertAdId();
  165. let insertAd = wx.createInterstitialAd({
  166. adUnitId: adId,
  167. });
  168. insertAd.load();
  169. insertAd.onLoad(() => {
  170. console.warn('插屏广告 加载完成');
  171. insertAd.show()
  172. .then(() => {
  173. })
  174. .catch((err) => {
  175. console.warn('插屏广告 显示失败 :' + JSON.stringify(err));
  176. insertAd.destroy();
  177. insertAd = null;
  178. if (onFailed) {
  179. onFailed();
  180. }
  181. });
  182. });
  183. insertAd.onError((err) => {
  184. console.warn('插屏广告 加载失败' + JSON.stringify(err));
  185. insertAd.destroy();
  186. insertAd = null;
  187. if (onFailed) {
  188. onFailed();
  189. }
  190. });
  191. insertAd.onClose(() => {
  192. console.warn('插屏广告 关闭');
  193. if (insertAd != null) {
  194. insertAd.destroy();
  195. insertAd = null;
  196. }
  197. if (onAdClose) {
  198. onAdClose();
  199. }
  200. });
  201. }
  202. protected isShowBanner: boolean = false;
  203. getBannerAdId(): string {
  204. const id: string = this.m_BannerAdId[this.m_BannerAdIdIndex];
  205. this.m_BannerAdIdIndex++;
  206. if (this.m_BannerAdIdIndex >= this.m_BannerAdId.length) {
  207. this.m_BannerAdIdIndex = 0;
  208. }
  209. return id;
  210. }
  211. protected screenSize: { screenWidth: number, screenHeight: number } = null;
  212. private getBannerType(type: number) {
  213. if (!this.screenSize) {
  214. const { screenWidth, screenHeight } = wx.getSystemInfoSync();
  215. this.screenSize = { screenWidth: screenWidth, screenHeight: screenHeight };
  216. }
  217. let rect: Rect = new Rect()
  218. switch (type) {
  219. case 0:
  220. default: {
  221. rect.width = 300;
  222. rect.height = 100;
  223. rect.x = (this.screenSize.screenWidth - rect.width) / 2;
  224. rect.y = this.screenSize.screenHeight - rect.height;
  225. break;
  226. }
  227. }
  228. return rect;
  229. }
  230. showBannerAD(node?: Node, successCB?: () => void, errorCB?: (error: any) => void, onCloseCB?: () => void, setBannerPos?: ({ screenWidth, screenHeight }) => Vec2): void {
  231. if (this.isShowBanner) {
  232. successCB && successCB();
  233. return;
  234. }
  235. if (this.m_BannerAd == null) {
  236. let rect = this.getBannerType(0);
  237. this.m_BannerAd = wx.createBannerAd({
  238. adUnitId: this.m_BannerAdId[0],
  239. adIntervals: 30,
  240. style: {
  241. top: rect.y,
  242. left: rect.x,
  243. width: rect.width,
  244. // height: rect.height,
  245. }
  246. });
  247. this.m_BannerAd.onError(err => {
  248. console.log("banner广告加载失败", JSON.stringify(err));
  249. errorCB && errorCB(err);
  250. this.isShowBanner = false;
  251. });
  252. this.m_BannerAd.onClose(() => {
  253. // onCloseCB && onCloseCB();
  254. });
  255. }
  256. this.m_BannerAd.show().then(() => {
  257. console.log('banner广告展示完成');
  258. successCB && successCB();
  259. this.isShowBanner = true;
  260. }).catch((err) => {
  261. console.log('banner广告展示失败', JSON.stringify(err));
  262. errorCB && errorCB(err);
  263. this.isShowBanner = false;
  264. });
  265. this.m_BannerAd.onResize((res) => {
  266. console.log("微信 banner >>> onResize :", JSON.stringify(res));
  267. });
  268. }
  269. hideBanner() {
  270. if (this.m_BannerAd != null) {
  271. this.m_BannerAd.hide();
  272. this.isShowBanner = false;
  273. }
  274. }
  275. destroyBanner() {
  276. if (this.m_BannerAd != null) {
  277. this.m_BannerAd.destroy();
  278. this.m_BannerAd = null;
  279. this.isShowBanner = false;
  280. }
  281. }
  282. addIcon(): void {
  283. wx.hasShortcutInstalled({
  284. success: (status) => {
  285. if (status) {
  286. console.log('已创建');
  287. // LayerMgr.instance.show("已添加成功");
  288. } else {
  289. console.log('未创建');
  290. wx.installShortcut({
  291. success: () => {
  292. console.log('创建成功');
  293. }
  294. });
  295. }
  296. }
  297. });
  298. }
  299. protected m_NativeAdId: string = "adunit-3ce3a5e5b209c3b0";
  300. protected m_NativeAd: any = null;
  301. loadAndShowNativeAd(success: () => void, fail?: () => void): void {
  302. if (!wx.createCustomAd) { return; }
  303. this.hideBanner();
  304. // this.hideHomeNative();
  305. const { screenWidth, screenHeight } = wx.getSystemInfoSync();
  306. let banTouchNode: Node = new Node();
  307. banTouchNode.addComponent(BlockInputEvents);
  308. // banTouchNode. = screenWidth;
  309. // banTouchNode.height = screenHeight;
  310. banTouchNode.setSiblingIndex(9999);
  311. this.m_NativeAd = wx.createCustomAd({
  312. adUnitId: this.m_NativeAdId,
  313. adIntervals: 30,
  314. style: {
  315. left: (screenWidth - 360 * 0.9) / 2,
  316. top: (screenHeight - 352 * 0.9) / 2,
  317. width: 360 * 0.9,
  318. fixed: true,
  319. },
  320. });
  321. this.m_NativeAd.onError(err => {
  322. console.log("原生模板广告加载失败", JSON.stringify(err));
  323. fail && fail();
  324. banTouchNode.destroy();
  325. this.showBannerAD();
  326. // this.loadAndShowHomeNativeAd();
  327. });
  328. this.m_NativeAd.onClose(() => {
  329. this.m_NativeAd = null;
  330. banTouchNode.destroy();
  331. this.showBannerAD();
  332. // this.loadAndShowHomeNativeAd();
  333. });
  334. this.m_NativeAd.show().then(() => {
  335. console.log('原生模板广告展示完成');
  336. success && success();
  337. }).catch((err) => {
  338. console.log('原生模板广告展示失败', JSON.stringify(err));
  339. });
  340. }
  341. hideNativeAd(): void {
  342. if (this.m_NativeAd) {
  343. this.m_NativeAd.hide();
  344. this.m_NativeAd.destroy();
  345. this.m_NativeAd = null;
  346. }
  347. }
  348. protected m_HomeNativeAdId: string = "adunit-d66dd70787191558";
  349. protected m_HomeNativeAd: any = null;
  350. loadAndShowHomeNativeAd(success?: () => void, fail?: () => void) {
  351. if (!wx.createCustomAd) { return; }
  352. const { screenWidth, screenHeight } = wx.getSystemInfoSync();
  353. if (this.m_HomeNativeAd != null && !this.m_HomeNativeAd.isShow()) {
  354. this.m_HomeNativeAd.show().then(() => {
  355. console.log('首页原生模板广告展示完成 have');
  356. success && success();
  357. this.hideBanner();
  358. }).catch((err) => {
  359. console.log('首页原生模板广告展示失败 have', JSON.stringify(err));
  360. });
  361. return;
  362. }
  363. this.m_HomeNativeAd = wx.createCustomAd({
  364. adUnitId: this.m_HomeNativeAdId,
  365. adIntervals: 30,
  366. style: {
  367. left: (screenWidth - 360 * 0.8) / 2,
  368. top: (screenHeight - 106 * 0.8),
  369. fixed: true,
  370. },
  371. });
  372. this.m_HomeNativeAd.onError(err => {
  373. console.log("首页原生模板广告加载失败", JSON.stringify(err));
  374. fail && fail();
  375. });
  376. this.m_HomeNativeAd.onClose(() => {
  377. this.m_HomeNativeAd = null;
  378. });
  379. this.m_HomeNativeAd.show().then(() => {
  380. console.log('首页原生模板广告展示完成');
  381. success && success();
  382. }).catch((err) => {
  383. console.log('首页原生模板广告展示失败', JSON.stringify(err));
  384. });
  385. }
  386. hideHomeNative() {
  387. if (this.m_HomeNativeAd) {
  388. this.m_HomeNativeAd.hide();
  389. }
  390. }
  391. updateAdTimeLimit(): void {
  392. }
  393. protected m_gameRecordDuration: number = 0;
  394. protected m_gameRecordError: { code: number, message: string } = null;
  395. recordedGameScreenStart(params: recordedGameScreenParams, onStart?: (res: any) => void): void {
  396. console.log("wx-api-recordedGameScreenStart");
  397. if (!this.m_gameRecorder.isFrameSupported()) {
  398. onStart && onStart(false);
  399. console.log("不能录制");
  400. return;
  401. }
  402. this.m_gameRecorder.start(params);
  403. let onStartFun = () => {
  404. onStart && onStart(null);
  405. console.log("已经开始录制了");
  406. }
  407. let onErrorFun = (res: { code: number, message: string }) => {
  408. this.m_gameRecordError = res;
  409. console.log("录制出错", JSON.stringify(res));
  410. }
  411. let onStopFun = (res: { duration: number }) => {
  412. this.m_gameRecordDuration = res.duration;
  413. this.m_gameRecorder.off("start", onStartFun);
  414. this.m_gameRecorder.off("stop", onStopFun);
  415. this.m_gameRecorder.off("error", onErrorFun);
  416. console.log("停止录制", JSON.stringify(res));
  417. }
  418. this.m_gameRecorder.on("start", onStartFun);
  419. this.m_gameRecorder.on("stop", onStopFun);
  420. this.m_gameRecorder.on("error", onErrorFun);
  421. }
  422. recordedGameScreenStop() { return true; }
  423. recordedGameScreenStop_WX(cb?: (bool: boolean) => void) {
  424. if (!this.m_gameRecorder.isFrameSupported()) {
  425. cb && cb(false);
  426. console.log("不能录制-stop");
  427. return;
  428. }
  429. this.m_gameRecorder.stop().that(() => {
  430. cb && cb(this.m_gameRecordDuration > 0);
  431. });
  432. }
  433. shareRecordedGameScreen(successCb?: () => void, failCb?: (e?: any) => void): void {
  434. console.log("wx-api-shareRecordedGameScreen");
  435. successCb && successCb();
  436. }
  437. isHaveRecordedGameScreen(): boolean {
  438. return true;
  439. }
  440. protected m_gameRecorderShareButton: any = null;
  441. createGameRecorderShareButton(cb?: () => void): void {
  442. if (!this.m_gameRecorder.isFrameSupported()) {
  443. cb && cb();
  444. console.log("不能录制-createGameRecorderShareButton");
  445. return;
  446. }
  447. if (this.m_gameRecorderShareButton == null) {
  448. this.m_gameRecorderShareButton = wx.createGameRecorderShareButton({
  449. // 样式参数
  450. style: {
  451. // left: 10,
  452. // top: 150,
  453. // height: 50,
  454. // color: '#ffffff',
  455. // textAlign: 'center',
  456. // fontSize: 16,
  457. // borderRadius: 4,
  458. // iconMarginRight: 16,
  459. // paddingLeft: 1,
  460. // paddingRight: 30,
  461. },
  462. // 按钮的背景图片
  463. // image: 'button.jpg',
  464. text: GameCfg.GAME_VIDEO_SHARE_DESC,
  465. // icon: 'icon.jpg',
  466. // 分享参数
  467. share: {
  468. // query: 'a=1&b=2',
  469. // 背景音乐的路径
  470. bgm: 'soundBundle/bgm.mp3',
  471. timeRange: [[0, 1000], [2000, 3000]],
  472. }
  473. });
  474. }
  475. this.m_gameRecorderShareButton.show();
  476. this.m_gameRecorderShareButton.onTap(() => {
  477. console.log("gameRecorderShareButton >>> onTap");
  478. cb && cb();
  479. });
  480. }
  481. recordeGameScreenAbort(): void {
  482. this.m_gameRecorder.abort();
  483. }
  484. getStorageSync(key?: string) {
  485. let data = null;
  486. data = sys.localStorage.getItem(key)
  487. return data
  488. }
  489. removeStorage(key?: string) {
  490. if (!key) {
  491. sys.localStorage.clear()
  492. } else {
  493. sys.localStorage.removeItem(key);
  494. }
  495. }
  496. getDeviceInfo() {
  497. wx.getSystemInfo({
  498. success: function (res) {
  499. console.log(res);
  500. return res.model
  501. },
  502. fail: function (res) {
  503. console.log("获取设备信息失败!")
  504. }
  505. })
  506. let str: string = navigator.userAgent
  507. let res: RegExpMatchArray = str.match(/ipad/i)
  508. console.log("userAgent: ", str)
  509. if (res) return "ipad"
  510. if (sys.isBrowser && sys.os == sys.OS.IOS) {
  511. res = str.match(/iphone/i)
  512. if (res) return "iphone"
  513. if (window.screen.height > window.screen.width) return "ipad"
  514. return "mac"
  515. }
  516. return "unknow"
  517. }
  518. setUnlockAllTime(time: number) {
  519. sys.localStorage.setItem("unit_unlock_all", time)
  520. }
  521. getUnlockAllTime(call: Function) {
  522. if (call)
  523. call(sys.localStorage.getItem("unit_unlock_all"))
  524. }
  525. setUnitState(state?: string) {
  526. sys.localStorage.setItem("unit_state", state)
  527. }
  528. setSoundInfo(sound?: boolean, music?: boolean) {
  529. sys.localStorage.setItem("sound", JSON.stringify({ sound: sound, music: music }))
  530. }
  531. onKeyboardConfirm(cb: (str: any) => void) {
  532. // throw new Error("Method not implemented.");
  533. }
  534. showShareMenu(successCb: () => any, failCb: (res: any) => void): void {
  535. // throw new Error("Method not implemented.");
  536. console.log('微信分享未实现')
  537. successCb && successCb();
  538. }
  539. protected m_IsLogin: boolean;
  540. vibrateLong(): void {
  541. throw new Error("Method not implemented.");
  542. }
  543. addShortcut(successCb: () => void, failCb: (res: any) => void): void {
  544. throw new Error("Method not implemented.");
  545. }
  546. reportAnalytics(name: any, data: any): void {
  547. // throw new Error("Method not implemented.");
  548. }
  549. public m_AdCnt: number;
  550. loadBannerAd() {
  551. }
  552. }