/** Shared image assets for the settlement, unlock presentation and Halloween digits. */ export default class BattlePassArt { static frames: { [name: string]: cc.SpriteFrame } = {}; private static pending: Promise; static settlementPrefab: cc.Prefab; static unlockPrefab: cc.Prefab; private static halloween: Promise; static loadHalloween(): Promise { if (!this.halloween) this.halloween = (async () => { const names = ['pumpkin_normal','pumpkin_active','time_bg','slash']; for (const group of ['digits_progress','digits_level_large','digits_level_small']) for (let i=0;i<10;i++) names.push(group+'/'+i); await Promise.all(names.map(n => this.loadAsset('passCheck','img/halloween/'+n,cc.SpriteFrame).then(f => {this.frames[n]=f;}))); })().catch(e => {this.halloween=null;throw e;}); return this.halloween; } static digits(target: cc.Node, value: number, disabled = false) { const ticket = ((target as any)._passDigitsTicket || 0) + 1; (target as any)._passDigitsTicket=ticket; this.loadHalloween().then(() => { if (!cc.isValid(target) || (target as any)._passDigitsTicket!==ticket) return; const progress=target.name==='progress_1'||target.name==='progress_2'; const group=progress?'digits_progress':disabled?'digits_level_large':'digits_level_small'; const chars=String(value).split(''), spacing=progress?28:40; target.destroyAllChildren(); chars.forEach((d,i) => this.image(target,group+'/'+d,(i-(chars.length-1)/2)*spacing,0)); if(!progress&&target.parent) { const pumpkin=target.parent.getChildByName('bright_bg'); if(pumpkin) { pumpkin.getComponent(cc.Sprite).spriteFrame=this.frames[disabled?'pumpkin_normal':'pumpkin_active']; pumpkin.setContentSize(140,140); } } }).catch(e=>cc.warn('战令数字素材加载失败',e)); } static loadAsset(bundle: string, path: string, type: any): Promise { return new Promise((resolve, reject) => { const load = (b: cc.AssetManager.Bundle) => b.load(path, type, (e, a) => e ? reject(e) : resolve(a)); const b = cc.assetManager.getBundle(bundle); if (b) load(b); else cc.assetManager.loadBundle(bundle, (e, loaded) => e ? reject(e) : load(loaded)); }); } static load(): Promise { if (this.pending) return this.pending; this.pending = Promise.all([ this.loadAsset('passCheck','prefab/PassSettlement',cc.Prefab).then(p => { this.settlementPrefab = p; }), this.loadAsset('passCheck','prefab/PassUnlock',cc.Prefab).then(p => { this.unlockPrefab = p; }) ]).then(() => {}).catch(e => { this.pending = null; throw e; }); return this.pending; } static image(parent: cc.Node, name: string, x: number, y: number, width?: number, height?: number): cc.Node { const n = new cc.Node(name); n.parent = parent; n.setPosition(x, y); const sprite = n.addComponent(cc.Sprite); sprite.spriteFrame = this.frames[name]; sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM; const size = sprite.spriteFrame.getOriginalSize(); n.setContentSize(width || size.width, height || size.height); return n; } static async unlock(parent: cc.Node, tier: number, done: () => void) { await this.load(); if (!cc.isValid(parent)) return; const root = cc.instantiate(this.unlockPrefab); root.parent = parent; root.zIndex = 1100; const content = root.getChildByName('content'); content.scaleX *= Math.min(parent.width / root.width, parent.height / root.height); content.scaleY *= Math.min(parent.width / root.width, parent.height / root.height); const vip = content.getChildByName('vip'), svip = content.getChildByName('svip'); vip.active = tier === 18; svip.active = tier !== 18; const card = (vip.active ? vip : svip).getChildByName('cardAnimation'); const scaleX = card.scaleX, scaleY = card.scaleY; card.scale = 0; let ready = false; cc.tween(card).to(0.35,{scaleX,scaleY},{easing:'backOut'}).delay(0.4).call(() => {ready=true;}).start(); root.getChildByName('shade').on(cc.Node.EventType.TOUCH_END, () => { if (ready) { root.destroy(); done(); } }); } }