diff --git a/.gitignore b/.gitignore index 362d2e8..73b5c29 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,5 @@ Thumbs.db #////////////////////////// .vscode/ + +apps/client/assets/Scripts/Common diff --git a/apps/client/assets/Scripts/Entity/Actor/ActorManager.ts b/apps/client/assets/Scripts/Entity/Actor/ActorManager.ts index f4789ce..e783505 100644 --- a/apps/client/assets/Scripts/Entity/Actor/ActorManager.ts +++ b/apps/client/assets/Scripts/Entity/Actor/ActorManager.ts @@ -4,7 +4,7 @@ import { ApiMsgEnum, EntityTypeEnum, IActor, InputTypeEnum, IVec2 } from '../../ import { EntityStateEnum } from '../../Enum'; import DataManager from '../../Global/DataManager'; import NetworkManager from '../../Global/NetworkManager'; -import { rad2Angle } from '../../Utils'; +import { rad2Angle, toFixed } from '../../Utils'; import { WeaponManager } from '../Weapon/WeaponManager'; import { PlayerStateMachine } from './ActorStateMachine'; const { ccclass } = _decorator; @@ -61,13 +61,15 @@ export class ActorManager extends EntityManager implements IActor { const { x, y } = DataManager.Instance.jm.input NetworkManager.Instance.sendMsg(ApiMsgEnum.MsgClientSync, { - type: InputTypeEnum.ActorMove, - id: this.id, - direction: { - x, - y - }, - dt + input: { + type: InputTypeEnum.ActorMove, + id: this.id, + direction: { + x: toFixed(x), + y: toFixed(y), + }, + dt: toFixed(dt) + } }) } diff --git a/apps/client/assets/Scripts/Entity/Weapon/WeaponManager.ts b/apps/client/assets/Scripts/Entity/Weapon/WeaponManager.ts index 6ff4779..2d7a27d 100644 --- a/apps/client/assets/Scripts/Entity/Weapon/WeaponManager.ts +++ b/apps/client/assets/Scripts/Entity/Weapon/WeaponManager.ts @@ -5,6 +5,7 @@ import { EntityStateEnum, EventEnum } from '../../Enum' import DataManager from '../../Global/DataManager' import EventManager from '../../Global/EventManager' import NetworkManager from '../../Global/NetworkManager' +import { toFixed } from '../../Utils' import { WeaponStateMachine } from './WeaponStateMachine' const { ccclass } = _decorator @@ -61,16 +62,18 @@ export class WeaponManager extends EntityManager { const directionVec2 = new Vec2(pointWorldPos.x - anchorWorldPos.x, pointWorldPos.y - anchorWorldPos.y).normalize() NetworkManager.Instance.sendMsg(ApiMsgEnum.MsgClientSync, { - type: InputTypeEnum.WeaponShoot, - owner: this.owner, - position: { - x: pointStagePos.x, - y: pointStagePos.y - }, - direction: { - x: directionVec2.x, - y: directionVec2.y - }, + input: { + type: InputTypeEnum.WeaponShoot, + owner: this.owner, + position: { + x: toFixed(pointStagePos.x), + y: toFixed(pointStagePos.y), + }, + direction: { + x: toFixed(directionVec2.x), + y: toFixed(directionVec2.y), + }, + } }) } } diff --git a/apps/client/assets/Scripts/Global/NetworkManager.ts b/apps/client/assets/Scripts/Global/NetworkManager.ts index a5c558b..29eead7 100644 --- a/apps/client/assets/Scripts/Global/NetworkManager.ts +++ b/apps/client/assets/Scripts/Global/NetworkManager.ts @@ -22,6 +22,10 @@ export default class NetworkManager extends Singleton { connect() { return new Promise((resolve, reject) => { + if (this.isConnected) { + resolve(true) + return + } this.ws = new WebSocket(`ws://localhost:${this.port}`) this.ws.onopen = () => { console.log("ws onopen") diff --git a/apps/client/assets/Scripts/Scene/BattleManager.ts b/apps/client/assets/Scripts/Scene/BattleManager.ts index e45b509..0d5310c 100644 --- a/apps/client/assets/Scripts/Scene/BattleManager.ts +++ b/apps/client/assets/Scripts/Scene/BattleManager.ts @@ -7,7 +7,8 @@ import { PrefabPathEnum, TexturePathEnum } from '../Enum'; import NetworkManager from '../Global/NetworkManager'; import ObjectPoolManager from '../Global/ObjectPoolManager'; import { BulletManager } from '../Entity/Bullet/BulletManager'; -import { EntityTypeEnum, InputTypeEnum } from '../Common'; +import { ApiMsgEnum, EntityTypeEnum, IMsgServerSync, InputTypeEnum } from '../Common'; +import { toFixed } from '../Utils'; const { ccclass } = _decorator; @@ -26,6 +27,7 @@ export class BattleManager extends Component { await this.loadRes() this.initScene() await this.connectServer() + NetworkManager.Instance.listenMsg(ApiMsgEnum.MsgServerSync, this.handleSync); this.isInited = true } @@ -84,6 +86,12 @@ export class BattleManager extends Component { map.setParent(this.stage) } + handleSync({ inputs }: IMsgServerSync) { + for (const input of inputs) { + DataManager.Instance.applyInput(input) + } + } + update(dt: number) { if (!this.isInited) { return @@ -108,9 +116,11 @@ export class BattleManager extends Component { } tickGlobal(dt: number) { - DataManager.Instance.applyInput({ - type: InputTypeEnum.TimePast, - dt + NetworkManager.Instance.sendMsg(ApiMsgEnum.MsgClientSync, { + input: { + type: InputTypeEnum.TimePast, + dt: toFixed(dt), + } }) } diff --git a/apps/client/assets/Scripts/Utils/index.ts b/apps/client/assets/Scripts/Utils/index.ts index 2f525f3..a13e573 100644 --- a/apps/client/assets/Scripts/Utils/index.ts +++ b/apps/client/assets/Scripts/Utils/index.ts @@ -9,3 +9,4 @@ export const sortSpriteFrame = (spriteFrame: Array) => export const rad2Angle = (rad: number) => rad / Math.PI * 180 +export const toFixed = (num: number, digit: number = 4): number => Math.floor(num * 10 ** digit) / 10 ** digit diff --git a/apps/server/src/Common/Msg.ts b/apps/server/src/Common/Msg.ts index 25911cc..15a9466 100644 --- a/apps/server/src/Common/Msg.ts +++ b/apps/server/src/Common/Msg.ts @@ -1,5 +1,5 @@ import { IPlayer, IRoom } from "./Model" -import { IState } from "./State" +import { IClientInput, IState } from "./State" export interface IMsgPlayerList { list: Array @@ -20,4 +20,12 @@ export interface IMsgGameStart { export interface IMsgGameStart { state: IState +} + +export interface IMsgClientSync { + input: IClientInput +} + +export interface IMsgServerSync { + inputs: Array } \ No newline at end of file diff --git a/apps/server/src/biz/Room.ts b/apps/server/src/biz/Room.ts index 68ec089..32a9cfe 100644 --- a/apps/server/src/biz/Room.ts +++ b/apps/server/src/biz/Room.ts @@ -1,4 +1,4 @@ -import { ApiMsgEnum, EntityTypeEnum, IState } from '../Common' +import { ApiMsgEnum, EntityTypeEnum, IClientInput, IState } from '../Common' import type Player from './Player' import PlayerManager from './PlayerManager' import RoomManager from './RoomManager' @@ -11,7 +11,7 @@ export default class Room { this.id = rid } - private inputs = [] + private inputs: Array = [] join(uid: number) { const player = PlayerManager.Instance.getPlayerById(uid) @@ -69,12 +69,26 @@ export default class Room { }) } this.listenPlayer() + setInterval(() => { + this.syncInput() + }, 300) } listenPlayer() { for (const player of this.players) { - player.connection.listenMsg(ApiMsgEnum.MsgClientSync, () => { } - ) + player.connection.listenMsg(ApiMsgEnum.MsgClientSync, ({ input }) => { + this.inputs.push(input) + }) + } + } + + syncInput() { + const inputs = this.inputs + this.inputs = [] + for (const player of this.players) { + player.connection.sendMsg(ApiMsgEnum.MsgServerSync, { + inputs + }) } } } diff --git a/apps/server/src/common/index.ts b/apps/server/src/common/index.ts index 2dbb671..dae85d0 100644 --- a/apps/server/src/common/index.ts +++ b/apps/server/src/common/index.ts @@ -1,6 +1,6 @@ import { IApiGameStartReq, IApiGameStartRes, IApiPlayerJoinReq, IApiPlayerJoinRes, IApiPlayerListReq, IApiPlayerListRes, IApiRoomCreateReq, IApiRoomCreateRes, IApiRoomJoinReq, IApiRoomJoinRes, IApiRoomLeaveReq, IApiRoomLeaveRes, IApiRoomListReq, IApiRoomListRes } from './Api' import { ApiMsgEnum } from './Enum' -import { IMsgGameStart, IMsgPlayerList, IMsgRoom, IMsgRoomList } from './Msg' +import { IMsgClientSync, IMsgGameStart, IMsgPlayerList, IMsgRoom, IMsgRoomList, IMsgServerSync } from './Msg' import { IClientInput } from './State' export * from './Api' export * from './Msg' @@ -44,8 +44,8 @@ export interface IModel { [ApiMsgEnum.MsgRoomList]: IMsgRoomList, [ApiMsgEnum.MsgRoom]: IMsgRoom, [ApiMsgEnum.MsgGameStart]: IMsgGameStart, - [ApiMsgEnum.MsgClientSync]: IClientInput, - [ApiMsgEnum.MsgServerSync]: IMsgGameStart, + [ApiMsgEnum.MsgClientSync]: IMsgClientSync, + [ApiMsgEnum.MsgServerSync]: IMsgServerSync, } } diff --git a/apps/server/src/core/Connection.ts b/apps/server/src/core/Connection.ts index b8a2b01..9aa3b1a 100644 --- a/apps/server/src/core/Connection.ts +++ b/apps/server/src/core/Connection.ts @@ -54,7 +54,7 @@ export default class Connection extends EventEmitter { }) } - listenMsg(name: string, cb: Function) { + listenMsg(name: T, cb: (args: IModel['msg'][T]) => void) { if (this.msgMap.has(name)) { this.msgMap.get(name)?.push(cb) } else { @@ -62,7 +62,7 @@ export default class Connection extends EventEmitter { } } - unlistenMsg(name: string, cb: Function) { + unlistenMsg(name: T, cb: (args: IModel['msg'][T]) => void) { if (this.msgMap.has(name)) { const index = this.msgMap.get(name)?.indexOf(cb) || -1 index > -1 && this.msgMap.get(name)?.splice(index, 1)