import { _decorator, CCInteger, clamp, Component, lerp, Sprite, Node, tween, Prefab } from 'cc'; import { EventManger } from '../Manager/EventManger'; import GameEvent from '../Events/GameEvent'; import ScoreType from '../Enum/ScoreType'; import Utilities from '../Utilities'; import { GameManager } from '../Manager/GameManager'; import BoosterType from '../Enum/BoosterType'; import { SpawnObjectManager } from '../Manager/SpawnObjectManager'; import ObjectPool from '../Pool/ObjectPool'; const { ccclass, property } = _decorator; @ccclass('CumulativeBar') export class CumulativeBar extends Component { @property({ type: Sprite, visible: true }) private _fillBar: Sprite; @property({ type: CCInteger, visible: true }) private _maxValue = 1000; @property({ type: Node, visible: true }) private _scoreUI: Node; @property({ type: Prefab, visible: true }) private _scoreObjectPrefab: Prefab; private _pools: ObjectPool; private _currentValue = 0; private _fillValue = 0; private _active = false; private _goal = false; private _timer = 0; protected onLoad(): void { this._fillBar.fillRange = 0; this._pools = new ObjectPool(this._scoreObjectPrefab, 10, false); EventManger.instance.on(GameEvent.Score, this.onScore, this); EventManger.instance.on(GameEvent.BoosterActive, this.onBoosterActive, this); EventManger.instance.on(GameEvent.BoosterDisable, this.onBoosterDisable, this); } protected update(dt: number): void { if (!this._goal && !this._active && this._currentValue > 0) { this._timer += dt; if (this._timer >= 0.1) { this._timer = 0; this._currentValue -= 0.5; if (this._currentValue < 0) { this._currentValue = 0; } this._fillValue = -clamp(this._currentValue / 2 / this._maxValue, 0, 0.5); } } if (Math.abs(this._fillValue - this._fillBar.fillRange) >= 0.001) { this._fillBar.fillRange = lerp(this._fillBar.fillRange, this._fillValue, dt * 3); } } private async onScore(score: number, points: number, type: ScoreType) { switch (type) { case ScoreType.DestroyObject: if (!this._active) return; this._currentValue += points; break; case ScoreType.Goal: if (this._currentValue == 0) return; this._goal = true; await Utilities.delay(1); let items = Math.round(this._currentValue / 5); GameManager.instance.addScore( Math.round(this._currentValue), ScoreType.Combo, this.node.getWorldPosition(), { scaleMin: 2, scaleMax: 4, duration: 1, }, ); this._currentValue = 0; this._goal = false; this.playCollectEffect(items); break; } this._fillValue = -clamp(this._currentValue / 2 / this._maxValue, 0, 0.5); } private async playCollectEffect(items: number) { const time = items < 10 ? 0.05 : 1.5 / items; while (items > 0) { const obj = this._pools.get(this.node); obj.setWorldPosition(this.node.worldPosition); tween(obj) .to(0.3, { worldPosition: this._scoreUI.worldPosition }) .call(() => ObjectPool.release(obj)) .start(); items--; await Utilities.delay(time); } } private onBoosterActive(type: BoosterType) { if (type == BoosterType.CumulativeBar) this._active = true; } private onBoosterDisable(type: BoosterType) { if (type == BoosterType.CumulativeBar) this._active = false; } }