pinball/assets/_Game/Scripts/Gacha/LuckyWheel.ts

143 lines
4.2 KiB
TypeScript
Raw Normal View History

2024-06-10 21:35:13 -07:00
import {
_decorator,
2024-06-18 21:35:41 -07:00
AudioClip,
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-18 21:35:41 -07:00
import AudioManager from '../Manager/AudioManager';
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;
2024-06-18 21:35:41 -07:00
@property(AudioClip)
private showSfx: AudioClip;
@property(AudioClip)
private btnSfx: AudioClip;
@property(AudioClip)
private spinSfx: AudioClip;
@property(AudioClip)
private stopSfx: AudioClip;
2024-06-10 06:13:32 -07:00
@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-18 21:35:41 -07:00
private _preAngle: 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();
2024-06-18 21:35:41 -07:00
if (Math.abs(this._preAngle - angle) >= 36) {
this._preAngle = angle;
AudioManager.playSfx(this.spinSfx);
}
2024-06-10 06:13:32 -07:00
if (this._timer >= this._timeSpin) {
this._spinning = false;
2024-06-18 21:35:41 -07:00
AudioManager.playSfx(this.stopSfx);
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);
2024-06-18 21:35:41 -07:00
AudioManager.playSfx(this.showSfx);
2024-06-10 06:13:32 -07:00
await this.animationHandler.setAnimationAsync('appear');
this.animationHandler.addAnimation('idle', { loop: true });
}
public async spin() {
if (this._spinning) return;
2024-06-18 21:35:41 -07:00
AudioManager.playSfx(this.btnSfx);
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-18 21:35:41 -07:00
this._preAngle = this._maxAngle;
2024-06-20 01:07:39 -07:00
this._spinning = true;
2024-06-10 06:13:32 -07:00
}
}