import { MsgCall } from "tsrpc"; import { playerManager } from "../managers/PlayerManager"; import { MsgPlayerMove } from "../shared/protocols/MsgPlayerMove"; import { MsgReqMove } from "../shared/protocols/MsgReqMove"; import { broadcastToAll } from "../utils/broadcast"; import { clientToGamePosition, gameToClientPosition } from "../utils/coordinate"; /** * 移动消息处理器 * 处理玩家移动请求,验证位置合法性,更新玩家位置并广播给其他玩家 */ export default async function (call: MsgCall) { const { x, y } = call.msg; // 从连接中获取玩家ID(需要在登录时保存) const playerId = (call.conn as any).playerId; if (!playerId) { call.conn.sendMsg('ResMove', { success: false, message: '未登录,请先登录' }); return; } // 获取玩家信息 const player = playerManager.getPlayer(playerId); if (!player) { call.conn.sendMsg('ResMove', { success: false, message: '玩家不存在' }); return; } // 检查玩家是否存活 if (!player.isAlive) { call.conn.sendMsg('ResMove', { success: false, message: '玩家已死亡,无法移动' }); return; } // 验证坐标是否为数字 if (typeof x !== 'number' || typeof y !== 'number') { call.conn.sendMsg('ResMove', { success: false, message: '坐标格式错误' }); return; } // 验证坐标是否为整数 if (!Number.isInteger(x) || !Number.isInteger(y)) { call.conn.sendMsg('ResMove', { success: false, message: '坐标必须为整数' }); return; } // 将客户端坐标(放大1000倍)转换为游戏内坐标 const gamePosition = clientToGamePosition({ x, y }); try { // 尝试更新玩家位置(使用游戏内坐标) const success = playerManager.updatePlayerPosition(playerId, gamePosition.x, gamePosition.y); if (!success) { call.conn.sendMsg('ResMove', { success: false, message: '移动失败,位置无效或超出世界边界' }); return; } // 获取更新后的位置(转换为客户端坐标) const newPosition = gameToClientPosition(gamePosition); // 广播移动消息给所有其他玩家(使用客户端坐标) const moveMsg: MsgPlayerMove = { playerId: player.id, playerName: player.name, position: newPosition, timestamp: Date.now() }; broadcastToAll('PlayerMove', moveMsg, call.conn.id); // 返回成功结果 call.conn.sendMsg('ResMove', { success: true, message: '移动成功', position: newPosition }); console.log(`玩家 ${player.name} 移动到游戏内坐标 (${gamePosition.x}, ${gamePosition.y}),客户端坐标 (${newPosition.x}, ${newPosition.y})`); } catch (error) { console.error('移动失败:', error); call.conn.sendMsg('ResMove', { success: false, message: `移动失败: ${error instanceof Error ? error.message : '未知错误'}` }); } }