消消方块阵换皮表情
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

163 lines
5.3 KiB

import { MiniGamePlatform } from '../platform/MiniGamePlatform';
/**
* 激励视频广告(微信 / 抖音 / 快手 / B 站 / OPPO / QQ)。
*
* 官方要点:
* - 先 onLoad/onError/onClose,再 load/show(抖音)
* - 微信/快手:全局单例,show 失败时 load→show(微信文档)
* - B 站:show 前 reportScene(1007)
* - onClose 仅以 isEnded 判定奖励(快手);微信兼容 res===undefined
*/
export class RewardedVideoAd {
static keys: string[] = [];
private static _keyIndex = 0;
private static _errCount = 0;
private static _callback: Function | null = null;
/** 非单例平台当前实例 */
private static _ad: any = null;
private static _currentUnitId = '';
/** 微信/快手:adUnitId → 单例实例 */
private static _singletonAds = new Map<string, any>();
private static _eventsBound = new WeakSet<object>();
static init(keys: string[]) {
this.keys = keys ?? [];
MiniGamePlatform.init();
if (this.keys.length > 0 && MiniGamePlatform.pf?.createRewardedVideoAd) {
const ad = this._ensureAd(this.keys[0]);
ad?.load?.();
}
}
static show(callback?: Function) {
this._callback = callback ?? null;
this._errCount = 0;
const pf = MiniGamePlatform.pf;
if (!pf?.createRewardedVideoAd) {
this._finish(false);
return;
}
const adUnitId = this.keys[this._keyIndex];
if (!adUnitId) {
this._finish(false);
return;
}
const ad = this._ensureAd(adUnitId);
if (!ad) {
this._finish(false);
return;
}
this._ad = ad;
MiniGamePlatform.reportRewardedVideoScene();
this._showWithReload(ad);
}
private static _ensureAd(adUnitId: string): any {
const pf = MiniGamePlatform.pf;
if (!pf?.createRewardedVideoAd) return null;
if (MiniGamePlatform.isRewardedVideoAdSingleton()) {
let ad = this._singletonAds.get(adUnitId);
if (ad) return ad;
ad = pf.createRewardedVideoAd({ adUnitId });
if (!ad) return null;
this._bindEvents(ad);
this._singletonAds.set(adUnitId, ad);
return ad;
}
if (this._ad && this._currentUnitId === adUnitId) {
return this._ad;
}
if (this._ad) {
this._destroyAd(this._ad);
this._ad = null;
}
const ad = pf.createRewardedVideoAd({ adUnitId });
if (!ad) return null;
this._currentUnitId = adUnitId;
this._bindEvents(ad);
ad.load?.();
return ad;
}
/** 官方推荐:先注册监听,再 load/show */
private static _bindEvents(ad: any): void {
if (this._eventsBound.has(ad)) return;
this._eventsBound.add(ad);
ad.onLoad?.(() => {
console.log('[RewardedVideoAd] onLoad');
});
ad.onError?.((err: unknown) => {
console.log('[RewardedVideoAd] onError', err);
this._onLoadError();
});
ad.onClose?.((res?: { isEnded?: boolean }) => {
const ok = MiniGamePlatform.isRewardedVideoCompleted(res);
console.log('[RewardedVideoAd] onClose', res, 'completed=', ok);
this._finish(ok);
ad.load?.();
});
}
/** show 失败时 load→show(微信/快手/B站官方示例) */
private static _showWithReload(ad: any): void {
const showResult = ad.show?.();
if (!showResult?.then) return;
showResult.catch((err: unknown) => {
console.log('[RewardedVideoAd] show fail, load then show', err);
const loadResult = ad.load?.();
if (!loadResult?.then) {
ad.load?.();
return;
}
loadResult.then(() => ad.show?.()).catch((err2: unknown) => {
console.log('[RewardedVideoAd] load+show fail', err2);
this._onLoadError();
});
});
}
private static _onLoadError(): void {
this._errCount++;
if (this._errCount >= 5 || this.keys.length === 0) {
this._finish(false);
return;
}
const oldKey = this.keys[this._keyIndex];
this._keyIndex = (this._keyIndex + 1) % this.keys.length;
const newKey = this.keys[this._keyIndex];
if (MiniGamePlatform.isRewardedVideoAdSingleton()) {
this._singletonAds.delete(oldKey);
} else if (this._ad) {
this._destroyAd(this._ad);
this._ad = null;
this._currentUnitId = '';
}
const ad = this._ensureAd(newKey);
if (!ad) {
this._finish(false);
return;
}
this._ad = ad;
this._showWithReload(ad);
}
private static _destroyAd(ad: any): void {
if (!ad?.destroy || MiniGamePlatform.isRewardedVideoAdSingleton()) return;
try {
ad.destroy();
} catch (e) {
console.warn('[RewardedVideoAd] destroy failed', e);
}
this._eventsBound.delete(ad);
}
private static _finish(success: boolean): void {
const cb = this._callback;
this._callback = null;
if (cb) cb(success);
}
}