2024-06-10 21:35:13 -07:00
|
|
|
import {
|
|
|
|
_decorator,
|
2024-06-12 04:48:19 -07:00
|
|
|
CCFloat,
|
2024-06-10 21:35:13 -07:00
|
|
|
CCInteger,
|
|
|
|
CCString,
|
|
|
|
Component,
|
|
|
|
game,
|
2024-06-12 04:48:19 -07:00
|
|
|
Label,
|
2024-06-10 21:35:13 -07:00
|
|
|
Node,
|
|
|
|
randomRangeInt,
|
|
|
|
RealCurve,
|
|
|
|
sp,
|
|
|
|
Sprite,
|
|
|
|
} from 'cc';
|
2024-06-10 06:13:32 -07:00
|
|
|
import GachaBase from '../Base/GachaBase';
|
|
|
|
import SpineAnimationHandler from '../Base/SpineAnimationHandler';
|
2024-06-10 21:35:13 -07:00
|
|
|
import GachaManager, { RewardConfig } from '../Manager/GachaManager';
|
2024-06-10 06:13:32 -07:00
|
|
|
|
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
2024-06-10 21:35:13 -07:00
|
|
|
class RewardCard {
|
|
|
|
public reward: RewardConfig;
|
|
|
|
|
2024-06-12 04:48:19 -07:00
|
|
|
constructor(reward: RewardConfig) {
|
2024-06-10 21:35:13 -07:00
|
|
|
this.reward = reward;
|
|
|
|
}
|
2024-06-12 04:48:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@ccclass('RewardDisplay')
|
|
|
|
class RewardDisplay {
|
|
|
|
@property(Sprite)
|
|
|
|
private sprite: Sprite;
|
|
|
|
@property(Label)
|
|
|
|
private label: Label;
|
2024-06-10 21:35:13 -07:00
|
|
|
|
2024-06-12 04:48:19 -07:00
|
|
|
public setReward(reward: RewardConfig) {
|
|
|
|
this.sprite.spriteFrame = reward.icon;
|
|
|
|
this.label.string = 'x' + reward.quantity;
|
2024-06-10 21:35:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-10 06:13:32 -07:00
|
|
|
@ccclass('LuckyWheel')
|
|
|
|
export default class LuckyWheel extends GachaBase {
|
|
|
|
@property(SpineAnimationHandler)
|
|
|
|
private animationHandler: SpineAnimationHandler;
|
|
|
|
@property(Node)
|
|
|
|
private spineRoot: Node;
|
|
|
|
@property(CCString)
|
|
|
|
private wheelBoneName: string = '';
|
|
|
|
@property(CCInteger)
|
|
|
|
private speed: number = 1;
|
|
|
|
@property(RealCurve)
|
|
|
|
private spinCurve: RealCurve = new RealCurve();
|
2024-06-12 04:48:19 -07:00
|
|
|
@property(RewardDisplay)
|
|
|
|
private rewardDisplay: RewardDisplay[] = [];
|
|
|
|
@property(CCFloat)
|
|
|
|
private offsetAngle: number;
|
2024-06-10 06:13:32 -07:00
|
|
|
|
|
|
|
private _wheel: sp.spine.Bone;
|
|
|
|
private _targetAngle: number = 0;
|
|
|
|
private _spinning: boolean = false;
|
|
|
|
private _timer: number = 0;
|
|
|
|
private _timeSpin: number = 0;
|
|
|
|
private _maxAngle: number = 0;
|
2024-06-10 21:35:13 -07:00
|
|
|
private _allCards: RewardCard[];
|
|
|
|
private _random: number;
|
2024-06-10 06:13:32 -07:00
|
|
|
|
|
|
|
protected onLoad(): void {
|
|
|
|
this._wheel = this.animationHandler.findBone(this.wheelBoneName);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected onEnable(): void {
|
2024-06-11 03:28:30 -07:00
|
|
|
this._random = null;
|
2024-06-10 06:13:32 -07:00
|
|
|
this.spineRoot.setActive(false);
|
|
|
|
this._wheel.rotation = 0;
|
|
|
|
this._wheel.update();
|
2024-06-11 03:28:30 -07:00
|
|
|
this._spinning = false;
|
2024-06-10 06:13:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
protected update(): void {
|
|
|
|
if (this._spinning) {
|
|
|
|
this._timer += game.deltaTime * this.speed;
|
|
|
|
const angle = this._maxAngle * this.spinCurve.evaluate(this._timer / this._timeSpin);
|
|
|
|
this._wheel.rotation = this._targetAngle + angle;
|
|
|
|
this._wheel.update();
|
|
|
|
if (this._timer >= this._timeSpin) {
|
|
|
|
this._spinning = false;
|
2024-06-10 21:35:13 -07:00
|
|
|
GachaManager.instance.showFloatingText(
|
|
|
|
this._allCards[this._random].reward.quantity.toString(),
|
|
|
|
this.node.worldPosition,
|
|
|
|
this._allCards[this._random].reward.icon,
|
|
|
|
);
|
|
|
|
GachaManager.instance.setReward(this._allCards[this._random].reward.id);
|
2024-06-10 06:13:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-10 21:35:13 -07:00
|
|
|
private setReward() {
|
2024-06-12 04:48:19 -07:00
|
|
|
this._allCards = this.rewardDisplay.map((card, i) => {
|
|
|
|
let rw = GachaManager.instance.rewards[i];
|
|
|
|
card.setReward(rw);
|
|
|
|
return new RewardCard(rw);
|
2024-06-10 21:35:13 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-06-10 06:13:32 -07:00
|
|
|
public async show(): Promise<void> {
|
2024-06-12 04:48:19 -07:00
|
|
|
this.setReward();
|
2024-06-10 06:13:32 -07:00
|
|
|
this.spineRoot.setActive(true);
|
|
|
|
await this.animationHandler.setAnimationAsync('appear');
|
|
|
|
|
|
|
|
this.animationHandler.addAnimation('idle', { loop: true });
|
|
|
|
}
|
|
|
|
|
|
|
|
public async spin() {
|
|
|
|
if (this._spinning) return;
|
|
|
|
this._spinning = true;
|
2024-06-10 21:35:13 -07:00
|
|
|
this._random = this._allCards.getRandomIndex();
|
2024-06-12 04:48:19 -07:00
|
|
|
this.animationHandler.clearTrack(0);
|
|
|
|
this._targetAngle = -(360 / this.rewardDisplay.length) * this._random + this.offsetAngle;
|
|
|
|
this._timer = 0;
|
|
|
|
this._timeSpin = randomRangeInt(10, 15);
|
|
|
|
this._maxAngle = 360 * this._timeSpin;
|
2024-06-10 06:13:32 -07:00
|
|
|
}
|
|
|
|
}
|