rp_11009/assets/Game/Scripts/BigWin.ts
2026-04-20 15:28:18 +08:00

335 lines
12 KiB
TypeScript

import { _decorator, Component, Label, Node, Tween, tween, UIOpacity, v3, sp } from 'cc';
import { WIN_TYPE } from './Define';
import { UIManager } from '../../Main/Scripts/managers/UIManager';
import { gold2cash } from '../../Main/Scripts/main/comm';
import { AudioManager } from '../../Main/Scripts/managers/AudioManager';
const { ccclass, property } = _decorator;
@ccclass('BigWin')
export class BigWin extends Component {
@property(Node)
grayoNode: Node = null;
@property(Node)
mainNode: Node = null;
@property(Node)
bigWinNode: Node = null;
@property(Node)
megaWinNode: Node = null;
@property(Node)
superMegaWinNode: Node = null;
@property(Label)
winCount: Label = null;
isScrolling: boolean = false;
winTypeMultis: number[] = [35, 50];
betAmount: number = 0;
winCounts: number[] = [];
curType: WIN_TYPE = WIN_TYPE.NONE;
endWinType: WIN_TYPE = WIN_TYPE.NONE;
numHolder: any = null;
isFreeSpin: boolean = false;
callBack: () => void = null;
bubbleTween: Tween<Node> = null;
bubbleNode: Node = null;
isClosing: boolean = false;
open(winType: WIN_TYPE, winCount: number, betAmount: number, callBack: () => void, isFreeSpin: boolean) {
this.isScrolling = true;
this.isFreeSpin = isFreeSpin;
this.callBack = callBack;
this.isClosing = false;
if (winType <= WIN_TYPE.NORMAL_WIN) {
this.isScrolling = false;
if (callBack) callBack();
return;
}
this.grayoNode.on(Node.EventType.TOUCH_START, this.onClickGrayBg, this);
let bigWinCount = this.winTypeMultis[0] * betAmount;
let megaWinCount = this.winTypeMultis[1] * betAmount;
if (winCount <= bigWinCount) {
this.winCounts = [0, 0, winCount];
this.endWinType = WIN_TYPE.BIG_WIN;
} else if (bigWinCount < winCount && winCount <= megaWinCount) {
this.winCounts = [0, 0, bigWinCount, winCount];
this.endWinType = WIN_TYPE.MEGA_WIN;
} else if (megaWinCount < winCount) {
this.winCounts = [0, 0, bigWinCount, megaWinCount, winCount];
this.endWinType = WIN_TYPE.SUPER_MEGA_WIN;
}
this.winCount.string = '0';
this.tweenOpen(WIN_TYPE.BIG_WIN);
this.startScrolling(true, WIN_TYPE.BIG_WIN, 0, this.winCounts[WIN_TYPE.BIG_WIN], callBack);
tween(this.winCount.node)
.set({ scale: v3(0, 0, 0) })
.to(0.5, { scale: v3(1, 1, 1) }, { easing: 'quadIn' })
.start();
}
tweenOpen(winType: WIN_TYPE) {
this.bigWinNode.active = winType == WIN_TYPE.BIG_WIN;
this.megaWinNode.active = winType == WIN_TYPE.MEGA_WIN;
this.superMegaWinNode.active = winType == WIN_TYPE.SUPER_MEGA_WIN;
if (winType == WIN_TYPE.BIG_WIN) {
AudioManager.instance.playBGM('Big_Win_Bgm');
} else if (winType == WIN_TYPE.MEGA_WIN) {
AudioManager.instance.playBGM('Mega_Win_Bgm');
} else if (winType == WIN_TYPE.SUPER_MEGA_WIN) {
AudioManager.instance.playBGM('Super_Mega_Win_Bgm');
}
this.bigWinNode.children[0].active = winType == WIN_TYPE.BIG_WIN;
this.megaWinNode.children[0].active = winType == WIN_TYPE.MEGA_WIN;
this.superMegaWinNode.children[0].active = winType == WIN_TYPE.SUPER_MEGA_WIN;
this.curType = winType;
let opacity, actionNode;
if (winType == WIN_TYPE.BIG_WIN) {
opacity = this.bigWinNode.getComponent(UIOpacity);
actionNode = this.bigWinNode;
} else if (winType == WIN_TYPE.MEGA_WIN) {
opacity = this.megaWinNode.getComponent(UIOpacity);
actionNode = this.megaWinNode;
} else if (winType == WIN_TYPE.SUPER_MEGA_WIN) {
opacity = this.superMegaWinNode.getComponent(UIOpacity);
actionNode = this.superMegaWinNode;
}
opacity.opacity = 0;
tween(opacity)
.to(0.5, { opacity: 255 }, { easing: 'quadIn' })
.start();
actionNode.scale = v3(1.1, 1.1, 1.1);
tween(actionNode)
.to(0.5, { scale: v3(1, 1, 1) }, { easing: 'quadIn' })
.start();
this.startBubbleAnimation(actionNode);
this.playSpineAnimation(actionNode, 'ruchang', false, () => {
this.playSpineAnimation(actionNode, 'chixu', true);
});
}
startScrolling(isFirst: boolean, curType: WIN_TYPE, startValue: number, targetValue: number, callBack: () => void) {
if (curType === this.endWinType && !isFirst) {
if (this.numHolder && this.numHolder.holder) Tween.stopAllByTarget(this.numHolder.holder);
this.winCount.string = gold2cash(targetValue);
this.isScrolling = false;
if (curType == WIN_TYPE.SUPER_MEGA_WIN) {
AudioManager.instance.playBGM('Super_Mega_Win_Bgm');
}
tween(this.winCount.node)
.to(0.1, { scale: v3(1.1, 1.1, 1.1) }, { easing: 'quadIn' })
.to(0.1, { scale: v3(1, 1, 1) }, { easing: 'quadOut' })
.call(() => {
this.scheduleOnce(() => {
this.stopBubbleAnimation();
this.playXiaoshiAndClose(callBack);
}, 5);
})
.start();
} else {
// 还没到最终级别,继续升级
this.numHolder = UIManager.instance.tweenScorelinear(startValue, targetValue, 5)
.onUpdate((v: number) => {
this.winCount.string = gold2cash(v);
})
.onComplete(() => {
this.winCount.string = gold2cash(targetValue);
if (this.curType !== this.endWinType) {
let nextType = curType + 1;
this.stopBubbleAnimation();
this.playCurrentXiaoshi(() => {
if (this.bigWinNode.active) this.bigWinNode.active = false;
if (this.megaWinNode.active) this.megaWinNode.active = false;
if (this.superMegaWinNode.active) this.superMegaWinNode.active = false;
});
this.tweenOpen(nextType);
this.startScrolling(false, nextType, this.winCounts[curType], this.winCounts[nextType], callBack);
} else {
this.startScrolling(false, this.endWinType, this.winCounts[curType], this.winCounts[this.endWinType], callBack);
}
})
.start();
}
}
onClickGrayBg() {
if (this.isClosing) return;
if (this.isScrolling) {
this.isScrolling = false;
if (this.numHolder && this.numHolder.holder) {
Tween.stopAllByTarget(this.numHolder.holder);
}
if (this.endWinType !== this.curType) {
this.stopBubbleAnimation();
this.playCurrentXiaoshi(() => {
if (this.bigWinNode.active) this.bigWinNode.active = false;
if (this.megaWinNode.active) this.megaWinNode.active = false;
if (this.superMegaWinNode.active) this.superMegaWinNode.active = false;
});
this.tweenOpen(this.endWinType);
this.winCount.string = gold2cash(this.winCounts[this.endWinType]);
tween(this.winCount.node)
.to(0.1, { scale: v3(1.1, 1.1, 1.1) }, { easing: 'quadIn' })
.to(0.1, { scale: v3(1, 1, 1) }, { easing: 'quadOut' })
.call(() => {
this.scheduleOnce(() => {
this.playXiaoshiAndClose(this.callBack);
}, 5);
})
.start();
} else {
this.winCount.string = gold2cash(this.winCounts[this.endWinType]);
tween(this.winCount.node)
.to(0.1, { scale: v3(1.1, 1.1, 1.1) }, { easing: 'quadIn' })
.to(0.1, { scale: v3(1, 1, 1) }, { easing: 'quadOut' })
.call(() => {
this.scheduleOnce(() => {
this.playXiaoshiAndClose(this.callBack);
}, 5);
})
.start();
}
return;
} else {
this.playXiaoshiAndClose(this.callBack);
}
}
private playSpineAnimation(node: Node, animationName: string, loop: boolean = false, onComplete?: () => void) {
if (!node || !node.active) {
if (onComplete) onComplete();
return;
}
let skeleton = node.getComponent(sp.Skeleton);
if (!skeleton && node.children.length > 0) {
skeleton = node.children[0].getComponent(sp.Skeleton);
}
if (!skeleton) {
console.warn(`未找到Spine组件: ${node.name}`);
if (onComplete) onComplete();
return;
}
skeleton.setAnimation(0, animationName, loop);
if (onComplete && !loop) {
const onAnimComplete = () => {
skeleton.setCompleteListener(null);
onComplete();
};
skeleton.setCompleteListener(onAnimComplete);
}
}
private playCurrentXiaoshi(onComplete: () => void) {
let activeNode: Node = null;
if (this.bigWinNode.active) {
activeNode = this.bigWinNode;
} else if (this.megaWinNode.active) {
activeNode = this.megaWinNode;
} else if (this.superMegaWinNode.active) {
activeNode = this.superMegaWinNode;
}
if (activeNode) {
this.playSpineAnimation(activeNode, 'xiaoshi', false, onComplete);
} else {
onComplete();
}
}
private playXiaoshiAndClose(callBack?: () => void) {
if (this.isClosing) return;
this.isClosing = true;
let activeNode: Node = null;
if (this.bigWinNode.active) {
activeNode = this.bigWinNode;
} else if (this.megaWinNode.active) {
activeNode = this.megaWinNode;
} else if (this.superMegaWinNode.active) {
activeNode = this.superMegaWinNode;
}
if (activeNode) {
this.playSpineAnimation(activeNode, 'xiaoshi', false, () => {
this.closeAndDestroy(callBack);
});
} else {
this.closeAndDestroy(callBack);
}
}
private closeAndDestroy(callBack?: () => void) {
if (callBack) callBack();
this.unscheduleAllCallbacks();
this.isFreeSpin ?
AudioManager.instance.playBGM('Free_Bg_Bgm') :
AudioManager.instance.playBGM('Normal_Bg_Bgm');
this.node.destroy();
}
private startBubbleAnimation(parentNode: Node) {
this.stopBubbleAnimation();
if (!parentNode || parentNode.children.length === 0) {
console.warn('找不到要做泡泡动画的子节点');
return;
}
this.bubbleNode = parentNode.children[0];
this.bubbleNode.setScale(v3(1, 1, 1));
this.bubbleTween = tween(this.bubbleNode)
.to(1, { scale: v3(1.1, 1.1, 1.1) }, {
easing: 'sineInOut'
})
.to(1, { scale: v3(1, 1, 1) }, {
easing: 'sineInOut'
})
.union()
.repeatForever()
.start();
}
private stopBubbleAnimation() {
if (this.bubbleTween) {
this.bubbleTween.stop();
this.bubbleTween = null;
}
if (this.bubbleNode && this.bubbleNode.isValid) {
this.bubbleNode.setScale(v3(1, 1, 1));
this.bubbleNode = null;
}
}
}