feat(chat): 添加地图切换功能
范围: src/gateway/chat/ - 新增 change_map 事件处理 - 实现 handleChangeMap() 方法 - 支持玩家在不同地图间切换 - 自动更新房间成员和广播通知 - 完善地图切换的错误处理 功能说明: - 玩家可以通过 WebSocket 发送 change_map 事件切换地图 - 自动处理房间加入/离开逻辑 - 向旧地图广播玩家离开,向新地图广播玩家加入 - 支持携带初始位置坐标,默认使用 (400, 300)
This commit is contained in:
@@ -169,6 +169,9 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha
|
||||
case 'position':
|
||||
await this.handlePosition(ws, message);
|
||||
break;
|
||||
case 'change_map':
|
||||
await this.handleChangeMap(ws, message);
|
||||
break;
|
||||
default:
|
||||
this.logger.warn(`未知消息类型: ${messageType}`);
|
||||
this.sendError(ws, `未知消息类型: ${messageType}`);
|
||||
@@ -254,7 +257,7 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha
|
||||
* 处理聊天消息
|
||||
*
|
||||
* @param ws WebSocket 连接实例
|
||||
* @param message 聊天消息(包含 content, scope)
|
||||
* @param message 聊天消息(包含 content, scope, mapId)
|
||||
*/
|
||||
private async handleChat(ws: ExtendedWebSocket, message: any) {
|
||||
if (!ws.authenticated) {
|
||||
@@ -271,7 +274,8 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha
|
||||
const result = await this.chatService.sendChatMessage({
|
||||
socketId: ws.id,
|
||||
content: message.content,
|
||||
scope: message.scope || 'local'
|
||||
scope: message.scope || 'local',
|
||||
mapId: message.mapId || ws.currentMap, // 支持指定目标地图
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
@@ -335,6 +339,82 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理切换地图
|
||||
*
|
||||
* @param ws WebSocket 连接实例
|
||||
* @param message 切换地图消息(包含 mapId)
|
||||
*/
|
||||
private async handleChangeMap(ws: ExtendedWebSocket, message: any) {
|
||||
if (!ws.authenticated) {
|
||||
this.sendError(ws, '请先登录');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message.mapId) {
|
||||
this.sendError(ws, '地图ID不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const oldMapId = ws.currentMap;
|
||||
const newMapId = message.mapId;
|
||||
|
||||
// 如果地图相同,直接返回成功
|
||||
if (oldMapId === newMapId) {
|
||||
this.sendMessage(ws, {
|
||||
t: 'map_changed',
|
||||
mapId: newMapId,
|
||||
message: '已在当前地图'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新房间
|
||||
this.leaveMapRoom(ws.id, oldMapId);
|
||||
this.joinMapRoom(ws.id, newMapId);
|
||||
ws.currentMap = newMapId;
|
||||
|
||||
// 更新会话中的地图信息(使用默认位置)
|
||||
await this.chatService.updatePlayerPosition({
|
||||
socketId: ws.id,
|
||||
x: message.x || 400,
|
||||
y: message.y || 300,
|
||||
mapId: newMapId
|
||||
});
|
||||
|
||||
// 通知客户端切换成功
|
||||
this.sendMessage(ws, {
|
||||
t: 'map_changed',
|
||||
mapId: newMapId,
|
||||
oldMapId: oldMapId,
|
||||
message: '地图切换成功'
|
||||
});
|
||||
|
||||
// 向旧地图广播玩家离开
|
||||
this.broadcastToMap(oldMapId, {
|
||||
t: 'player_left',
|
||||
userId: ws.userId,
|
||||
username: ws.username,
|
||||
mapId: oldMapId
|
||||
});
|
||||
|
||||
// 向新地图广播玩家加入
|
||||
this.broadcastToMap(newMapId, {
|
||||
t: 'player_joined',
|
||||
userId: ws.userId,
|
||||
username: ws.username,
|
||||
mapId: newMapId
|
||||
}, ws.id);
|
||||
|
||||
this.logger.log(`用户切换地图: ${ws.username} (${oldMapId} -> ${newMapId})`);
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error('切换地图处理失败', error);
|
||||
this.sendError(ws, '切换地图处理失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理连接关闭
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user