119 lines
4.2 KiB
TypeScript
119 lines
4.2 KiB
TypeScript
const { ccclass } = cc._decorator;
|
|
|
|
type WinPanelAction = (event?: cc.Event, customEventData?: string) => void;
|
|
|
|
interface WinPanelActions {
|
|
[name: string]: WinPanelAction;
|
|
}
|
|
|
|
/** Win prefab 内部按钮入口;具体游戏流程由 Map 在实例化后注入。 */
|
|
@ccclass
|
|
export default class WinPanel extends cc.Component {
|
|
private actions: WinPanelActions = null;
|
|
private rainbowStars: cc.Node[] = [];
|
|
private starTime = 0;
|
|
private avatarFrame: cc.SpriteFrame = null;
|
|
|
|
bind(actions: WinPanelActions) {
|
|
this.actions = actions || {};
|
|
}
|
|
|
|
initRainbowWinStreak(count: number) {
|
|
const streak = this.node.getChildByName("WinStreak2");
|
|
if (!streak) return;
|
|
count = Math.max(0, Math.min(10, count));
|
|
const reward = streak.getChildByName("reward");
|
|
const avatar = streak.getChildByName("avatar");
|
|
const milestone = count > 0 ? streak.getChildByName("hammer").getChildByName(String(count))
|
|
: streak.getChildByName("progress");
|
|
if (milestone) {
|
|
const position = milestone.convertToWorldSpaceAR(cc.v2());
|
|
[reward, avatar].forEach(node => {
|
|
if (node) node.x = node.parent.convertToNodeSpaceAR(position).x;
|
|
});
|
|
}
|
|
this.rainbowStars = reward ? reward.children.filter(node => node.name === "star") : [];
|
|
this.starTime = 0;
|
|
this.update(0);
|
|
|
|
const mask = avatar && avatar.getChildByName("mask");
|
|
if (!mask) return;
|
|
const icon = mask.getChildByName("icon");
|
|
const spine = mask.getChildByName("sp");
|
|
const selected = cc.fx.GameConfig.GM_INFO.useravatarIcon || "icon_0";
|
|
const remote = selected.length > 10;
|
|
icon.active = remote;
|
|
spine.active = !remote;
|
|
if (remote) {
|
|
icon.getComponent(cc.Sprite).spriteFrame = null;
|
|
cc.assetManager.loadRemote(selected, { ext: '.png' }, (err, texture: cc.Texture2D) => {
|
|
if (err || !texture || !cc.isValid(this, true) || !cc.isValid(icon, true)
|
|
|| cc.fx.GameConfig.GM_INFO.useravatarIcon !== selected) return;
|
|
if (!this.avatarFrame) this.avatarFrame = new cc.SpriteFrame(texture);
|
|
else this.avatarFrame.setTexture(texture);
|
|
icon.getComponent(cc.Sprite).spriteFrame = this.avatarFrame;
|
|
});
|
|
} else {
|
|
cc.fx.GameTool.loadSpineSimple(spine, cc.fx.GameTool.getActionName(selected));
|
|
}
|
|
}
|
|
|
|
update(dt: number) {
|
|
if (!this.rainbowStars.length) return;
|
|
this.starTime = (this.starTime + dt) % 1.8;
|
|
this.rainbowStars.forEach((star, index) => {
|
|
const phase = (this.starTime / 1.8 - index / this.rainbowStars.length) * Math.PI * 2;
|
|
star.opacity = 40 + (Math.cos(phase) + 1) * 107.5;
|
|
});
|
|
}
|
|
|
|
setSpecialTipsVisible(visible: boolean) {
|
|
const specialTips = this.node.getChildByName("specialTips");
|
|
if (specialTips) {
|
|
specialTips.active = visible;
|
|
}
|
|
}
|
|
|
|
openPosition(event?: cc.Event, customEventData?: string) {
|
|
this.invoke("openPosition", event, customEventData);
|
|
}
|
|
|
|
winMaxLevelShowClose() {
|
|
this.setSpecialTipsVisible(false);
|
|
}
|
|
|
|
winLevel(event?: cc.Event, customEventData?: string) {
|
|
this.invoke("winLevel", event, customEventData);
|
|
}
|
|
|
|
winLevel2(event?: cc.Event, customEventData?: string) {
|
|
this.invoke("winLevel2", event, customEventData);
|
|
}
|
|
|
|
returnHome(event?: cc.Event, customEventData?: string) {
|
|
this.invoke("returnHome", event, customEventData);
|
|
}
|
|
|
|
returnHomeScene(event?: cc.Event, customEventData?: string) {
|
|
this.invoke("returnHomeScene", event, customEventData);
|
|
}
|
|
|
|
showDoubleCoin(event?: cc.Event, customEventData?: string) {
|
|
this.invoke("showDoubleCoin", event, customEventData);
|
|
}
|
|
|
|
private invoke(name: string, event?: cc.Event, customEventData?: string) {
|
|
const action = this.actions && this.actions[name];
|
|
if (action) {
|
|
action(event, customEventData);
|
|
return;
|
|
}
|
|
cc.warn("WinPanel action is not bound:", name);
|
|
}
|
|
|
|
onDestroy() {
|
|
if (this.avatarFrame) this.avatarFrame.destroy();
|
|
this.actions = null;
|
|
}
|
|
}
|