import { _decorator, CCInteger, CCString, clamp01, Component, easing, Enum, game, 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 { 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() { @property(CCString) public gachaId: string; @property(UIOpacity) private container: UIOpacity; @property(FloatingTextFactory) private floatingScoreFactory: FloatingTextFactory; @property(Gacha) private gachas: Gacha[] = []; @property(RewardConfig) public rewards: RewardConfig[] = []; private _reward: RewardConfig; private _showing: boolean = false; private _showTimer: number = 0; private _idType: GachaType; protected onLoad(): void { super.onLoad(); this.container.setNodeActive(false); } 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); floatingText.show(`+${text}`, position, 3, 1, icon); } private showGacha() { const gacha = this.gachas.find((gacha) => gacha.type == this._idType); gacha.gacha.show(); } public async getReward(): Promise { 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() { console.log(`Gacha reward: ${RewardType[this._reward.type]} quantity: ${this._reward.quantity}`); await Utils.delay(1); game.timeScale = 1; tween(this.container) .to(0.1, { opacity: 0 }) .call(() => { this.container.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, Vec3.ZERO); 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(); } }