122 lines
3.3 KiB
TypeScript
Raw Normal View History

2022-12-08 21:14:02 +08:00
import { ApiMsgEnum, EntityTypeEnum, IClientInput, IMsgClientSync, InputTypeEnum, IState, toFixed } from "../Common";
import { Connection } from "../Core";
import type Player from "./Player";
import PlayerManager from "./PlayerManager";
import RoomManager from "./RoomManager";
2022-12-01 22:26:41 +08:00
export default class Room {
2022-12-08 21:14:02 +08:00
id: number;
players: Set<Player> = new Set();
2022-12-04 22:10:30 +08:00
2022-12-08 21:14:02 +08:00
private lastTime?: number;
private timers: NodeJS.Timer[] = [];
private pendingInput: Array<IClientInput> = [];
private lastPlayerFrameIdMap: Map<number, number> = new Map();
2022-12-01 22:26:41 +08:00
constructor(rid: number) {
2022-12-08 21:14:02 +08:00
this.id = rid;
2022-12-01 22:26:41 +08:00
}
join(uid: number) {
2022-12-08 21:14:02 +08:00
const player = PlayerManager.Instance.getPlayerById(uid);
2022-12-01 22:26:41 +08:00
if (player) {
2022-12-08 21:14:02 +08:00
player.rid = this.id;
this.players.add(player);
2022-12-01 22:26:41 +08:00
}
}
leave(uid: number) {
2022-12-08 21:14:02 +08:00
const player = PlayerManager.Instance.getPlayerById(uid);
2022-12-01 22:26:41 +08:00
if (player) {
2022-12-08 21:14:02 +08:00
player.rid = -1;
player.connection.unlistenMsg(ApiMsgEnum.MsgClientSync, this.getClientMsg, this);
this.players.delete(player);
2022-12-01 22:26:41 +08:00
if (!this.players.size) {
2022-12-08 21:14:02 +08:00
RoomManager.Instance.closeRoom(this.id);
2022-12-01 22:26:41 +08:00
}
}
}
2022-12-07 22:24:46 +08:00
close() {
2022-12-08 21:14:02 +08:00
this.timers.forEach((t) => clearInterval(t));
2022-12-07 22:24:46 +08:00
for (const player of this.players) {
2022-12-08 21:14:02 +08:00
player.rid = -1;
player.connection.sendMsg(ApiMsgEnum.MsgGameEnd, {});
player.connection.unlistenMsg(ApiMsgEnum.MsgClientSync, this.getClientMsg, this);
2022-12-07 22:24:46 +08:00
}
2022-12-08 21:14:02 +08:00
this.players.clear();
2022-12-07 22:24:46 +08:00
}
2022-12-01 22:26:41 +08:00
sync() {
for (const player of this.players) {
2022-12-03 20:06:57 +08:00
player.connection.sendMsg(ApiMsgEnum.MsgRoom, {
2022-12-08 21:14:02 +08:00
room: RoomManager.Instance.getRoomView(this),
});
2022-12-03 20:06:57 +08:00
}
}
start() {
const state: IState = {
2022-12-08 21:14:02 +08:00
actors: [...this.players].map((player, index) => ({
2022-12-03 20:06:57 +08:00
id: player.id,
nickname: player.nickname,
position: {
x: -150 + index * 300,
y: -150 + index * 300,
},
direction: {
x: 1,
2022-12-08 21:14:02 +08:00
y: 0,
2022-12-03 20:06:57 +08:00
},
hp: 100,
2022-12-08 21:14:02 +08:00
type: index === 0 ? EntityTypeEnum.Actor1 : EntityTypeEnum.Actor2,
weaponType: index === 0 ? EntityTypeEnum.Weapon1 : EntityTypeEnum.Weapon2,
bulletType: index === 0 ? EntityTypeEnum.Bullet1 : EntityTypeEnum.Bullet2,
2022-12-03 20:06:57 +08:00
})),
bullets: [],
2022-12-08 21:14:02 +08:00
nextBulletId: 1,
};
2022-12-03 20:06:57 +08:00
for (const player of this.players) {
player.connection.sendMsg(ApiMsgEnum.MsgGameStart, {
2022-12-08 21:14:02 +08:00
state,
});
player.connection.listenMsg(ApiMsgEnum.MsgClientSync, this.getClientMsg, this);
2022-12-03 20:06:57 +08:00
}
2022-12-06 23:10:03 +08:00
let t1 = setInterval(() => {
2022-12-08 21:14:02 +08:00
this.sendServerMsg();
}, 100);
2022-12-06 23:10:03 +08:00
let t2 = setInterval(() => {
2022-12-08 21:14:02 +08:00
this.timePast();
}, 16);
this.timers = [t1, t2];
2022-12-03 20:06:57 +08:00
}
2022-12-08 21:14:02 +08:00
getClientMsg(connection: Connection, { frameId, input }: IMsgClientSync) {
this.lastPlayerFrameIdMap.set(connection.playerId, frameId);
this.pendingInput.push(input);
2022-12-03 21:28:38 +08:00
}
2022-12-08 21:14:02 +08:00
sendServerMsg() {
const pendingInput = this.pendingInput;
this.pendingInput = [];
2022-12-04 22:10:30 +08:00
2022-12-03 21:28:38 +08:00
for (const player of this.players) {
2022-12-08 21:14:02 +08:00
player.connection.sendMsg(ApiMsgEnum.MsgServerSync, {
lastFrameId: this.lastPlayerFrameIdMap.get(player.id) ?? 0,
inputs: pendingInput,
});
2022-12-01 22:26:41 +08:00
}
}
2022-12-04 22:10:30 +08:00
timePast() {
let now = process.uptime();
2022-12-08 21:14:02 +08:00
const dt = now - (this.lastTime ?? now);
this.pendingInput.push({
2022-12-04 22:10:30 +08:00
type: InputTypeEnum.TimePast,
2022-12-08 21:14:02 +08:00
dt: toFixed(dt),
});
this.lastTime = now;
2022-12-04 22:10:30 +08:00
}
2022-12-01 22:26:41 +08:00
}