226 lines
7.7 KiB
TypeScript
226 lines
7.7 KiB
TypeScript
|
import { _decorator, CCInteger, Component, Enum, EventTarget, instantiate, Node, ParticleSystem2D, Prefab, randomRange, randomRangeInt, RigidBody2D, Vec2 } from 'cc';
|
||
|
import { Ball } from './Ball';
|
||
|
import { EventType } from './Enums';
|
||
|
import { SoundManager } from './SoundManager';
|
||
|
import BEConnector from './BEConnector';
|
||
|
import { UIController } from './UIController';
|
||
|
import { LevelController } from './LevelController';
|
||
|
const { ccclass, property } = _decorator;
|
||
|
|
||
|
|
||
|
window.addEventListener("message", (data) => {
|
||
|
const { data: res } = data
|
||
|
const objectRes = JSON.parse(res)
|
||
|
const { type, value } = objectRes
|
||
|
if (type === "newTicket") {
|
||
|
BEConnector.instance.numberTicket += value
|
||
|
GameplayController.Instance().OnRevive();
|
||
|
}
|
||
|
})
|
||
|
export enum GameState {
|
||
|
MainMenu,
|
||
|
StartGame,
|
||
|
PlayGame,
|
||
|
EndGame
|
||
|
}
|
||
|
@ccclass('GameplayController')
|
||
|
export class GameplayController extends Component {
|
||
|
//#region Singleton
|
||
|
private static instance: GameplayController;
|
||
|
public static Instance(): GameplayController {
|
||
|
if (!GameplayController.instance) {
|
||
|
GameplayController.instance = new Node().addComponent(GameplayController);
|
||
|
}
|
||
|
|
||
|
return GameplayController.instance;
|
||
|
}
|
||
|
protected onLoad(): void {
|
||
|
GameplayController.instance = this;
|
||
|
}
|
||
|
//#endregion
|
||
|
//#region Properties
|
||
|
@property(Prefab)
|
||
|
private ballPrefab: Prefab;
|
||
|
@property([Vec2])
|
||
|
private startPositions: Vec2[] = [];
|
||
|
@property({ readonly: true, type: Node })
|
||
|
private controllingBall: Node = null;
|
||
|
@property(UIController)
|
||
|
public uiController: UIController = null;
|
||
|
@property(LevelController)
|
||
|
private levelController: LevelController = null;
|
||
|
|
||
|
@property({ readonly: true, type: CCInteger })
|
||
|
public score: number = 0;
|
||
|
@property({ readonly: true, type: CCInteger })
|
||
|
private streak: number = 0;
|
||
|
@property({ readonly: true, type: CCInteger })
|
||
|
public highestStreak: number = 0;
|
||
|
// @property({ readonly: true, type: CCInteger })
|
||
|
@property(CCInteger)
|
||
|
private ball: number = 10;
|
||
|
@property(CCInteger)
|
||
|
private scoreToSpawnObstacle: number = 5;
|
||
|
|
||
|
@property({ type: Enum(GameState) })
|
||
|
public currentGameState: GameState = GameState.MainMenu;
|
||
|
|
||
|
@property(ParticleSystem2D)
|
||
|
public particle: ParticleSystem2D = null;
|
||
|
|
||
|
@property(CCInteger)
|
||
|
public startGameCountDown: number = 3;
|
||
|
//#endregion
|
||
|
|
||
|
public eventMenuGame = new EventTarget();
|
||
|
|
||
|
public eventStartGame = new EventTarget();
|
||
|
public eventPlayGame = new EventTarget();
|
||
|
public eventEndGame = new EventTarget();
|
||
|
|
||
|
public eventSpawnObstacle = new EventTarget();
|
||
|
|
||
|
public eventUpdateScore = new EventTarget();
|
||
|
public eventUpdateStreak = new EventTarget();
|
||
|
public eventUpdateHighestStreak = new EventTarget();
|
||
|
public eventUpdateBall = new EventTarget();
|
||
|
|
||
|
protected start(): void {
|
||
|
BEConnector.instance.authenticate();
|
||
|
this.ChangeGameState(GameState.MainMenu);
|
||
|
|
||
|
}
|
||
|
|
||
|
private SpawnBall(): void {
|
||
|
if (this.currentGameState == GameState.EndGame) return;
|
||
|
|
||
|
if (this.controllingBall == null) {
|
||
|
this.controllingBall = instantiate(this.ballPrefab);
|
||
|
this.controllingBall.parent = this.node;
|
||
|
|
||
|
let randonPos = randomRangeInt(0, this.startPositions.length);
|
||
|
this.controllingBall.setPosition(this.startPositions[randonPos].x, this.startPositions[randonPos].y, 0);
|
||
|
this.controllingBall.active = true;
|
||
|
|
||
|
this.controllingBall.getComponent(Ball).eventHitObstacle.on("HitObstacle", this.ObstacleHitControl, this);
|
||
|
this.controllingBall.getComponent(Ball).eventGoal.on("Goal", this.GoalControl, this);
|
||
|
return;
|
||
|
} else {
|
||
|
this.controllingBall.getComponent(RigidBody2D).linearVelocity = Vec2.ZERO;
|
||
|
let randonPos = randomRangeInt(0, this.startPositions.length);
|
||
|
this.controllingBall.parent = this.node;
|
||
|
|
||
|
this.controllingBall.setPosition(this.startPositions[randonPos].x, this.startPositions[randonPos].y, 0);
|
||
|
this.controllingBall.active = true;
|
||
|
}
|
||
|
SoundManager.Instance().PlayOneShot(SoundManager.Instance().whistle);
|
||
|
}
|
||
|
public SpawnBallInTime(time: number): void {
|
||
|
if (this.ball <= 0) return;
|
||
|
if (this.currentGameState == GameState.EndGame) return;
|
||
|
//this.unscheduleAllCallbacks();
|
||
|
console.log(this.currentGameState.toString());
|
||
|
|
||
|
this.scheduleOnce(() => {
|
||
|
this.SpawnBall();
|
||
|
}, time);
|
||
|
this.SetupObstacle();
|
||
|
}
|
||
|
//#region Events
|
||
|
public AddScore(score: number): void {
|
||
|
this.score += score;
|
||
|
this.streak++;
|
||
|
this.eventUpdateStreak.emit(EventType.UpdateStreak, this.streak);
|
||
|
this.ball--;
|
||
|
|
||
|
if (this.streak > 2) {
|
||
|
let addBall = this.streak - 2;
|
||
|
this.ball += addBall;
|
||
|
}
|
||
|
|
||
|
if (this.highestStreak < this.streak) {
|
||
|
this.highestStreak = this.streak;
|
||
|
this.eventUpdateHighestStreak.emit(EventType.UpdateHighestStreak, this.highestStreak);
|
||
|
}
|
||
|
this.eventUpdateBall.emit(EventType.UpdateBall, this.ball);
|
||
|
|
||
|
this.eventUpdateScore.emit(EventType.UpdateScore, this.score);
|
||
|
|
||
|
SoundManager.Instance().PlayOneShot(SoundManager.Instance().sfxGoal);
|
||
|
|
||
|
if (this.ball <= 0)
|
||
|
this.ChangeGameState(GameState.EndGame);
|
||
|
else this.SpawnBallInTime(1);
|
||
|
}
|
||
|
public LoseStreak(): void {
|
||
|
this.streak = 0;
|
||
|
this.eventUpdateStreak.emit(EventType.UpdateStreak, this.streak);
|
||
|
this.ball--;
|
||
|
this.eventUpdateBall.emit(EventType.UpdateBall, this.ball);
|
||
|
if (this.ball <= 0)
|
||
|
this.ChangeGameState(GameState.EndGame);
|
||
|
else this.SpawnBallInTime(1);
|
||
|
|
||
|
}
|
||
|
public ChangeGameState(newState: GameState): void {
|
||
|
if (this.currentGameState == newState) return;
|
||
|
|
||
|
this.currentGameState = newState;
|
||
|
this.StateChangeHandle();
|
||
|
}
|
||
|
private StateChangeHandle(): void {
|
||
|
switch (this.currentGameState) {
|
||
|
case GameState.MainMenu:
|
||
|
this.eventMenuGame.emit(EventType.MainMenu);
|
||
|
|
||
|
break;
|
||
|
case GameState.StartGame:
|
||
|
|
||
|
this.eventStartGame.emit(EventType.StartGame);
|
||
|
this.SpawnBallInTime(this.startGameCountDown);
|
||
|
this.levelController.LevelUp();
|
||
|
BEConnector.instance.ticketMinus("auth");
|
||
|
|
||
|
break;
|
||
|
case GameState.PlayGame:
|
||
|
this.eventUpdateBall.emit(EventType.UpdateBall, this.ball);
|
||
|
this.eventPlayGame.emit(EventType.PlayGame);
|
||
|
break;
|
||
|
case GameState.EndGame:
|
||
|
this.eventEndGame.emit(EventType.EndGame);
|
||
|
BEConnector.instance.postScoreToServer(this.score);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public SetBall(ball: number): void {
|
||
|
this.ball = ball;
|
||
|
this.eventUpdateBall.emit(EventType.UpdateBall, this.ball);
|
||
|
}
|
||
|
//#endregion
|
||
|
|
||
|
|
||
|
private SetupObstacle(): void {
|
||
|
if (this.score < this.scoreToSpawnObstacle + 2)
|
||
|
return;
|
||
|
this.eventSpawnObstacle.emit("SpawnObstacle");
|
||
|
// this.harderObstacle.active = true;
|
||
|
}
|
||
|
private ObstacleHitControl(node: Node): void {
|
||
|
node.active = false;
|
||
|
this.scheduleOnce(function () {
|
||
|
node.active = true;
|
||
|
}, 3);
|
||
|
}
|
||
|
private GoalControl(): void {
|
||
|
this.particle.node.setPosition(this.controllingBall.position);
|
||
|
this.particle.resetSystem();
|
||
|
}
|
||
|
|
||
|
public OnRevive(): void {
|
||
|
this.uiController.ShutEndPnl();
|
||
|
this.ball += 5;
|
||
|
this.eventUpdateBall.emit(EventType.UpdateBall, this.ball);
|
||
|
this.SpawnBallInTime(1);
|
||
|
}
|
||
|
}
|