pinball/assets/Scripts/GameplayController.ts

241 lines
8.0 KiB
TypeScript
Raw Normal View History

2024-02-28 03:25:11 -08:00
import {
_decorator,
CCInteger,
Component,
Enum,
EventTarget,
instantiate,
Node,
ParticleSystem,
ParticleSystem2D,
Prefab,
randomRangeInt,
RigidBody2D,
Vec2,
} from 'cc';
2024-02-27 18:19:33 -08:00
import { Ball } from './Ball';
import { EventType } from './Enums';
import { SoundManager } from './SoundManager';
import BEConnector from './BEConnector';
import { UIController } from './UIController';
import { LevelController } from './LevelController';
2024-02-28 03:25:11 -08:00
import Utilities from './Utilities/Utilities';
2024-02-27 18:19:33 -08:00
const { ccclass, property } = _decorator;
2024-02-28 03:25:11 -08:00
window.addEventListener('message', (data) => {
const { data: res } = data;
const objectRes = Utilities.getJson(res);
if (objectRes) {
const { type, value } = objectRes;
if (type === 'newTicket') {
BEConnector.instance.numberTicket += value;
GameplayController.Instance().OnRevive();
}
2024-02-27 18:19:33 -08:00
}
2024-02-28 03:25:11 -08:00
});
2024-02-27 18:19:33 -08:00
export enum GameState {
MainMenu,
StartGame,
PlayGame,
2024-02-28 03:25:11 -08:00
EndGame,
2024-02-27 18:19:33 -08:00
}
@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;
2024-02-28 03:25:11 -08:00
@property(ParticleSystem)
public particle: ParticleSystem = null;
2024-02-27 18:19:33 -08:00
@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;
2024-02-28 03:25:11 -08:00
const ball = this.controllingBall.getComponent(Ball);
ball.eventHitObstacle.on('HitObstacle', this.ObstacleHitControl, this);
ball.getComponent(Ball).eventGoal.on('Goal', this.GoalControl, this);
2024-02-27 18:19:33 -08:00
return;
} else {
2024-02-28 03:25:11 -08:00
const rigi = this.controllingBall.getComponent(RigidBody2D);
rigi.angularVelocity = 0;
rigi.linearVelocity = Vec2.ZERO.clone();
2024-02-27 18:19:33 -08:00
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;
2024-02-28 03:25:11 -08:00
this.controllingBall.getComponent(Ball).resetTrail();
2024-02-27 18:19:33 -08:00
}
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);
2024-02-28 03:25:11 -08:00
if (this.ball <= 0) this.ChangeGameState(GameState.EndGame);
2024-02-27 18:19:33 -08:00
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);
2024-02-28 03:25:11 -08:00
if (this.ball <= 0) this.ChangeGameState(GameState.EndGame);
2024-02-27 18:19:33 -08:00
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();
2024-02-28 03:25:11 -08:00
BEConnector.instance.ticketMinus('auth');
2024-02-27 18:19:33 -08:00
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 {
2024-02-28 03:25:11 -08:00
if (this.score < this.scoreToSpawnObstacle + 2) return;
this.eventSpawnObstacle.emit('SpawnObstacle');
2024-02-27 18:19:33 -08:00
// this.harderObstacle.active = true;
}
private ObstacleHitControl(node: Node): void {
node.active = false;
this.scheduleOnce(function () {
node.active = true;
}, 3);
}
private GoalControl(): void {
2024-02-28 03:25:11 -08:00
const pos = this.controllingBall.position.clone();
pos.z = this.particle.node.position.z;
this.particle.node.setPosition(pos);
this.particle.play();
2024-02-27 18:19:33 -08:00
}
public OnRevive(): void {
this.uiController.ShutEndPnl();
this.ball += 5;
this.eventUpdateBall.emit(EventType.UpdateBall, this.ball);
this.SpawnBallInTime(1);
}
2024-02-28 03:25:11 -08:00
}