diff --git a/src/global.d.ts b/src/global.d.ts index bb36731..8a2b03f 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -42,6 +42,12 @@ declare module "colyseus" { */ bUserJoin(data?: any, options?: any): void; + /** + * 广播玩家离开 + * @param data + */ + bUserLeft(data?: any): void; + /** * 给指定用户下发英雄选择结果 * @param client @@ -197,14 +203,16 @@ declare module "colyseus" { * 取消当前room.mainClock的任务 * mainClock任何时候只有一个可执行的任务 * 返回当前剩余的毫秒数 + * @param name */ - stopSchedule(): number; + stopSchedule(name: string): number; /** * 给room.mainClock增加n秒 + * @param name * @param millisecond * @param reason */ - addScheduleTime(millisecond: number, reason?: string): void; + addScheduleTime(millisecond: number, reason?: string, name?: string, ): void; addRobot():void; diff --git a/src/rooms/GeneralRoom.ts b/src/rooms/GeneralRoom.ts index a3511cd..e9e96c9 100644 --- a/src/rooms/GeneralRoom.ts +++ b/src/rooms/GeneralRoom.ts @@ -26,7 +26,7 @@ export class GeneralRoom extends Room { maxClients = 4; battleMan = new BattleHandler(); // 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家 - mainClock: Delayed; + gameClock: Map = new Map(); async onAuth (client:Client, options: any, request: IncomingMessage) { console.log(options); // TODO: 验证用户信息 @@ -40,9 +40,6 @@ export class GeneralRoom extends Room { this.battleMan.init(cs, this); this.clock.start(); this.state.gameState = GameStateConst.STATE_WAIT_JOIN; - this.beginSchedule(1, function (){ - debugRoom('init main clock'); - }, 'init') this.onMessage("play_ready_c2s", (client, message) => { msgLog('play_ready from ', client.sessionId, message); this.dispatcher.dispatch(new PlayReadyCommand(), {client}); @@ -118,6 +115,7 @@ export class GeneralRoom extends Room { //TODO: 检查重新开始后, gameState if (this.state.gameState === GameStateConst.STATE_GAME_OVER) { this.state.players.delete(client.id); + this.bUserLeft(client.id); } } @@ -139,46 +137,75 @@ export class GeneralRoom extends Room { } /** - * 给room.mainClock设定任务 - * mainClock任何时候只有一个可执行的任务 + * 给room.gameClock设定任务 + * gameClock任何时候只有一个可执行的任务 * @param millisecond * @param handler * @param name */ beginSchedule(millisecond: number, handler: Function, name: string): void { debugRoom(`begin schedule: `, name, millisecond / 1000); - if (this.mainClock?.active) { - error(`当前已存在进行中的mainClock: ${this.mainClock['args']}`); - this.mainClock.clear(); + if (this.gameClock.has(name) && this.gameClock.get(name)?.active) { + error(`当前已存在进行中的gameClock: ${name}`); + this.gameClock.get(name).clear(); + this.gameClock.delete(name); } - this.mainClock = this.clock.setTimeout(handler, millisecond , name); + let self = this; + let timeOverFun = function () { + handler && handler(); + } + this.gameClock.set(name, this.clock.setTimeout(timeOverFun, millisecond , name)); } /** - * 取消当前room.mainClock的任务 - * mainClock任何时候只有一个可执行的任务 + * 取消当前room.gameClock的任务 + * gameClock任何时候只有一个可执行的任务 */ - stopSchedule(): number { - debugRoom(`manual stop schedule: ${this.mainClock['args']}`); - if (!this.mainClock.active) { + stopSchedule(name: string): number { + debugRoom(`manual stop schedule: ${name}`); + if (!this.gameClock.has(name)) { return -1; } else { - let time = this.mainClock.elapsedTime; - this.mainClock.clear(); - return time; + let clock = this.gameClock.get(name) + if (!clock.active) { + this.gameClock.delete(name); + return -1; + } else { + let time = clock.elapsedTime; + clock.clear(); + this.gameClock.delete(name); + return time; + } + } } /** - * 给room的mainClock增加n秒 + * 给room的gameClock增加n秒 + * @param name * @param millisecond * @param reason */ - addScheduleTime(millisecond: number, reason?: string): void { - debugRoom(`add schedule for ${this.mainClock['args']}, time: ${millisecond/1000}`); - if (this.mainClock?.active) { - this.mainClock.time += millisecond ; - debugRoom(`schedule remain: ${(this.mainClock.time - this.mainClock.elapsedTime)/1000}`); + addScheduleTime(millisecond: number, reason?: string, name?: string): void { + let current; + let currentName = name; + if (!name) { + for (let [id, clock] of this.gameClock) { + if (clock.active) { + current = clock; + currentName = id; + break; + } + } + } else { + if (this.gameClock.has(name)) { + current = this.gameClock.get(name); + } + } + debugRoom(`add schedule for ${currentName}, time: ${millisecond/1000}, reason: ${reason}`); + if (current) { + current.time += millisecond ; + debugRoom(`schedule for ${name} remain: ${(current.time - current.elapsedTime)/1000}`); } } diff --git a/src/rooms/MSender.ts b/src/rooms/MSender.ts index 8ab14ca..4d10517 100644 --- a/src/rooms/MSender.ts +++ b/src/rooms/MSender.ts @@ -22,6 +22,13 @@ Object.defineProperties(Room.prototype, { }, writable: true }, + + bUserLeft: { + value: function (data?: any) { + this.broadcast("player_left", data); + }, + writable: true + }, /** * 给指定用户下发英雄选择结果 * @param client diff --git a/src/rooms/commands/DiscardCommand.ts b/src/rooms/commands/DiscardCommand.ts index 8ed711a..aac0370 100644 --- a/src/rooms/commands/DiscardCommand.ts +++ b/src/rooms/commands/DiscardCommand.ts @@ -45,7 +45,7 @@ export class DiscardCommand extends Command= 0) { let maxTime = singleton(GameEnv).maxDiscardTime * 1000; let count = elapsedTime - maxTime; @@ -87,7 +87,7 @@ export class DiscardCommand extends Command { self.room.dispatcher.dispatch(new DiscardCommand(), {client, cards: [card.id], dtype: 1}); } } - this.room.beginSchedule(maxTime + player.extraTime, timeOverDraw, `draw_card_${sessionId}`); + this.room.beginSchedule(maxTime + player.extraTime, timeOverDraw, `draw_card`); } } diff --git a/src/rooms/commands/EatConfirmCommand.ts b/src/rooms/commands/EatConfirmCommand.ts index 3c55351..a1d0c6e 100644 --- a/src/rooms/commands/EatConfirmCommand.ts +++ b/src/rooms/commands/EatConfirmCommand.ts @@ -31,7 +31,7 @@ export class EatConfirmCommand extends Command= playerCount) { // 所有人都放弃了, 则取消定时, 直接进入下一轮 - this.room.stopSchedule(); + this.room.stopSchedule('eat_round'); // if (this.room.mainClock?.active) { // this.room.mainClock.clear(); // } @@ -70,7 +70,7 @@ export class EatConfirmCommand extends Command execute({client} = this.payload) { this.state.restartCount ++; if (this.state.restartCount >= this.room.maxClients) { - this.room.stopSchedule(); + this.room.stopSchedule('restart_schedule'); } return [new PlayReadyCommand().setPayload({client})]; } diff --git a/src/rooms/commands/GameResultCommand.ts b/src/rooms/commands/GameResultCommand.ts index 793478c..c7d2848 100644 --- a/src/rooms/commands/GameResultCommand.ts +++ b/src/rooms/commands/GameResultCommand.ts @@ -79,7 +79,7 @@ export class GameResultCommand extends Command { await self.room.unlock(); await self.room.setPrivate(false); - //TODO:: 开启匹配定时, 长时间没匹配到人的话, 添加机器人 + //开启匹配定时, 长时间没匹配到人的话, 添加机器人 let timeOutWaitingPlayer = function () { let count = self.room.maxClients - self.room.clients.length; if (count > 0) { diff --git a/src/rooms/commands/NextSubCommand.ts b/src/rooms/commands/NextSubCommand.ts index b59dad0..048bcb1 100644 --- a/src/rooms/commands/NextSubCommand.ts +++ b/src/rooms/commands/NextSubCommand.ts @@ -28,7 +28,7 @@ export class NextSubCommand extends Command { debugRoom('吃牌时间到, 进入下一轮') self.room.dispatcher.dispatch(new EatConfirmCommand(), {timeUp: true}); } - this.room.beginSchedule(time, timeOverEat, `eat_round_${this.state.currentTurn}`); + this.room.beginSchedule(time, timeOverEat, `eat_round`); // this.room.mainClock = this.clock.setTimeout(function () { // debugRoom('吃牌时间到, 进入下一轮') // self.room.mainClock.clear(); diff --git a/src/rooms/commands/OnJoinCommand.ts b/src/rooms/commands/OnJoinCommand.ts index 8e8f76c..d602f12 100644 --- a/src/rooms/commands/OnJoinCommand.ts +++ b/src/rooms/commands/OnJoinCommand.ts @@ -30,6 +30,9 @@ export class OnJoinCommand extends Command 1 && this.room.clients.length < this.room.maxClients) { + let moreTime = singleton(GameEnv).waitingPlayerOnePlus * 1000; + self.room.addScheduleTime(moreTime, 'play_join', 'waiting_player') } if (this.state.players.size >= this.room.maxClients) { this.room.lock().then(() => {}); diff --git a/src/rooms/commands/PlayReadyCommand.ts b/src/rooms/commands/PlayReadyCommand.ts index bb0c287..6bd9312 100644 --- a/src/rooms/commands/PlayReadyCommand.ts +++ b/src/rooms/commands/PlayReadyCommand.ts @@ -22,7 +22,8 @@ export class PlayReadyCommand extends Command= this.room.maxClients) { - this.room.stopSchedule(); + this.room.stopSchedule('restart_schedule'); + this.room.stopSchedule('waiting_player'); // 比大小, 确定先手 // return [new PrepareCommand()]; let i = 0; diff --git a/src/rooms/commands/SelectPetCommand.ts b/src/rooms/commands/SelectPetCommand.ts index 9bd82ec..209acd6 100644 --- a/src/rooms/commands/SelectPetCommand.ts +++ b/src/rooms/commands/SelectPetCommand.ts @@ -60,7 +60,7 @@ export class SelectPetCommand extends Command= 0) { let count = elapsedTime - singleton(GameEnv).playerActTime * 1000; let newCount = player.extraTime - Math.min(count, 0);