export interface SevenDayGiftDebugActions { getStatusText: () => string; queryServer: () => void; openGift: () => void; clearAutoOpen: () => void; mockDay: (day: number) => void; mockTodayClaimed: () => void; mockCompleted: () => void; mockExpired: () => void; addCoins: () => void; addHammer: () => void; addFreeze: () => void; addMagicWand: () => void; addInfiniteHealth: () => void; } /** 七日活动开发工具。只由 SevenDayGiftHost 在非正式环境创建。 */ export default class SevenDayGiftDebugPanel { private root: cc.Node = null; private panel: cc.Node = null; private statusLabel: cc.Label = null; constructor(private parent: cc.Node, private actions: SevenDayGiftDebugActions) { } public build() { this.root = new cc.Node("sevenDayGiftDebug"); this.root.parent = this.parent; this.root.setContentSize(this.parent.getContentSize()); this.root.zIndex = 30000; const toggle = this.createButton("debugToggle", "7日测试", 160, 72, () => this.show()); toggle.parent = this.root; toggle.setPosition(-this.root.width * 0.5 + 95, this.root.height * 0.5 - 105); this.panel = new cc.Node("panel"); this.panel.parent = this.root; this.panel.setContentSize(720, 1180); this.panel.addComponent(cc.BlockInputEvents); this.drawRect(this.panel, cc.color(24, 31, 43, 245), 720, 1180); const scale = Math.min(1, (this.root.width - 20) / 720, (this.root.height - 20) / 1180); this.panel.setScale(scale); this.panel.active = false; this.createLabel(this.panel, "七日活动测试面板(正式版不显示)", 34, -35, 540, 560, 54, cc.color(255, 226, 117)); const close = this.createButton("close", "关闭", 120, 58, () => this.hide()); close.parent = this.panel; close.setPosition(290, 540); const statusNode = new cc.Node("status"); statusNode.parent = this.panel; statusNode.setContentSize(660, 300); statusNode.setPosition(0, 350); this.drawRect(statusNode, cc.color(10, 14, 22, 230), 660, 300); this.statusLabel = this.createLabel(statusNode, "", 25, 0, 0, 625, 270, cc.Color.WHITE); this.statusLabel.horizontalAlign = cc.Label.HorizontalAlign.LEFT; this.statusLabel.verticalAlign = cc.Label.VerticalAlign.TOP; this.statusLabel.overflow = cc.Label.Overflow.CLAMP; this.createLabel(this.panel, "真实测试服", 27, 0, 174, 660, 42, cc.color(113, 210, 255)); this.addButton("查询接口", -235, 112, () => this.actions.queryServer()); this.addButton("打开活动", 0, 112, () => this.actions.openGift()); this.addButton("清除自动弹出", 235, 112, () => this.actions.clearAutoOpen()); this.createLabel(this.panel, "本地模拟(不会发奖)", 27, 0, 52, 660, 42, cc.color(124, 237, 167)); for (let day = 1; day <= 7; day++) { const index = day - 1; const x = [-235, 0, 235][index % 3]; const y = -10 - Math.floor(index / 3) * 82; this.addButton("模拟第" + day + "天", x, y, () => this.actions.mockDay(day), cc.color(37, 139, 91)); } this.addButton("今日已领", 0, -174, () => this.actions.mockTodayClaimed(), cc.color(151, 102, 38)); this.addButton("七天完成", 235, -174, () => this.actions.mockCompleted(), cc.color(151, 102, 38)); this.addButton("活动过期", 0, -256, () => this.actions.mockExpired(), cc.color(133, 66, 79)); this.createLabel(this.panel, "测试资产(开发/体验版会同步测试服)", 27, 0, -320, 660, 42, cc.color(255, 188, 103)); this.addButton("金币 +1000", -235, -382, () => this.actions.addCoins(), cc.color(179, 117, 28)); this.addButton("锤子 +5", 0, -382, () => this.actions.addHammer(), cc.color(179, 117, 28)); this.addButton("冻结 +5", 235, -382, () => this.actions.addFreeze(), cc.color(55, 130, 181)); this.addButton("魔法棒 +5", -118, -464, () => this.actions.addMagicWand(), cc.color(126, 75, 170)); this.addButton("无限体力 +15分", 118, -464, () => this.actions.addInfiniteHealth(), cc.color(184, 66, 91)); this.refresh(); } public refresh() { if (this.statusLabel) this.statusLabel.string = this.actions.getStatusText(); } public show() { if (!this.panel) return; this.refresh(); this.panel.active = true; } public hide() { if (this.panel) this.panel.active = false; } public destroy() { if (this.root && cc.isValid(this.root)) this.root.destroy(); this.root = null; this.panel = null; this.statusLabel = null; } private addButton(text: string, x: number, y: number, callback: () => void, color?: cc.Color) { const button = this.createButton(text, text, 210, 68, callback, color); button.parent = this.panel; button.setPosition(x, y); } private createButton(name: string, text: string, width: number, height: number, callback: () => void, color?: cc.Color): cc.Node { const node = new cc.Node(name); node.setContentSize(width, height); node.addComponent(cc.Button); this.drawRect(node, color || cc.color(43, 123, 190), width, height); this.createLabel(node, text, 25, 0, 0, width - 10, height, cc.Color.WHITE); node.on(cc.Node.EventType.TOUCH_END, (event: cc.Event) => { event.stopPropagation(); callback(); this.refresh(); }); return node; } private createLabel(parent: cc.Node, text: string, fontSize: number, x: number, y: number, width: number, height: number, color: cc.Color): cc.Label { const node = new cc.Node("label"); node.parent = parent; node.setContentSize(width, height); node.setPosition(x, y); node.color = color; const label = node.addComponent(cc.Label); label.string = text; label.fontSize = fontSize; label.lineHeight = fontSize + 6; label.horizontalAlign = cc.Label.HorizontalAlign.CENTER; label.verticalAlign = cc.Label.VerticalAlign.CENTER; return label; } private drawRect(node: cc.Node, color: cc.Color, width: number, height: number) { const graphics = node.addComponent(cc.Graphics); graphics.fillColor = color; graphics.rect(-width * 0.5, -height * 0.5, width, height); graphics.fill(); } }