feat(map): 实现地图加载和玩家进入地图功能
- 在 Player 结构中添加 MapId 字段,用于记录当前所在地图 ID - 新增地图配置解析功能,支持从 XML 文件中读取地图信息 - 实现玩家进入地图的逻辑,包括设置玩家位置和广播通知 - 更新登录逻辑,在玩家登录时自动进入默认地图 - 重构地图相关的数据结构和接口,为后续地图功能扩展做准备
This commit is contained in:
@@ -14,6 +14,7 @@ type Player struct {
|
||||
UserID uint32 //用户ID
|
||||
IsLogin bool //是否登录
|
||||
mu sync.Mutex
|
||||
MapId uint32 //当前所在的地图ID
|
||||
|
||||
loginChan chan struct{} // 登录完成通知通道
|
||||
context.Context
|
||||
|
||||
@@ -1 +1,123 @@
|
||||
package xml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/ECUST-XX/xml"
|
||||
)
|
||||
|
||||
// Maps 根节点,对应<Maps>标签
|
||||
type Maps struct {
|
||||
XMLName xml.Name `xml:"Maps"`
|
||||
Maps []Map `xml:"map"` // 包含所有地图配置
|
||||
}
|
||||
|
||||
// Map 单张地图配置,对应<map>标签
|
||||
type Map struct {
|
||||
ID int `xml:"id,attr"` // 地图ID
|
||||
Name string `xml:"name,attr"` // 地图名称
|
||||
X int `xml:"x,attr"` // 地图X坐标
|
||||
Y int `xml:"y,attr"` // 地图Y坐标
|
||||
Des string `xml:"des,attr,omitempty"` // 地图描述(可选)
|
||||
Super int `xml:"super,attr,omitempty"` // 上级地图ID(可选)
|
||||
IsFB int `xml:"isFB,attr,omitempty"` // 是否为副本(0/1,可选)
|
||||
IsLocal int `xml:"isLocal,attr,omitempty"` // 是否为本地地图(0/1,可选)
|
||||
Sound string `xml:"sound,attr,omitempty"` // 背景音乐(可选)
|
||||
ReplaceMapID int `xml:"replaceMapId,attr,omitempty"` // 替换地图ID(可选)
|
||||
FX int `xml:"fx,attr,omitempty"` // 道具地面X坐标(可选)
|
||||
FY int `xml:"fy,attr,omitempty"` // 道具地面Y坐标(可选)
|
||||
WX int `xml:"wx,attr,omitempty"` // 道具墙面X坐标(可选)
|
||||
WY int `xml:"wy,attr,omitempty"` // 道具墙面Y坐标(可选)
|
||||
HX int `xml:"hx,attr,omitempty"` // 总部主电脑X坐标(可选)
|
||||
HY int `xml:"hy,attr,omitempty"` // 总部主电脑Y坐标(可选)
|
||||
|
||||
Entries Entries `xml:"Entries,omitempty"` // 进入点配置(可选)
|
||||
ChangeMapComp ComponentList `xml:"changeMapComp,omitempty"` // 场景切换组件(可选)
|
||||
FunComp ComponentList `xml:"funComp,omitempty"` // 点击触发组件(可选)
|
||||
AutoComp ComponentList `xml:"autoComp,omitempty"` // 自动触发组件(可选)
|
||||
}
|
||||
|
||||
// Entries 进入点集合,对应<Entries>标签
|
||||
type Entries struct {
|
||||
Entries []Entry `xml:"Entry"` // 多个进入点
|
||||
}
|
||||
|
||||
// Entry 单个进入点配置,对应<Entry>标签
|
||||
type Entry struct {
|
||||
FromMap int `xml:"FromMap,attr"` // 来源地图ID
|
||||
PosX int `xml:"PosX,attr"` // 进入后X坐标
|
||||
PosY int `xml:"PosY,attr"` // 进入后Y坐标
|
||||
}
|
||||
|
||||
// ComponentList 组件集合(用于统一管理不同类型的组件列表)
|
||||
type ComponentList struct {
|
||||
Components []Component `xml:"component"` // 多个组件
|
||||
}
|
||||
|
||||
// Component 单个功能组件配置,对应<component>标签
|
||||
type Component struct {
|
||||
Name string `xml:"name,attr,omitempty"` // 组件名称(可选)
|
||||
Hit string `xml:"hit,attr,omitempty"` // 碰撞区域标识(可选)
|
||||
TargetID int `xml:"targetID,attr,omitempty"` // 目标地图ID(可选)
|
||||
Dir int `xml:"dir,attr,omitempty"` // 滚动方向(1-4,可选)
|
||||
Fun string `xml:"fun,attr,omitempty"` // 触发函数名(可选)
|
||||
Des string `xml:"des,attr,omitempty"` // 鼠标提示文本(可选)
|
||||
IsStop int `xml:"isStop,attr,omitempty"` // 鼠标悬停是否跳帧(0/1,可选)
|
||||
}
|
||||
|
||||
// ReadHTTPFile 通过HTTP GET请求获取远程文件内容
|
||||
// url: 远程文件的URL地址
|
||||
// 返回文件内容字节流和可能的错误
|
||||
func ReadHTTPFile(url string) ([]byte, error) {
|
||||
// 创建HTTP客户端并设置超时时间(避免无限等待)
|
||||
client := &http.Client{
|
||||
Timeout: 30 * time.Second, // 30秒超时
|
||||
}
|
||||
|
||||
// 发送GET请求
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求失败: %w", err)
|
||||
}
|
||||
defer resp.Body.Close() // 确保响应体被关闭
|
||||
|
||||
// 检查响应状态码
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("请求返回非成功状态码: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 读取响应体内容
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取内容失败: %w", err)
|
||||
}
|
||||
|
||||
return content, nil
|
||||
}
|
||||
func getxml() ([]byte, error) {
|
||||
|
||||
// 读取整个文件内容,返回字节切片和错误
|
||||
content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/map_info.xml")
|
||||
if err != nil {
|
||||
// 处理错误(文件不存在、权限问题等)
|
||||
log.Fatalf("无法读取文件: %v", err)
|
||||
}
|
||||
return content, nil
|
||||
|
||||
}
|
||||
func getMaps() Maps {
|
||||
|
||||
// 解析XML到结构体
|
||||
var maps Maps
|
||||
t1, _ := getxml()
|
||||
xml.Unmarshal(t1, &maps)
|
||||
|
||||
return maps
|
||||
}
|
||||
|
||||
// 全局函数配置
|
||||
var MapConfig = getMaps()
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package xml
|
||||
|
||||
import (
|
||||
"github.com/ECUST-XX/xml"
|
||||
)
|
||||
|
||||
type xmls struct {
|
||||
Text string `xml:",chardata"`
|
||||
Version string `xml:"comment"`
|
||||
|
||||
SuperMaps SuperMaps `xml:"superMaps"`
|
||||
}
|
||||
type SuperMaps struct {
|
||||
XMLName xml.Name `xml:"superMaps"`
|
||||
Text string `xml:",comment"`
|
||||
Maps []Maps `xml:"maps"`
|
||||
}
|
||||
|
||||
type Maps struct {
|
||||
Text string `xml:",chardata"`
|
||||
ID string `xml:"id,attr"`
|
||||
Name string `xml:"name,attr"`
|
||||
X string `xml:"x,attr"`
|
||||
Y string `xml:"y,attr"`
|
||||
// Galaxy string `xml:"galaxy,attr"`
|
||||
}
|
||||
@@ -48,25 +48,14 @@ var s = `
|
||||
</superMaps>`
|
||||
|
||||
func Test_main(t *testing.T) {
|
||||
tt := &SuperMaps{}
|
||||
xml.Unmarshal([]byte(s), tt)
|
||||
|
||||
// tt.Maps = append(tt.Maps, Maps{
|
||||
// ID: "1",
|
||||
// Name: "传送舱",
|
||||
// // Galaxy: "1",
|
||||
// X: "358",
|
||||
// Y: "46",
|
||||
// })
|
||||
// tt.Maps = append(tt.Maps, Maps{
|
||||
// ID: "4",
|
||||
// Name: "船长室",
|
||||
// // Galaxy: "1",
|
||||
// X: "358",
|
||||
// Y: "46",
|
||||
// })
|
||||
tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
|
||||
fmt.Println(string(tf))
|
||||
// 解析XML到结构体
|
||||
var maps Maps
|
||||
t1, _ := getxml()
|
||||
xml.Unmarshal(t1, &maps)
|
||||
|
||||
//tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
|
||||
fmt.Println(maps)
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user