diff --git a/src/cfg/GameEnv.ts b/src/cfg/GameEnv.ts index 8b911be..f3a5d47 100644 --- a/src/cfg/GameEnv.ts +++ b/src/cfg/GameEnv.ts @@ -34,6 +34,8 @@ export class GameEnv { public baseAddScore: number; // 额外奖励分 public extraAddScore: number; + // 游戏结果显示时间, 也是游戏重开等待时间 + public gameResultTime: number; public init(data: Map) { this.initCardNum = data.get(BaseConst.INIT_CARD_NUM).value; @@ -52,5 +54,6 @@ export class GameEnv { this.resultShowTime = data.get(BaseConst.ROUND_SHOW_TIME).value; this.baseAddScore = data.get(BaseConst.BASE_ADD_SCORE).value; this.extraAddScore = data.get(BaseConst.EXTRA_ADD_SCORE).value; + this.gameResultTime = data.get(BaseConst.GAME_RESULT_TIME).value; } } diff --git a/src/constants/BaseConst.ts b/src/constants/BaseConst.ts index b026dc5..63a93ab 100644 --- a/src/constants/BaseConst.ts +++ b/src/constants/BaseConst.ts @@ -31,6 +31,8 @@ export class BaseConst { public static readonly BASE_ADD_SCORE = 99015; // 额外奖励分 public static readonly EXTRA_ADD_SCORE = 99016; + // 游戏结果显示时间, 也是游戏重开等待时间 + public static readonly GAME_RESULT_TIME = 99017; diff --git a/src/rooms/GeneralRoom.ts b/src/rooms/GeneralRoom.ts index 51c7ffe..94b6319 100644 --- a/src/rooms/GeneralRoom.ts +++ b/src/rooms/GeneralRoom.ts @@ -16,12 +16,13 @@ import {IncomingMessage} from "http"; import {PlayerStateConst} from "../constants/PlayerStateConst"; import {Player} from "./schema/Player"; import {GMCommand} from "./commands/GMCommand"; +import {GameStateConst} from "../constants/GameStateConst"; +import {GameRestartCommand} from "./commands/GameRestartCommand"; export class GeneralRoom extends Room { dispatcher = new Dispatcher(this); maxClients = 4; - clientMap = new Map(); battleMan = new BattleHandler(); // 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家 mainClock: Delayed; @@ -75,6 +76,11 @@ export class GeneralRoom extends Room { this.dispatcher.dispatch(new GMCommand(), {client, message}); }); + this.onMessage("restart_c2s", (client, message) => { + msgLog('restart game from ', client.sessionId, message); + this.dispatcher.dispatch(new GameRestartCommand(), {client}); + }); + this.onMessage("*", (client, type, message) => { // // Triggers when any other type of message is sent, @@ -90,7 +96,6 @@ export class GeneralRoom extends Room { client: client }; this.dispatcher.dispatch(new OnJoinCommand(), data); - this.clientMap.set(client.sessionId, client); } //TODO: 掉线逻辑 async onLeave (client: Client, consented: boolean) { @@ -106,6 +111,9 @@ export class GeneralRoom extends Room { // } catch (e) { // this.state.players.delete(client.sessionId); // } + if (this.state.gameSate === GameStateConst.STATE_GAME_OVER) { + this.state.players.delete(client.id); + } } onDispose() { diff --git a/src/rooms/commands/GameRestartCommand.ts b/src/rooms/commands/GameRestartCommand.ts new file mode 100644 index 0000000..65f162c --- /dev/null +++ b/src/rooms/commands/GameRestartCommand.ts @@ -0,0 +1,16 @@ +import {Command} from "@colyseus/command"; +import {CardGameState} from "../schema/CardGameState"; +import {Client} from "colyseus"; +import {PlayReadyCommand} from "./PlayReadyCommand"; + + +export class GameRestartCommand extends Command { + + execute({client} = this.payload) { + this.state.restartCount ++; + if (this.state.restartCount >= this.room.maxClients) { + this.room.stopSchedule(); + } + return [new PlayReadyCommand().setPayload({client})]; + } +} diff --git a/src/rooms/commands/GameResultCommand.ts b/src/rooms/commands/GameResultCommand.ts index cd5dae8..56078a4 100644 --- a/src/rooms/commands/GameResultCommand.ts +++ b/src/rooms/commands/GameResultCommand.ts @@ -1,15 +1,78 @@ import {Command} from "@colyseus/command"; import {CardGameState} from "../schema/CardGameState"; import {GameStateConst} from "../../constants/GameStateConst"; +import {PlayerStateConst} from "../../constants/PlayerStateConst"; +import {Pet} from "../schema/Pet"; +import {singleton} from "../../common/Singleton"; +import {GameEnv} from "../../cfg/GameEnv"; +import {error} from "../../common/Debug"; /** * 游戏结束 */ export class GameResultCommand extends Command { - execute() { + async execute() { this.room.bGameResult({}); this.state.gameState = GameStateConst.STATE_GAME_OVER; + this.resetAllState(); + //TODO: 启动定时, 时间到后, 踢出没离开且没点重玩的玩家, 并将房间设为非private + let self = this; + let resultTimeOver = async function () { + let restartCount = 0; + // 踢出没离开并没点击重新开始的玩家 + for (let [,player] of self.state.players) { + if (player.state !== PlayerStateConst.PLAYER_READY) { + let client = self.room.getClient(player); + client.leave(); + } else { + restartCount ++; + } + } + if (restartCount == 0) { + // 没有任何人点重新开始, 则解散房间 + await self.room.disconnect(); + } else if (restartCount < self.room.maxClients){ + // 如果点击重开的玩家少于房间最大人数, 则把房间设为公开, 等待其他玩家匹配进来 + await self.room.unlock(); + await self.room.setPrivate(false); + } else { // 如果4个人都点击了重开, 理论上不存在这种情况 + error(`所有人都点击了重新开始, 为啥还没开始游戏???`); + } + } + let time = singleton(GameEnv).gameResultTime * 1000; + this.room.beginSchedule(time, resultTimeOver, 'restart_schedule'); + } + + /** + * 重置所有状态 + */ + resetAllState() { + this.state.restartCount = 0; + this.state.currentTurn = undefined; + this.state.subTurn = undefined; + this.state.round = 0; + this.state.cardQueue.length = 0; + this.state.cards.clear(); + + for (let [,player] of this.state.players) { + player.cards.clear(); + player.cardSet.clear(); + player.countTotal = 0; + player.countPresent = 0; + for(let [,pet] of player.pets) { + this.resetPet(pet); + } + } + } + resetPet(pet: Pet) { + pet.state = 0; + pet.ap = 0; + pet.id = undefined; + pet.extAp = 0; + pet.harmReduce = 0; + pet.skills.length = 0; + pet.extSkills.length = 0; } } diff --git a/src/rooms/commands/OnJoinCommand.ts b/src/rooms/commands/OnJoinCommand.ts index 4d3a92b..9dccf0d 100644 --- a/src/rooms/commands/OnJoinCommand.ts +++ b/src/rooms/commands/OnJoinCommand.ts @@ -12,6 +12,7 @@ export class OnJoinCommand extends Command { execute({client} = this.payload) { let team = this.state.players.size / 2 | 0; + // 实际的team会在PlayReadyCommand中设置 let player = new Player(client.sessionId, 0, team); this.state.players.set(client.sessionId, player); if (this.state.players.size >= this.room.maxClients) { diff --git a/src/rooms/commands/PlayReadyCommand.ts b/src/rooms/commands/PlayReadyCommand.ts index 107e524..422820d 100644 --- a/src/rooms/commands/PlayReadyCommand.ts +++ b/src/rooms/commands/PlayReadyCommand.ts @@ -24,6 +24,10 @@ export class PlayReadyCommand extends Command= this.room.maxClients) { // 比大小, 确定先手 // return [new PrepareCommand()]; + let i = 0; + for (let [,player] of this.state.players) { + player.team = (i ++ / 2) | 0; + } await this.room.setPrivate(true); this.room.state.gameState = GameStateConst.CHANGE_HERO; } diff --git a/src/rooms/schema/CardGameState.ts b/src/rooms/schema/CardGameState.ts index e8c4b49..d4a483d 100644 --- a/src/rooms/schema/CardGameState.ts +++ b/src/rooms/schema/CardGameState.ts @@ -52,5 +52,9 @@ export class CardGameState extends Schema { * 用于临时存放吃牌的数据 */ tmpActionMap: Map = new Map(); + /** + * 点击重开的玩家数量 + */ + restartCount = 0; }