import { Game, director } from "cc"; import { RoomMgr } from "../../module_basic/scripts/RoomMgr"; import { UserMgr } from "../../module_basic/scripts/UserMgr"; import { gameNet } from "../../module_basic/scripts/NetGameServer"; import { IGameData, IGamePlayer, } from "../../module_basic/shared/protocols/public/game/GameTypeDef"; import { MsgFoodAddedPush } from "../../module_basic/shared/protocols/public/game/MsgFoodAddedPush"; import { MsgFoodEatenPush } from "../../module_basic/shared/protocols/public/game/MsgFoodEatenPush"; import { MsgGameBeginPush } from "../../module_basic/shared/protocols/public/game/MsgGameBeginPush"; import { MsgGameDataChangedPush } from "../../module_basic/shared/protocols/public/game/MsgGameDataChangedPush"; import { MsgGameDataSyncPush } from "../../module_basic/shared/protocols/public/game/MsgGameDataSyncPush"; import { MsgGameOverPush } from "../../module_basic/shared/protocols/public/game/MsgGameOverPush"; import { MsgPlayerComesPush } from "../../module_basic/shared/protocols/public/game/MsgPlayerComesPush"; import { MsgPlayerDataChangedPush } from "../../module_basic/shared/protocols/public/game/MsgPlayerDataChangedPush"; import { MsgPlayerLeavesPush } from "../../module_basic/shared/protocols/public/game/MsgPlayerLeavesPush"; import { MsgCellDataChange } from "../../module_basic/shared/protocols/public/game/MsgCellDataChange"; export class GameEvent { public static PLAYER_COMES = "GameEvent.PLAYER_COMES"; public static PLAYER_LEAVES = "GameEvent.PLAYER_LEAVES"; public static PLAYER_DATA_CHANGED = "GameEvent.PLAYER_DATA_CHANGED"; public static GAME_BEGIN = "GameEvent.GAME_BEGIN"; public static GAME_OVER = "GameEvent.GAME_OVER"; public static CELL_DATA_CHANGED = "GameEvent.CELL_DATA_CHANGED"; public static FOOD_EATEN = "GameEvent.FOOD_EATEN"; public static FOOD_ADDED = "GameEvent.FOOD_ADDED"; public static PLAYER_DIE = "GameEvent.PLAYER_DIE"; public static PLAYER_REVIVE = "GameEvent.PLAYER_REVIVE"; public static GAME_DATA_CHANGED = "GameEvent.GAME_DATA_CHANGED"; public static GAME_EXIT = "GameEvent.GAME_EXIT"; } export class Skill { public static SKILL_1 = 1000; public static SKILL_2 = 1001; public id: number; public cd: number; } export class SillCastInfo { skill: Skill; lastCastTime: number; get isInCD() { let cdTime = this.lastCastTime + this.skill.cd - Date.now(); return cdTime > 0; } get cdPercent() { let cdTime = this.lastCastTime + this.skill.cd - Date.now(); if (cdTime <= 0) { return 0.0; } return cdTime / this.skill.cd; } } const skillMap = {}; skillMap[Skill.SKILL_1] = { id: Skill.SKILL_1, cd: 2000 }; skillMap[Skill.SKILL_2] = { id: Skill.SKILL_1, cd: 30000 }; export class GameMgr { private static _inst: GameMgr; public static get inst(): GameMgr { if (!this._inst) { this._inst = new GameMgr(); } return this._inst; } constructor() { this.initNetMsgHandlers(); } public localGameOver() { this._gameData.gameState = "gameover"; } public reset() { this._gameData = null; this._playerMap = {}; this._skillCdMap = {}; } private _gameData: IGameData; private _gameStateEndTime: number = 0; private _playerMap: { [key: number]: IGamePlayer } = {}; private _skillCdMap: { [key: number]: SillCastInfo } = {}; private _selfPlayer: IGamePlayer; public get selfPlayer(): IGamePlayer { return this._selfPlayer; } public localMode(p: IGameData) { this._gameData = p; } public get gameData(): Readonly { return this._gameData; } public get gameStateEndTime(): number { return this._gameStateEndTime; } public castSkill(skillId: number) { let skill = skillMap[skillId]; if (!skill) { return false; } let cdInfo = this._skillCdMap[skillId]; if (!cdInfo) { cdInfo = new SillCastInfo(); cdInfo.skill = skill; cdInfo.lastCastTime = 0; this._skillCdMap[skillId] = cdInfo; } if (cdInfo.isInCD) { return false; } cdInfo.lastCastTime = Date.now(); return true; } public getSkillCd(skillId: number) { return this._skillCdMap[skillId]; } initNetMsgHandlers() { gameNet.listenMsg( "game/GameDataSyncPush", this.onNet_GameDataSyncPush, this ); gameNet.listenMsg( "game/GameDataChangedPush", this.onNet_GameDataChangedPush, this ); gameNet.listenMsg("game/PlayerComesPush", this.onNet_PlayerComesPush, this); gameNet.listenMsg( "game/PlayerDataChangedPush", this.onNet_PlayerDataChangedPush, this ); gameNet.listenMsg( "game/PlayerLeavesPush", this.onNet_PlayerLeavesPush, this ); gameNet.listenMsg("game/GameBeginPush", this.onNet_GameBeginPush, this); gameNet.listenMsg("game/GameOverPush", this.onNet_GameOverPush, this); gameNet.listenMsg("game/CellDataChange", this.onNet_CellDataChange, this); gameNet.listenMsg("game/FoodEatenPush", this.onNet_FoodEatenPush, this); gameNet.listenMsg("game/FoodAddedPush", this.onNet_FoodAddedPush, this); } sendMsg_CellDataChange(x: number, y: number, z: number, rotation: number) { gameNet.sendMsg("game/CellDataChange", { transform: [x, y, z, rotation] }); } private get selfPlayerIndex(): number { return this.getPlayerIndex(UserMgr.inst.uid); } public get leftUserId(): string { if (!this._gameData || this._gameData.players.length == 0) { return ""; } if (RoomMgr.inst.isPlayer) { return UserMgr.inst.uid; } else { return this._gameData.players[0].uid; } } public get rightUserId(): string { if (!this._gameData || this._gameData.players.length == 0) { return ""; } if (RoomMgr.inst.isPlayer) { if (this._gameData.players[0].uid != UserMgr.inst.uid) { return this._gameData.players[0].uid; } else { let p = this._gameData.players[1]; return p ? p.uid : ""; } } else { let p = this._gameData.players[1]; return p ? p.uid : ""; } } public getPlayer(playerId: number): IGamePlayer { if (!this._gameData || !this._gameData.players) { return null; } for (let i = 0; i < this._gameData.players.length; ++i) { let p = this._gameData.players[i]; if (p.playerId == playerId) { return p; } } return null; } private getPlayerIndex(userId: string): number { for (let i = 0; i < this._gameData.players.length; ++i) { if (this._gameData.players[i].uid == userId) { return i; } } return -1; } // ============= MESSAGE HANDLER ============ /** * This message will arrive before login result. * 这个消息会在登录成功返回之前收到。 */ onNet_GameDataSyncPush(msg: MsgGameDataSyncPush) { this._gameData = msg.data; this._gameData.players.forEach((v) => { this._playerMap[v.playerId] = v; if (v.uid == UserMgr.inst.uid) { this._selfPlayer = v; } }); this._gameStateEndTime = this._gameData.gameStateRemainingTime + Date.now(); } onNet_GameDataChangedPush(msg: MsgGameDataChangedPush) { if (!this._gameData) { return; } if (msg.gameState != undefined) { this._gameData.gameState = msg.gameState; } if (msg.gameStateRemainingTime != undefined) { this._gameData.gameStateRemainingTime = msg.gameStateRemainingTime; this._gameStateEndTime = this._gameData.gameStateRemainingTime + Date.now(); } if (msg.teamWeights != undefined) { for (let teamId in msg.teamWeights) { let score = msg.teamWeights[teamId]; this._gameData.teamsWeights[teamId] = score; } } director.emit(GameEvent.GAME_DATA_CHANGED, msg); } onNet_PlayerComesPush(msg: MsgPlayerComesPush) { this._gameData.players.push(msg.player); this._playerMap[msg.player.playerId] = msg.player; if (msg.player.uid == UserMgr.inst.uid) { this._selfPlayer = msg.player; } director.emit(GameEvent.PLAYER_COMES, msg.player); } onNet_PlayerDataChangedPush(msg: MsgPlayerDataChangedPush) { let p = this.getPlayer(msg.playerId); if (!p) { return; } for (let k in msg) { p[k] = msg[k]; } if (msg.reviveTime != undefined) { if (msg.reviveTime > 0) { director.emit(GameEvent.PLAYER_DIE, p); } else { director.emit(GameEvent.PLAYER_REVIVE, p); } } director.emit(GameEvent.PLAYER_DATA_CHANGED, msg); } onNet_PlayerLeavesPush(msg: MsgPlayerLeavesPush) { for (let i = 0; i < this._gameData.players.length; ++i) { let p = this._gameData.players[i]; if (p.uid == msg.uid) { this._gameData.players.splice(i, 1); delete this._playerMap[p.playerId]; director.emit(GameEvent.PLAYER_LEAVES, p); break; } } } onNet_GameBeginPush(msg: MsgGameBeginPush) { if (!this._gameData) { return; } this._gameData.players.forEach((v) => { //v.color = ''; }); director.emit(GameEvent.GAME_BEGIN); } onNet_GameOverPush(msg: MsgGameOverPush) { director.emit(GameEvent.GAME_OVER, msg); } onNet_CellDataChange(msg: MsgCellDataChange) { let p = this.getPlayer(msg.playerId); for (let k in msg) { p[k] = msg[k]; } director.emit(GameEvent.CELL_DATA_CHANGED, msg); } onNet_FoodEatenPush(msg: MsgFoodEatenPush) { for (let i = 0; i < msg.eatenFoods.length; i++) { let foodId = msg.eatenFoods[i]; delete this._gameData.foodList[foodId]; } director.emit(GameEvent.FOOD_EATEN, msg); } onNet_FoodAddedPush(msg: MsgFoodAddedPush) { for (let i = 0; i < msg.foods.length; ++i) { let fd = msg.foods[i]; this._gameData.foodList[fd.id] = fd; } director.emit(GameEvent.FOOD_ADDED, msg); } } GameMgr.inst;