feat: 支持关卡配置分享
This commit is contained in:
167
assets/scripts/utils/ShareManager.ts
Normal file
167
assets/scripts/utils/ShareManager.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
import { SpriteFrame, Texture2D, ImageAsset, assetManager } from 'cc';
|
||||
import { HttpUtil } from './HttpUtil';
|
||||
import { WxSDK } from './WxSDK';
|
||||
import { API_ENDPOINTS, getShareJoinUrl, API_TIMEOUT } from '../config/ApiConfig';
|
||||
import { ApiEnvelope, CreateShareData, JoinShareData, ShareLevelData } from '../types/ApiTypes';
|
||||
import { RuntimeLevelConfig } from '../types/LevelTypes';
|
||||
|
||||
/**
|
||||
* 分享管理器
|
||||
* 负责创建分享、加入分享、缓存分享关卡数据
|
||||
*/
|
||||
export class ShareManager {
|
||||
private static _instance: ShareManager | null = null;
|
||||
|
||||
/** 分享模式的关卡数据(null 表示正常模式) */
|
||||
private _shareLevels: RuntimeLevelConfig[] | null = null;
|
||||
|
||||
/** API 返回的原始关卡数据(保留 imageUrl 用于懒加载) */
|
||||
private _shareApiLevels: ShareLevelData[] = [];
|
||||
|
||||
private _shareTitle: string = '';
|
||||
private _shareCode: string | null = null;
|
||||
|
||||
/** 图片缓存:URL -> SpriteFrame */
|
||||
private _imageCache: Map<string, SpriteFrame> = new Map();
|
||||
|
||||
static get instance(): ShareManager {
|
||||
if (!this._instance) {
|
||||
this._instance = new ShareManager();
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
private constructor() {}
|
||||
|
||||
get isShareMode(): boolean {
|
||||
return this._shareLevels !== null && this._shareLevels.length > 0;
|
||||
}
|
||||
|
||||
async createShare(title: string, levelIds: string[]): Promise<string | null> {
|
||||
try {
|
||||
const response = await HttpUtil.post<ApiEnvelope<CreateShareData>>(
|
||||
API_ENDPOINTS.SHARE_CREATE,
|
||||
{ title, levelIds },
|
||||
API_TIMEOUT.DEFAULT,
|
||||
);
|
||||
|
||||
if (!response.success || !response.data) {
|
||||
console.error('[ShareManager] 创建分享失败:', response.message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return response.data.shareCode;
|
||||
} catch (err) {
|
||||
console.error('[ShareManager] 创建分享异常:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async joinShare(code: string): Promise<boolean> {
|
||||
try {
|
||||
const response = await HttpUtil.post<ApiEnvelope<JoinShareData>>(
|
||||
getShareJoinUrl(code),
|
||||
{},
|
||||
API_TIMEOUT.DEFAULT,
|
||||
);
|
||||
|
||||
if (!response.success || !response.data) {
|
||||
console.error('[ShareManager] 加入分享失败:', response.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
const { shareCode, title, levels } = response.data;
|
||||
this._shareCode = shareCode;
|
||||
this._shareTitle = title;
|
||||
this._shareApiLevels = levels;
|
||||
|
||||
const runtimeLevels: RuntimeLevelConfig[] = levels.map((level) => ({
|
||||
id: level.id,
|
||||
name: `第${level.level}关`,
|
||||
spriteFrame: null,
|
||||
clue1: level.hint1,
|
||||
clue2: level.hint2,
|
||||
clue3: level.hint3,
|
||||
answer: level.answer,
|
||||
}));
|
||||
|
||||
// 预加载首关图片
|
||||
if (levels.length > 0) {
|
||||
const sf = await this._loadImage(levels[0].imageUrl);
|
||||
if (sf) {
|
||||
runtimeLevels[0].spriteFrame = sf;
|
||||
}
|
||||
}
|
||||
|
||||
this._shareLevels = runtimeLevels;
|
||||
console.log(`[ShareManager] 加入分享成功: ${title}, ${levels.length} 关`);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error('[ShareManager] 加入分享异常:', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async ensureShareLevelReady(index: number): Promise<RuntimeLevelConfig | null> {
|
||||
if (!this._shareLevels || index < 0 || index >= this._shareLevels.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const config = this._shareLevels[index];
|
||||
if (config.spriteFrame) {
|
||||
return config;
|
||||
}
|
||||
|
||||
const apiLevel = this._shareApiLevels[index];
|
||||
if (apiLevel?.imageUrl) {
|
||||
const sf = await this._loadImage(apiLevel.imageUrl);
|
||||
if (sf) {
|
||||
config.spriteFrame = sf;
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
getShareLevelCount(): number {
|
||||
return this._shareLevels?.length ?? 0;
|
||||
}
|
||||
|
||||
triggerWxShare(title: string, shareCode: string): void {
|
||||
WxSDK.shareAppMessage({
|
||||
title: title || '来挑战我出的谐音梗吧!',
|
||||
query: `shareCode=${shareCode}`,
|
||||
});
|
||||
}
|
||||
|
||||
clearShareMode(): void {
|
||||
this._shareLevels = null;
|
||||
this._shareApiLevels = [];
|
||||
this._shareTitle = '';
|
||||
this._shareCode = null;
|
||||
this._imageCache.clear();
|
||||
}
|
||||
|
||||
private _loadImage(url: string): Promise<SpriteFrame | null> {
|
||||
const cached = this._imageCache.get(url);
|
||||
if (cached) {
|
||||
return Promise.resolve(cached);
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
assetManager.loadRemote<ImageAsset>(url, (err, imageAsset) => {
|
||||
if (err) {
|
||||
console.error('[ShareManager] 加载图片失败:', url, err);
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
const texture = new Texture2D();
|
||||
texture.image = imageAsset;
|
||||
const spriteFrame = new SpriteFrame();
|
||||
spriteFrame.texture = texture;
|
||||
this._imageCache.set(url, spriteFrame);
|
||||
resolve(spriteFrame);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user