pinball/assets/_Game/Scripts/Manager/GachaManager.ts

214 lines
6.2 KiB
TypeScript

import {
_decorator,
AudioClip,
CCInteger,
CCString,
clamp01,
Component,
easing,
Enum,
game,
Label,
lerp,
Node,
SpriteFrame,
tween,
UIOpacity,
Vec3,
} from 'cc';
import { EDITOR, PREVIEW } from 'cc/env';
import GachaBase from '../Base/GachaBase';
import BoosterType from '../Enum/BoosterType';
import ScoreType from '../Enum/ScoreType';
import GameEvent from '../Events/GameEvent';
import FloatingTextFactory from '../Factory/FloatingTextFactory';
import P4PSDK from '../P4PSDK';
import Singleton from '../Singleton';
import Utils from '../Utilities';
import AudioManager from './AudioManager';
import { EventManger } from './EventManger';
import { GameManager } from './GameManager';
import { SpawnObjectManager } from './SpawnObjectManager';
const { ccclass, property } = _decorator;
export enum GachaType {
FreeReward,
LuckyWheel,
LuckyChain,
FlipCard,
}
Enum(GachaType);
export enum RewardType {
Star,
Time,
Cheese,
Ball,
}
Enum(RewardType);
@ccclass('Gacha')
class Gacha {
@property(CCString)
public id: string = '';
@property({ type: GachaType })
public type: GachaType = GachaType.FreeReward;
@property(GachaBase)
public gacha: GachaBase;
}
@ccclass('RewardConfig')
export class RewardConfig {
@property(CCString)
public id: string = '';
@property({ type: RewardType })
public type: RewardType = RewardType.Star;
@property(SpriteFrame)
public icon: SpriteFrame;
@property(CCInteger)
public quantity: number;
}
@ccclass('GachaManager')
export default class GachaManager extends Singleton<GachaManager>() {
@property(CCString)
public gachaId: string;
@property(UIOpacity)
private container: UIOpacity;
@property(FloatingTextFactory)
private floatingScoreFactory: FloatingTextFactory;
@property(Label)
private countDownLabel: Label;
@property(AudioClip)
private collectSfx: AudioClip;
@property(AudioClip)
private countDownSfx: AudioClip;
@property(AudioClip)
private readySfx: AudioClip;
@property(Gacha)
private gachas: Gacha[] = [];
@property(RewardConfig)
public rewards: RewardConfig[] = [];
private _reward: RewardConfig;
private _showing: boolean = false;
private _showTimer: number = 0;
private _idType: GachaType;
private _currentGacha: GachaBase;
protected onLoad(): void {
super.onLoad();
this.container.setNodeActive(false);
this.countDownLabel.setNodeActive(false);
this.gachas.forEach((gacha) => gacha.gacha.setNodeActive(false));
}
public showBtn(_, data: string) {
this.show(GachaType[data]);
}
public async show(type: GachaType, delay: number = 0) {
game.timeScale = 0;
await Utils.delay(delay);
this.container.setNodeActive(true);
this._showTimer = 0;
this._showing = true;
this._idType = type;
}
protected update(dt: number): void {
if (this._showing) {
this._showTimer += game.deltaTime;
const k = easing.smooth(clamp01(this._showTimer / 0.2));
this.container.opacity = lerp(0, 255, k);
if (k === 1) {
this._showing = false;
this.showGacha();
}
}
}
public showFloatingText(text: string, position: Vec3, icon: SpriteFrame) {
const floatingText = this.floatingScoreFactory.create(this.node);
AudioManager.playSfx(this.collectSfx);
floatingText.show(`+${text}`, position, 3, 1, icon);
}
private showGacha() {
this._currentGacha = this.gachas.find((gacha) => gacha.type == this._idType).gacha;
this._currentGacha.setNodeActive(true);
this._currentGacha.show();
}
public async getReward(): Promise<RewardConfig> {
// if (!EDITOR && !PREVIEW) {
// try {
// const rw = await P4PSDK.spinGacha(this.gachaId);
// this._reward = this.rewards.find((r) => r.id == rw.id);
// } catch (error) {
// console.log(error);
// return null;
// }
// } else {
// }
this._reward = this.getRandomReward();
return this._reward;
}
public getRewardIndex(reward: RewardConfig): number {
return this.rewards.indexOf(reward);
}
public async gachaDone() {
await Utils.delay(1);
this._currentGacha.setNodeActive(false);
this.countDownLabel.setNodeActive(true);
console.log(`Gacha reward: ${RewardType[this._reward.type]} quantity: ${this._reward.quantity}`);
let count = 3;
while (count >= 0) {
this.countDownLabel.setString(count == 0 ? 'Ready' : count);
AudioManager.playSfx(count == 0 ? this.readySfx : this.countDownSfx);
count--;
await Utils.delay(0.5);
}
game.timeScale = 1;
tween(this.container)
.to(0.1, { opacity: 0 })
.call(() => {
this.container.setNodeActive(false);
this.countDownLabel.setNodeActive(false);
switch (this._reward.type) {
case RewardType.Star:
GameManager.instance.addScore(this._reward.quantity, ScoreType.DestroyObject);
break;
case RewardType.Time:
GameManager.instance.addTime(this._reward.quantity);
break;
case RewardType.Cheese:
const cheese = SpawnObjectManager.instance.getBoosterByType(BoosterType.CumulativeBar);
cheese.activeCollider = false;
cheese.hide();
GameManager.instance.addBooster(cheese);
break;
case RewardType.Ball:
EventManger.instance.emit(GameEvent.SpawnMultiBall, this._reward.quantity);
break;
}
})
.start();
}
public getRandomReward(weights?: number[]) {
return this.rewards.getRandom(weights);
}
public setReward(id: string) {
this._reward = this.rewards.find((r) => r.id == id);
this.gachaDone();
}
}