feat: web flow

main
tiendat3699 2024-03-26 14:28:59 +07:00
parent a2a735f97f
commit a45a461a85
11 changed files with 2623 additions and 420 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,23 @@
import { _decorator } from 'cc';
import * as CryptoES from 'crypto-es';
import { GameManager } from '../Manager/GameManager';
import Utilities from '../Utilities';
export let CryptoESDefault = CryptoES.default;
const { ccclass, property } = _decorator;
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;
GameManager.instance.gameRelive();
}
}
});
@ccclass('BEConnector')
export default class BEConnector {
public static _instance: BEConnector = null;
@ -18,6 +31,7 @@ export default class BEConnector {
// Ticket infors
public numberTicket: number;
public maxScore: number;
public currentScore: number;
private mileStone: string;
private gameURL: string = '';
@ -43,6 +57,7 @@ export default class BEConnector {
this.numberTicket = parseInt(url.get('numberTicket'));
this.maxScore = parseInt(url.get('maxScore'));
this.currentScore = parseInt(url.get('currentScore')) || 0;
this.mileStone = url.get('mileStone');
this.gameURL = ENV_CONFIG[url.get('env')];
}
@ -115,19 +130,15 @@ export default class BEConnector {
public postMessage() {
let totalScore: number = GameManager.instance.score;
// window.parent.postMessage(
// JSON.stringify({
// error: false,
// message: "Hello World",
// score: totalScore,
// type: "paypal_modal",
// }),
// "*"
// );
setTimeout(() => {
BEConnector.instance.numberTicket += 5;
GameManager.instance.onRevive();
}, 2000);
window.parent.postMessage(
JSON.stringify({
error: false,
message: 'Hello World',
score: totalScore,
type: 'paypal_modal',
}),
'*',
);
}
public postScoreToServer(score: number) {
@ -155,7 +166,7 @@ export default class BEConnector {
JSON.stringify({
error: false,
message: 'Hello World',
score: score,
score: score + this.currentScore,
type: 'game_tournament',
}),
'*',

View File

@ -2,6 +2,8 @@ enum GameState {
Init,
Playing,
GameOver,
End,
Relive,
}
export default GameState;

View File

@ -22,8 +22,21 @@ import ScoreType from '../Enum/ScoreType';
import { FloatingText } from '../Environments/FloatingText';
import { SoundManager } from './SoundManager';
import TimeConfig from '../Enum/TimeConfig';
import BEConnector from '../API/BEConnector';
const { ccclass, property } = _decorator;
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;
GameManager.instance.gameRelive();
}
}
});
@ccclass('GameManager')
export class GameManager extends Component {
//singleton
@ -55,6 +68,7 @@ export class GameManager extends Component {
private _timer: number;
private _score = 0;
private isReplayed = false;
private _isMultiBall = false;
private _currentBallInGame = 0;
@ -84,9 +98,29 @@ export class GameManager extends Component {
EventManger.instance.emit(GameEvent.TimeUpdate, this._timer);
}
private changeGameState(state: GameState) {
private async changeGameState(state: GameState) {
this._gameState = state;
EventManger.instance.emit(GameEvent.GameStateChange, this._gameState);
switch (state) {
case GameState.Init:
BEConnector.instance.authenticate();
break;
case GameState.Playing:
BEConnector.instance.ticketMinus('auth');
break;
case GameState.GameOver:
break;
case GameState.End:
await Utilities.delay(3);
BEConnector.instance.postScoreToServer(this._score);
break;
case GameState.Relive:
BEConnector.instance.ticketMinus('revive');
break;
default:
throw new Error(`Argument Out Of Range Exception: ${GameState[state]}`);
}
}
private addScore(score: number, type: ScoreType, position: Vec3) {
@ -164,7 +198,13 @@ export class GameManager extends Component {
this._timer += time;
}
private gameOver() {
public gameOver() {
if (this.isReplayed) {
this.changeGameState(GameState.End);
return;
}
this.isReplayed = true;
this._ballPool.releaseAll();
this.changeGameState(GameState.GameOver);
}
@ -180,7 +220,14 @@ export class GameManager extends Component {
this.spawnBall(true);
}
public onRevive() {
throw new Error('Method not implemented.');
public async gameRelive() {
this.changeGameState(GameState.Relive);
this._timer = 60 + TimeConfig.DelayPLay;
this._currentBallInGame = 0;
this._isMultiBall = false;
SoundManager.instance.playBGM(this._backgroundMusic, 0.5);
this.changeGameState(GameState.Playing);
await Utilities.delay(TimeConfig.DelayPLay);
this.spawnBall(true);
}
}

View File

@ -101,9 +101,6 @@ export class SpawnObjectManager extends Component {
private onGameStateChange(state: GameState) {
switch (state) {
case GameState.Init:
break;
case GameState.Playing:
this._playing = true;
this._weights = this._objects.map((obj) => {
obj.currentWeight = obj.weight;
return obj.currentWeight;
@ -112,10 +109,11 @@ export class SpawnObjectManager extends Component {
this.spawn();
}
break;
case GameState.Playing:
this._playing = true;
break;
case GameState.GameOver:
this._playing = false;
this._objects.forEach((object) => (object.currentWeight = object.weight));
this._pools.forEach((pool) => pool.releaseAll());
break;
}
}

View File

@ -0,0 +1,32 @@
import { _decorator, Component, Label, Node } from 'cc';
import BEConnector from '../API/BEConnector';
import { GameManager } from '../Manager/GameManager';
const { ccclass, property } = _decorator;
@ccclass('ConfirmPanel')
export class ConfirmPanel extends Component {
@property(Label) ticketWaringText: Label = null;
protected onEnable(): void {
this.ticketWaringText.string = `To continue playing, you will be deducted ${BEConnector.instance.getTicketCanBeMinus()} ticket`;
}
onClickYesButton() {
if (BEConnector.instance.canRelive()) {
BEConnector.instance
.checkGameScoreTicket()
.then(() => {
GameManager.instance.gameRelive();
})
.catch(() => {
GameManager.instance.gameOver();
});
} else {
BEConnector.instance.postMessage();
}
}
onClickNoButton() {
this.node.active = false;
}
}

View File

@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "99bfd134-ace2-424f-b5da-79474dd94bd9",
"uuid": "a0ece421-9b71-46f8-a587-35d6a5991259",
"files": [],
"subMetas": {},
"userData": {}

View File

@ -1,137 +0,0 @@
import { _decorator, Button, CCInteger, Component, EventTarget, Label, Node, EventTouch } from 'cc';
import BEConnector from '../API/BEConnector';
import { GameManager } from '../Manager/GameManager';
const { ccclass, property } = _decorator;
export enum PanelState {
NotShowing,
CompareScore,
Continue,
ShowResult,
}
@ccclass('EndGameUIController')
export class EndGameUIController extends Component {
@property(CCInteger)
private countdownTime: number = 15;
private currentCD: number = 15;
private isContinuable: boolean = true;
private isEndGameByTime: boolean = false;
private currentState: PanelState = PanelState.NotShowing;
// Texts
@property(Label)
private yourScoreTxt: Label = null;
@property(Label)
private topScoreTxt: Label = null;
@property(Label)
private continueTxt: Label = null;
@property(Label)
private countdownToReplayTxt: Label = null;
// Buttons
@property(Button)
private yesBtn: Label = null;
@property(Button)
private noBtn: Label = null;
// Panel
@property(Node)
private compareScorePnl: Node = null;
@property(Node)
private continuePnl: Node = null;
@property(Node)
private finalResultPnl: Node = null;
private eventRevive = new EventTarget();
//#region Cocos methods
protected onEnable(): void {
this.Setup();
this.currentCD = this.countdownTime;
}
protected update(dt: number): void {
if (this.isEndGameByTime == true) return;
this.currentCD -= dt;
this.countdownToReplayTxt.string = Math.round(this.currentCD).toString();
if (this.currentCD <= 0 && !this.isEndGameByTime) {
this.currentCD = 0;
this.ChangeState(PanelState.ShowResult);
this.isEndGameByTime = true;
}
}
//#endregion
private Setup(): void {
if (this.isContinuable) this.ChangeState(PanelState.CompareScore);
else this.ChangeState(PanelState.ShowResult);
}
private ChangeState(newState: PanelState): void {
if (this.currentState == newState) return;
this.currentState = newState;
switch (this.currentState) {
case PanelState.CompareScore:
this.TurnOffAllPanels(this.compareScorePnl);
var totalScore = GameManager.instance.score;
this.yourScoreTxt.string = 'Your score: ' + totalScore;
/// Todo: set top score here
break;
case PanelState.Continue:
this.TurnOffAllPanels(this.continuePnl);
var ticket = BEConnector.instance.numberTicket;
if (ticket >= BEConnector.instance.getTicketCanBeMinus()) {
this.continueTxt.string =
'To continue playing, you will be deducted ' + ticket + ' Extras. Do you want to proceed?';
} else {
this.continueTxt.string =
"You don't have enough Extras to continue playing. Would you like to buy more tickets?";
}
break;
case PanelState.ShowResult:
this.yesBtn.node.active = false;
this.noBtn.node.active = false;
this.countdownToReplayTxt.node.active = false;
this.TurnOffAllPanels(this.finalResultPnl);
BEConnector.instance.postScoreToServer(GameManager.instance.score);
break;
}
}
private TurnOffAllPanels(activePnl: Node): void {
this.compareScorePnl.active = false;
this.continuePnl.active = false;
this.finalResultPnl.active = false;
if (activePnl != null) activePnl.active = true;
}
public YesNoClick(e: EventTouch, yesNoString: string): void {
var isYesClick = true;
if (yesNoString == 'true') isYesClick = true;
else isYesClick = false;
switch (this.currentState) {
case PanelState.CompareScore:
if (isYesClick) this.ChangeState(PanelState.Continue);
else this.ChangeState(PanelState.ShowResult);
break;
case PanelState.Continue:
if (isYesClick) {
var ticket = BEConnector.instance.getTicketCanBeMinus();
if (BEConnector.instance.numberTicket >= ticket) {
GameManager.instance.onRevive();
BEConnector.instance.ticketMinus('revive');
this.isContinuable = false;
} else BEConnector.instance.postMessage();
} else {
this.ChangeState(PanelState.CompareScore);
}
break;
}
}
}

View File

@ -0,0 +1,34 @@
import { _decorator, Component, Label, Node } from 'cc';
import BEConnector from '../API/BEConnector';
import { GameManager } from '../Manager/GameManager';
const { ccclass, property } = _decorator;
@ccclass('GameOverPanel')
export class GameOverPanel extends Component {
@property(Label) private topScore: Label = null;
@property(Label) private yourScore: Label = null;
@property(Node) private confirmPanel: Node = null;
protected onEnable(): void {
let currentScore = BEConnector.instance.currentScore + GameManager.instance.score;
this.topScore.string = BEConnector.instance.maxScore.toString();
this.yourScore.string = currentScore.toString();
this.scheduleOnce(this.endGame, 60);
}
onClickYesButton() {
this.confirmPanel.active = true;
}
onClickNoButton() {
GameManager.instance.gameOver();
}
protected onDisable(): void {
this.unschedule(this.endGame);
}
private endGame() {
GameManager.instance.gameOver();
}
}

View File

@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "c5e2d9b4-a975-4eb8-a3f5-8eeeeec8cb49",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -3,6 +3,8 @@ import { EventManger } from '../Manager/EventManger';
import GameEvent from '../Events/GameEvent';
import ScoreType from '../Enum/ScoreType';
import GameState from '../Enum/GameState';
import { GameManager } from '../Manager/GameManager';
import BEConnector from '../API/BEConnector';
const { ccclass, property } = _decorator;
@ccclass('UIController')
@ -13,6 +15,8 @@ export class UIController extends Component {
private _eventLabel: Label;
@property({ type: Label, visible: true })
private _resultLabel: Label;
@property({ type: Label, visible: true })
private _resultTotalLabel: Label;
@property({ type: ParticleSystem, visible: true })
private _buffFx: ParticleSystem;
@property({ type: Node, visible: true })
@ -21,10 +25,8 @@ export class UIController extends Component {
private _overPanel: Node;
@property({ type: Label, visible: true })
private _timeLabe: Label;
@property({ type: Label, visible: true })
private _timeResult: Label;
private _timer = 0;
private _playing = false;
@property({ type: Node, visible: true })
private _resultPanel: Node = null;
protected async onLoad() {
EventManger.instance.on(GameEvent.Score, this.onScore, this);
@ -35,10 +37,6 @@ export class UIController extends Component {
this._eventLabel.string = '';
}
protected update(dt: number): void {
if (this._playing) this._timer += dt;
}
private async onScore(score: number, type: ScoreType) {
this._scoreLabel.string = `Score: ${score}`;
if (type == ScoreType.Goal) {
@ -76,18 +74,25 @@ export class UIController extends Component {
this._startPanel.active = true;
break;
case GameState.Playing:
this._timer = 0;
this._playing = true;
this._scoreLabel.string = 'Score: 0';
this._startPanel.active = false;
this._overPanel.active = false;
break;
case GameState.GameOver:
this._buffFx.stop();
this._playing = false;
this._overPanel.active = true;
this._resultLabel.string = this._scoreLabel.string;
this._timeResult.string = this.secondsToTime(this._timer);
break;
case GameState.End:
this._overPanel.active = false;
this._resultPanel.active = true;
this._resultLabel.string = GameManager.instance.score.toString();
this._resultTotalLabel.string = (
GameManager.instance.score + BEConnector.instance.currentScore
).toString();
break;
case GameState.Relive:
this._overPanel.active = false;
break;
}
}