import { UIViewID } from '@scripts/define/UIDefine'; import { UIPopup } from '@scripts/framework/ui/UIPopup'; import { addBtnClick } from '@scripts/utils/UIHelper'; import { _decorator, Button, Label, Node, Tween, tween } from 'cc'; const { ccclass, property } = _decorator; const ITEM_COUNT = 13; const ITEM_ANGLE = 360 / ITEM_COUNT; const SPIN_SPEED = 1080; // 匀速阶段:每秒两圈。 const ACCELERATE_TIME = 1; const LOOP_COUNT = 5; let testIndex = 0; @ccclass('UIInviteSpin') export class UIInviteSpin extends UIPopup { readonly viewId: UIViewID = UIViewID.UIInviteSpin; @property(Button) btnClose: Button; @property(Button) btnSpin: Button; @property(Label) lblCount: Label; @property(Node) btnDiabled: Node; @property(Node) turntable: Node; private spinning = false; protected onCreate(): void | Promise { addBtnClick(this.btnClose, this.closeSelf, this); addBtnClick(this.btnSpin, this.onBtnSpinClick, this); } private onBtnSpinClick() { this.startSpine(testIndex); testIndex++; if (testIndex > ITEM_COUNT) testIndex = 0; } private startSpine(index: number) { if (this.spinning || !Number.isInteger(index) || index < 0 || index >= ITEM_COUNT) return; this.spinning = true; this.btnClose.interactable = false; this.btnSpin.interactable = false; Tween.stopAllByTarget(this.turntable); const angle = ((this.turntable.angle % 360) + 360) % 360; this.turntable.angle = angle; const accAngle = angle + SPIN_SPEED * ACCELERATE_TIME / 2; const loopAngle = accAngle + 360 * LOOP_COUNT; // 奖项从顶部开始顺时针排列,转盘正向旋转到对应奖项。 const targetAngle = index * ITEM_ANGLE; const remainingAngle = ((targetAngle - loopAngle) % 360 + 360) % 360; const decelerateAngle = 360 * 2 + remainingAngle; // quadIn/quadOut 的端点速度与匀速段一致,衔接时不会突然变速。 tween(this.turntable) .to(ACCELERATE_TIME, { angle: accAngle }, { easing: 'quadIn' }) .to(360 * LOOP_COUNT / SPIN_SPEED, { angle: loopAngle }, { easing: 'linear' }) .to(2 * decelerateAngle / SPIN_SPEED, { angle: loopAngle + decelerateAngle }, { easing: 'quadOut' }) .call(() => { this.turntable.angle = targetAngle; this.spinning = false; this.btnClose.interactable = true; this.btnSpin.interactable = true; }) .start(); } protected onDisable(): void { Tween.stopAllByTarget(this.turntable); this.spinning = false; } protected onOpen(_params: unknown) { this.btnClose.interactable = true; this.btnSpin.interactable = true; } }