import { _decorator, AudioClip, Component, geometry, Label, Node, Prefab, Tween, tween, Vec3 } from 'cc'; import BEConnector from '../API/BEConnector'; import { GameManager } from '../Manager/GameManager'; import ObjectPool from '../Pool/ObjectPool'; import Utilities from '../Utilities'; import { EventManger } from '../Manager/EventManger'; import GameEvent from '../Events/GameEvent'; import GameState from '../Enum/GameState'; import { SequenceSound } from '../Environments/SequenceSound'; import { SoundManager } from '../Manager/SoundManager'; const { ccclass, property } = _decorator; @ccclass('GameOverPanel') export class GameOverPanel extends Component { @property(Label) private topScore: Label = null; @property(Label) private yourScore: Label = null; @property({ type: Label, visible: true }) private _ticketMinus: Label; @property({ type: Node, visible: true }) private _buyTicketBtn: Node; @property({ type: Node, visible: true }) private _quitBtn: Node; @property({ type: Node, visible: true }) private _scoreUI: Node; @property({ type: Prefab, visible: true }) private _scorePrefab: Prefab; @property({ type: AudioClip, visible: true }) private _soundCollectCoinFx: AudioClip; @property({ type: geometry.AnimationCurve, visible: true }) private _starSpeedCurve: geometry.AnimationCurve = new geometry.AnimationCurve(); @property({ type: geometry.AnimationCurve, visible: true }) private _starScaleCurve: geometry.AnimationCurve = new geometry.AnimationCurve(); private _pool: ObjectPool; private _active = false; private _clicked = false; private _end = false; protected onLoad(): void { this._pool = new ObjectPool(this._scorePrefab, 100, true); EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this); } protected onEnable(): void { this._ticketMinus.string = '-' + BEConnector.getTicketCanBeMinus().toString(); this.topScore.string = BEConnector.maxScore.toString(); this.yourScore.string = BEConnector.currentScore.toString(); const gameScore = GameManager.instance.score; const currentScore = BEConnector.currentScore; this.playCollectEffect(gameScore, currentScore); this.scheduleOnce(this.endGame, 60); this._active = true; } private async onGameStateChange(state: GameState) { switch (state) { case GameState.Init: break; case GameState.Ready: break; case GameState.Playing: break; case GameState.GameOver: break; case GameState.End: this._buyTicketBtn.active = false; this._quitBtn.active = false; this._end = true; if (this._active) { await Utilities.delay(1); BEConnector.postScoreToServer(); } break; case GameState.Relive: break; } } onClickYesButton() { if (this._clicked) return; this._clicked = true; if (BEConnector.canRelive()) { BEConnector.checkGameScoreTicket() .then(() => { this._clicked = false; GameManager.instance.gameRelive(); }) .catch(() => { this._clicked = false; GameManager.instance.gameOver(); }); } else { this._clicked = false; BEConnector.postMessage(); } } onClickNoButton() { GameManager.instance.gameOver(); } protected onDisable(): void { this._active = false; this.unschedule(this.endGame); } private endGame() { GameManager.instance.gameOver(); } private async playCollectEffect(gameScore: number, currentScore: number) { if (!this._active) { let x = 10; let items = Math.ceil(gameScore / x); if (items >= 50) { items = 50; x = Math.round(gameScore / items); } const totalScore = gameScore + currentScore; let score = currentScore; const target = this.yourScore.node.getWorldPosition(); let duration = 0; for (let i = 0; i < items; i++) { score += x; duration = this._starSpeedCurve.evaluate(i / items - 1); score = score > totalScore ? totalScore : score; const obj = this._pool.get(this._scoreUI); obj.setWorldPosition(this._scoreUI.worldPosition); tween(obj) .to( duration, { worldPosition: target }, { easing: 'sineIn', onUpdate: (target: Node, ratio: number) => { const scale = this._starScaleCurve.evaluate(ratio) * 1.5; target.setScale(new Vec3(scale, scale)); }, }, ) .call(() => this._pool.release(obj)) .call(async () => { Tween.stopAllByTarget(this.yourScore.node); this.yourScore.string = score.toString(); tween(this.yourScore.node) .to(duration / 6, { scale: new Vec3(1.3, 1.3) }) .to(duration / 6, { scale: new Vec3(1, 1) }) .start(); }) .start(); SoundManager.instance.playSfx(this._soundCollectCoinFx); await Utilities.delay(duration / 3); } await Utilities.waitUntil(() => this._pool.countActive == 0, 0.1); this.yourScore.string = totalScore.toString(); Tween.stopAllByTarget(this.yourScore.node); tween(this.yourScore.node) .set({ scale: Vec3.ONE }) .to(0.3, { scale: new Vec3(1.8, 1.8) }, { easing: 'backIn' }) .to(0.3, { scale: new Vec3(1, 1) }, { easing: 'backOut' }) .start(); if (!this._end) return; await Utilities.delay(1); BEConnector.postScoreToServer(); } } }