更新内存优化方案,更新获胜结算界面图和动画
This commit is contained in:
@@ -72,14 +72,30 @@ export class GameConfig {
|
||||
private static sceneLoadRequest = 0;
|
||||
private static cancelBlockLoading: () => void = null;
|
||||
|
||||
static getCurrentLevelBlockDefinitions(): any[] {
|
||||
const blocks = this.BLOCK_INFO && this.BLOCK_INFO[0] ? this.BLOCK_INFO[0] : [];
|
||||
const level: any = this.LEVEL_INFO && this.LEVEL_INFO[0];
|
||||
const result = blocks.slice();
|
||||
const gates = level && Array.isArray(level.spawnGates) ? level.spawnGates : [];
|
||||
for (const gate of gates) {
|
||||
const queue = gate && Array.isArray(gate.spawnQueue) ? gate.spawnQueue : [];
|
||||
for (const item of queue) {
|
||||
if (item && Array.isArray(item.members)) result.push(...item.members);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** 只准备当前关图片,不预读或加载下一关图片。 */
|
||||
static prepareBlockWindow(onRemoteRequired?: () => void, stage = "进关"): Promise<boolean> {
|
||||
const blocks = this.BLOCK_INFO && this.BLOCK_INFO[0];
|
||||
if (!blocks || !this.loadedLevelNumber) return Promise.reject(new Error("关卡配置尚未就绪"));
|
||||
const blockInfo = this.BLOCK_INFO && this.BLOCK_INFO[0];
|
||||
const levelInfo = this.LEVEL_INFO && this.LEVEL_INFO[0];
|
||||
if (!blockInfo || !this.loadedLevelNumber) return Promise.reject(new Error("关卡配置尚未就绪"));
|
||||
const blocks = this.getCurrentLevelBlockDefinitions();
|
||||
const currentLevel = this.loadedLevelNumber;
|
||||
return BlockAssetManager.instance.prepareWindow(blocks,
|
||||
{ onRemoteRequired, currentLevel, stage }).then(ready =>
|
||||
ready && this.BLOCK_INFO[0] === blocks);
|
||||
ready && this.BLOCK_INFO[0] === blockInfo && this.LEVEL_INFO[0] === levelInfo);
|
||||
}
|
||||
|
||||
/** 创建时不显示;仅远程图片调用 open。失效请求不能打开或关闭后续请求的 Loading。 */
|
||||
@@ -109,14 +125,32 @@ export class GameConfig {
|
||||
};
|
||||
}
|
||||
|
||||
/** 所有正式进关入口都在当前关图片就绪后才切换 GameScene。 */
|
||||
/** 所有正式进关入口都在弹窗分包及当前关图片就绪后才切换 GameScene。 */
|
||||
static enterGameSceneWhenReady(time = 0): void {
|
||||
const id = ++this.sceneLoadRequest;
|
||||
const scene = cc.director.getScene();
|
||||
const blocks = this.BLOCK_INFO;
|
||||
const isCurrent = () => id === this.sceneLoadRequest && cc.director.getScene() === scene && this.BLOCK_INFO === blocks;
|
||||
const loading = this.createBlockLoading(isCurrent);
|
||||
this.prepareBlockWindow(loading.open).then(ready => {
|
||||
|
||||
if (!GameTool.areGameplayPopupSubpackagesDownloaded()) loading.open();
|
||||
GameTool.ensureGameplayPopupSubpackagesDownloaded().then(popupReady => {
|
||||
if (!isCurrent()) {
|
||||
loading.close();
|
||||
return false;
|
||||
}
|
||||
if (!popupReady) {
|
||||
loading.close();
|
||||
const missing = GameTool.getMissingGameplayPopupSubpackages();
|
||||
this.showBlockLoadError(
|
||||
new Error(`游戏弹窗分包下载失败: ${missing.join(", ")}`),
|
||||
() => this.enterGameSceneWhenReady(time),
|
||||
"游戏界面资源下载失败\n请检查网络,点击此处重试"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return this.prepareBlockWindow(loading.open);
|
||||
}).then(ready => {
|
||||
loading.close();
|
||||
if (!ready || !isCurrent()) return;
|
||||
cc.director.preloadScene("GameScene", error => {
|
||||
@@ -140,8 +174,9 @@ export class GameConfig {
|
||||
}
|
||||
|
||||
/** 不推进关卡、不无限卡在转场;此提示不依赖任何远程图片。 */
|
||||
static showBlockLoadError(error: any, retry: () => void): void {
|
||||
cc.error("方块资源加载失败:", error);
|
||||
static showBlockLoadError(error: any, retry: () => void,
|
||||
messageText = "方块图片加载失败\n请检查网络,点击此处重试"): void {
|
||||
cc.error(messageText, error);
|
||||
const canvas = cc.find("Canvas");
|
||||
if (!canvas || canvas.getChildByName("BlockLoadRetry")) return;
|
||||
const overlay = new cc.Node("BlockLoadRetry");
|
||||
@@ -156,7 +191,7 @@ export class GameConfig {
|
||||
const message = new cc.Node("message");
|
||||
message.parent = overlay;
|
||||
const label = message.addComponent(cc.Label);
|
||||
label.string = "方块图片加载失败\n请检查网络,点击此处重试";
|
||||
label.string = messageText;
|
||||
label.fontSize = 32;
|
||||
label.lineHeight = 48;
|
||||
label.horizontalAlign = cc.Label.HorizontalAlign.CENTER;
|
||||
@@ -445,8 +480,7 @@ export class GameConfig {
|
||||
vibrateOpen: true, //震动
|
||||
coinnum: 0, //每局的金币数
|
||||
paid_user: false, //是否是付费用户
|
||||
version: "1.0.41", //版本号
|
||||
version: "1.0.43", //版本号
|
||||
version: "1.0.44", //版本号
|
||||
shushu_DistinctId: "", //数数访客ID
|
||||
shushu_AccountId: "", //数数账号ID
|
||||
uid: "", //用户和后端唯一id
|
||||
|
||||
@@ -8,8 +8,9 @@ import Utils from "../Pay/Utils";
|
||||
//@ts-ignore
|
||||
//最大工具类 各种公共方法,以及处理上传,获取后端接口数据
|
||||
var GameTool = {
|
||||
MAX_NORMAL_LEVEL: 1920,
|
||||
MAX_NORMAL_LEVEL: 3000,
|
||||
MEMORY_WARNING_EVENT: "game-memory-warning",
|
||||
GAMEPLAY_POPUP_SUBPACKAGES: ["pause", "NewMode", "propWindow", "lose", "win"],
|
||||
_startTime: 0,
|
||||
_endTime: 0,
|
||||
_totalTime: 0,
|
||||
@@ -17,6 +18,9 @@ var GameTool = {
|
||||
_memoryWarningHandler: null,
|
||||
_lowMemoryMode: false,
|
||||
_memoryWarningCount: 0,
|
||||
_gameplayPopupSubpackageDownloaded: {},
|
||||
_gameplayPopupSubpackageRetryTimer: null,
|
||||
_gameplayPopupSubpackagePreloadPromise: null,
|
||||
|
||||
//获取userId
|
||||
Authentication() {
|
||||
@@ -2556,7 +2560,10 @@ var GameTool = {
|
||||
wx.triggerGC();
|
||||
}
|
||||
|
||||
// 2. 释放不需要的 Bundle
|
||||
// 2. 释放不需要的 Bundle。释放 shop 前同步清空两个场景脚本中的静态 Prefab 缓存,
|
||||
// 避免下一场景继续实例化已经被 releaseAll 的对象。
|
||||
SceneManager.clearShopPrefabCaches();
|
||||
JiaZai.clearShopPrefabCaches();
|
||||
const bundles = ['shop', 'action_bundle', 'TextureBg', 'TextureBlock', 'UI'];
|
||||
bundles.forEach(name => {
|
||||
const bundle = cc.assetManager.getBundle(name);
|
||||
@@ -2622,6 +2629,19 @@ var GameTool = {
|
||||
return platform === "ios" || (!platform && cc.sys.os === cc.sys.OS_IOS);
|
||||
},
|
||||
|
||||
isLowMemoryIOSDevice() {
|
||||
if (cc.sys.platform !== cc.sys.WECHAT_GAME) {
|
||||
return false;
|
||||
}
|
||||
const deviceInfo = this.getWechatDeviceInfo();
|
||||
const platform = deviceInfo && deviceInfo.platform
|
||||
? String(deviceInfo.platform).toLowerCase()
|
||||
: "";
|
||||
const isIOS = platform === "ios" || (!platform && cc.sys.os === cc.sys.OS_IOS);
|
||||
const memorySizeMB = Number(deviceInfo && deviceInfo.memorySize);
|
||||
return isIOS && memorySizeMB > 0 && memorySizeMB < 5000;
|
||||
},
|
||||
|
||||
isLowMemoryMode() {
|
||||
return this._lowMemoryMode === true;
|
||||
},
|
||||
@@ -2704,6 +2724,127 @@ var GameTool = {
|
||||
this._memoryWarningHandler = null;
|
||||
},
|
||||
|
||||
/** 已 loadBundle 或本次启动中预下载成功的分包都视为就绪。 */
|
||||
getMissingGameplayPopupSubpackages(): string[] {
|
||||
return this.GAMEPLAY_POPUP_SUBPACKAGES.filter((bundleName) => {
|
||||
if (cc.assetManager.getBundle(bundleName)) {
|
||||
this._gameplayPopupSubpackageDownloaded[bundleName] = true;
|
||||
}
|
||||
return !this._gameplayPopupSubpackageDownloaded[bundleName];
|
||||
});
|
||||
},
|
||||
|
||||
areGameplayPopupSubpackagesDownloaded(): boolean {
|
||||
return cc.sys.platform !== cc.sys.WECHAT_GAME
|
||||
|| this.getMissingGameplayPopupSubpackages().length === 0;
|
||||
},
|
||||
|
||||
/** 进关前等待当前预下载批次;失败交给进关界面提示用户重试。 */
|
||||
ensureGameplayPopupSubpackagesDownloaded(): Promise<boolean> {
|
||||
if (cc.sys.platform !== cc.sys.WECHAT_GAME) return Promise.resolve(true);
|
||||
const missing = this.getMissingGameplayPopupSubpackages();
|
||||
if (missing.length === 0) return Promise.resolve(true);
|
||||
console.log(`[PopupSubpackage] GameScene gate waiting for: ${missing.join(", ")}`);
|
||||
return this.predownloadGameplayPopupSubpackages(false).then((ready) => {
|
||||
if (ready) console.log("[PopupSubpackage] GameScene gate ready");
|
||||
return ready;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 只让微信提前下载弹窗分包,不调用 loadBundle,也不解析 Prefab 和图片。
|
||||
* 下载由微信管理到代码包缓存;每次启动都检查一次,命中缓存时会很快完成。
|
||||
*/
|
||||
predownloadGameplayPopupSubpackages(scheduleRetry = true): Promise<boolean> {
|
||||
if (cc.sys.platform !== cc.sys.WECHAT_GAME) return Promise.resolve(true);
|
||||
if (this._gameplayPopupSubpackagePreloadPromise) {
|
||||
return this._gameplayPopupSubpackagePreloadPromise;
|
||||
}
|
||||
//@ts-ignore
|
||||
const wechat = typeof wx !== "undefined" ? wx : null;
|
||||
if (!wechat) return Promise.resolve(false);
|
||||
const predownloadSubpackage = wechat.preDownloadSubpackage || wechat.loadSubpackage;
|
||||
if (!predownloadSubpackage) {
|
||||
cc.warn("[PopupSubpackage] current WeChat version does not support subpackage predownload");
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
// Pause 和 NewMode 可能刚进关就用到,优先于结算弹窗。
|
||||
const pendingNames = this.getMissingGameplayPopupSubpackages();
|
||||
if (pendingNames.length === 0) return Promise.resolve(true);
|
||||
|
||||
if (this._gameplayPopupSubpackageRetryTimer) {
|
||||
clearTimeout(this._gameplayPopupSubpackageRetryTimer);
|
||||
this._gameplayPopupSubpackageRetryTimer = null;
|
||||
}
|
||||
let activeCount = 0;
|
||||
let nextIndex = 0;
|
||||
let failedCount = 0;
|
||||
let batchFinished = false;
|
||||
let resolveBatch: (ready: boolean) => void = null;
|
||||
const apiName = wechat.preDownloadSubpackage ? "preDownloadSubpackage" : "loadSubpackage";
|
||||
console.log(`[PopupSubpackage] using wx.${apiName}`);
|
||||
|
||||
const batchPromise = new Promise<boolean>((resolve) => {
|
||||
resolveBatch = resolve;
|
||||
});
|
||||
this._gameplayPopupSubpackagePreloadPromise = batchPromise;
|
||||
|
||||
const finishBatch = () => {
|
||||
if (batchFinished || activeCount > 0 || nextIndex < pendingNames.length) return;
|
||||
batchFinished = true;
|
||||
const ready = this.getMissingGameplayPopupSubpackages().length === 0;
|
||||
this._gameplayPopupSubpackagePreloadPromise = null;
|
||||
if (ready) {
|
||||
console.log("[PopupSubpackage] all gameplay popup subpackages are cached");
|
||||
}
|
||||
else if (scheduleRetry) {
|
||||
console.warn(`[PopupSubpackage] ${failedCount} subpackage(s) failed; retrying in 10 seconds`);
|
||||
this._gameplayPopupSubpackageRetryTimer = setTimeout(() => {
|
||||
this._gameplayPopupSubpackageRetryTimer = null;
|
||||
GameTool.predownloadGameplayPopupSubpackages(true);
|
||||
}, 10000);
|
||||
}
|
||||
else {
|
||||
console.warn(`[PopupSubpackage] ${failedCount} subpackage(s) failed while entering GameScene`);
|
||||
}
|
||||
resolveBatch(ready);
|
||||
};
|
||||
|
||||
const startNext = () => {
|
||||
while (activeCount < 2 && nextIndex < pendingNames.length) {
|
||||
const bundleName = pendingNames[nextIndex++];
|
||||
activeCount++;
|
||||
console.log(`[PopupSubpackage] predownload start: ${bundleName}`);
|
||||
try {
|
||||
predownloadSubpackage.call(wechat, {
|
||||
name: bundleName,
|
||||
success: () => {
|
||||
this._gameplayPopupSubpackageDownloaded[bundleName] = true;
|
||||
activeCount--;
|
||||
console.log(`[PopupSubpackage] predownload complete: ${bundleName}`);
|
||||
startNext();
|
||||
},
|
||||
fail: (error) => {
|
||||
failedCount++;
|
||||
activeCount--;
|
||||
console.warn(`[PopupSubpackage] predownload failed: ${bundleName}`, error);
|
||||
startNext();
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
failedCount++;
|
||||
activeCount--;
|
||||
console.warn(`[PopupSubpackage] predownload exception: ${bundleName}`, error);
|
||||
}
|
||||
}
|
||||
finishBatch();
|
||||
};
|
||||
|
||||
startNext();
|
||||
return batchPromise;
|
||||
},
|
||||
|
||||
shouldPreloadGameplayPopupInstances() {
|
||||
const systemInfo = this.getGameplayPopupSystemInfo();
|
||||
const platform = systemInfo && systemInfo.platform
|
||||
|
||||
Reference in New Issue
Block a user