MatchMaster/assets/testSeven/TestSeven.ts

207 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SevenApiPanel from "./SevenApiPanel";
const { ccclass } = cc._decorator;
/** 仅编辑器预览使用。通过真实 Prefab 的视图接口模拟,不调用正式 Runtime。 */
@ccclass
export default class TestSeven extends cc.Component {
private gift: cc.Node = null;
private view: any = null;
private info: any = null;
private status: cc.Label = null;
private busy = false;
private failNext = false;
// 仅在编辑器预览加载真实活动 Prefab,并创建测试按钮。
start() {
if (!CC_PREVIEW) {
cc.error("[testSeven] 仅允许编辑器预览,请从构建中排除 testSeven。");
return;
}
this.status = this.label("正在加载 seven_day_gift…", 0, 850, 26);
this.button("临时打开 JungleTreasure", 0, 645, () => this.openJunglePreview());
const apiPanel = this.node.addComponent(SevenApiPanel);
apiPanel.preview = info => {
if (!this.view || this.busy) return this.report("请等待活动资源加载或奖励动画结束");
this.info = info;
this.open();
this.report("接口数据模拟 | 点击当天奖励领取,或点击外部只领取,本次不关闭(不增加资产)");
};
cc.assetManager.loadBundle("seven_day_gift", (error, bundle) => {
if (!cc.isValid(this.node, true)) return;
if (error) return this.report("分包加载失败:" + error.message);
bundle.load("prefab/sevenDayGift", cc.Prefab, (loadError, prefab: cc.Prefab) => {
if (!cc.isValid(this.node, true)) return;
if (loadError) return this.report("Prefab 加载失败:" + loadError.message);
this.gift = cc.instantiate(prefab);
this.node.addChild(this.gift);
this.gift.setPosition(0, 0);
this.view = this.gift.getComponent("SevenDayGift");
if (!this.view) return this.report("缺少 SevenDayGift 组件");
this.view.setCloseHandler(() => this.report("已关闭,可选择状态重新打开"));
// 控制面板在遮罩上方,使用与活动一致的 1080 × 1920 设计尺寸。
for (let day = 1; day <= 7; day++) {
this.button("第" + day + "天", (day - 4) * 140, -670, () => this.select(day));
}
this.button("今日已领", -330, -755, () => this.select(this.info.nextRewardDay, "claimed"));
this.button("全部完成", -110, -755, () => this.select(7, "completed"));
this.button("已过期", 110, -755, () => this.select(3, "expired"));
this.button("点击外部", 330, -755, () => {
if (this.gift.active) this.view.close();
else this.report("弹窗已关闭,请先重新打开");
});
this.button("下次失败", -220, -840, () => {
this.failNext = true;
this.report("下一次领取模拟失败,可再次点击重试");
});
this.button("重新打开", 0, -840, () => this.open());
this.button("重置", 220, -840, () => { this.failNext = false; this.select(1); });
this.button("预览弹出上浮(不领取)", 0, 730, () => {
if (!this.gift.active) this.open();
const reward = this.info.rewards.find(item => Number(item.day) === Number(this.info.nextRewardDay));
if (!reward) return;
this.busy = true;
this.view.playRewardEffect(reward.items, reward.day, () => { this.busy = false; });
});
this.select(1);
});
});
}
// 临时查看真实丛林活动界面;使用内存样例和原有动画预览模式。
private openJunglePreview() {
if (!CC_PREVIEW || this.busy) return;
this.busy = true;
this.report("正在加载 JungleTreasure…");
cc.assetManager.loadBundle("jungle_treasure", (error, bundle) => {
if (!cc.isValid(this.node, true)) return;
if (error) { this.busy = false; return this.report("丛林分包加载失败:" + error.message); }
bundle.load("prefab/jungle", cc.Prefab, (loadError, prefab: cc.Prefab) => {
if (!cc.isValid(this.node, true)) return;
if (loadError) { this.busy = false; return this.report("丛林界面加载失败:" + loadError.message); }
const node = cc.instantiate(prefab);
node.active = false;
const manager: any = node.getComponent("jungle_Manager");
if (!manager) {
node.destroy();
this.busy = false;
return this.report("丛林界面缺少 jungle_Manager 组件");
}
manager.previewAnimationOnly = true;
// 独立预览场景没有主页音频管理器,当前实例关闭音效。
manager.anniuMusic = manager.unLockMusic = manager.rewardMusic = null;
this.node.addChild(node);
node.setPosition(0, 0);
node.zIndex = 3000;
const close = () => {
node.destroy();
this.busy = false;
this.report("已关闭 JungleTreasure,可继续七日活动测试");
};
node.on("jungle-close", close, this);
node.on("jungle-complete", close, this);
node.active = true;
const types = ["coin", "freeze", "hammer", "magic_wand", "infinite_health"];
const config = {
activityId: "testSeven-jungle-preview", endAt: Date.now() + 86400000,
tiers: types.map((type, index) => ({
id: index + 1, price: index === 2 ? 6 : 0,
rewards: [{ type, count: type === "coin" ? 500 : type === "infinite_health" ? 1800 : 2 }],
})),
};
if (!manager.setServerData(config, [1, 1, 0, 1, 1])) {
close();
return this.report("丛林预览数据初始化失败");
}
manager.openActivity();
this.report("JungleTreasure 本地界面预览,不发奖、不支付");
});
});
}
// 生成指定天数和状态的内存样例,不修改账号资产。
private select(day: number, state: string = "active") {
if (this.busy) return;
const claimedCount = state === "completed" ? 7 : state === "claimed" ? day : day - 1;
const items = [
[{ type: "coin", count: 100 }],
[{ type: "hammer", count: 2 }],
[{ type: "freeze", count: 2 }, { type: "coin", count: 200 }],
[{ type: "magic_wand", count: 2 }],
[{ type: "infinite_health", count: 1800 }], // 秒:30 分钟,效果显示 +1800秒。
[{ type: "hammer", count: 1 }, { type: "freeze", count: 1 }], // 第六天移除魔法棒。
[{ type: "infinite_health", count: 1800 }, { type: "cat_skin", count: 1, itemId: 1 }],
];
this.info = {
serverNow: Date.now(), activityId: "testSeven-memory", status: state === "claimed" ? "active" : state,
triggerLevel: 23, triggerReached: true, startAt: Date.now() - 86400000,
endAt: Date.now() + (state === "expired" ? -1 : 7 * 86400000),
claimedCount, todayClaimed: state === "claimed" || state === "completed",
canClaim: state === "active", nextRewardDay: day,
rewards: items.map((reward, index) => ({ day: index + 1, items: reward, claimed: index < claimedCount })),
};
this.open();
}
// 用当前模拟状态重新打开弹窗。
private open() {
if (this.busy || !this.view || !this.info) return;
this.bindData();
this.view.show();
this.report("本地模拟 | 第" + this.info.nextRewardDay + "天 | " + this.info.status + " | 已领 " + this.info.claimedCount + "/7");
}
// 本地领取立即响应,支持一次失败;成功后使用正式视图的领取效果。
private bindData() {
this.view.setData(this.info, (done: (success: boolean) => void) => {
if (this.busy || !this.info.canClaim) return done(false);
const reward = this.info.rewards.find(item => Number(item.day) === Number(this.info.nextRewardDay));
if (!reward || reward.claimed || !Array.isArray(reward.items) || reward.items.length === 0) {
done(false);
return this.report("当前数据没有可领取奖励,请重新选择模拟天数或查询接口");
}
if (this.failNext) {
this.failNext = false;
done(false);
return this.report("模拟领取失败,弹窗保留;可点击当天奖励或外部重试");
}
this.busy = true;
reward.claimed = true;
this.info.claimedCount++;
this.info.todayClaimed = true;
this.info.canClaim = false;
if (this.info.claimedCount === 7) this.info.status = "completed";
// 更新视图仍沿用本地回调,不调用 initializeRuntime。
this.bindData();
this.view.playRewardEffect(reward.items, reward.day, () => { this.busy = false; done(true); });
this.report("模拟领取成功(不写入资产):" + reward.items.map(item => item.type + " × " + item.count).join(" / "));
});
}
// 更新测试状态提示。
private report(message: string) { this.status.string = message; }
// 创建测试面板文字,放在活动遮罩上方。
private label(text: string, x: number, y: number, size: number): cc.Label {
const node = new cc.Node("testSevenLabel");
this.node.addChild(node);
node.setPosition(x, y);
node.zIndex = 1000;
const label = node.addComponent(cc.Label);
label.string = text;
label.fontSize = size;
label.lineHeight = size + 6;
return label;
}
// 创建测试按钮,忙碌时忽略操作,避免切换正在播放的数据。
private button(text: string, x: number, y: number, action: () => void) {
const label = this.label(text, x, y, 28);
label.node.color = cc.color(110, 225, 255);
label.node.on(cc.Node.EventType.TOUCH_END, (event: cc.Event) => {
event.stopPropagation();
if (!this.busy) action();
});
}
}