DOF/sqr/User/Object/Map/MapObject.nut

459 lines
17 KiB
Plaintext

/*
文件名:MapObject.nut
路径:User/Object/Map/MapObject.nut
创建日期:2024-11-22 19:40
文件用途:地图对象
*/
class MapLayer extends Actor {
function _typeof() {
return "townmap";
}
}
class Map extends Actor {
//图层对象Map
LayerObject = null;
//所属城镇
m_town = 0;
//地图编号
m_mapId = 0;
//数据
m_data = null;
//地图长度
m_length = 0;
//地图高度
m_height = 0;
//摄像机
m_camera = null;
//地图的摄像机最大可移动参数
CameraMovableAreaX = null;
CameraMovableAreaY = null;
//背景音乐
BackGroundMusic = null;
function _typeof() {
return "townmap";
}
//初始化图层对象
function InitLayer() {
//图层ObjMap
LayerObject = {
contact = MapLayer(),
distantback = MapLayer(),
middleback = MapLayer(),
bottom = MapLayer(),
closeback = MapLayer(),
normal = MapLayer(),
close = MapLayer(),
cover = MapLayer(),
max = MapLayer()
};
//把所有图层Obj挂上Map的子对象
foreach(LayerObj in LayerObject) {
Addchild(LayerObj);
}
local FristOrder = 10000;
//按照层级给Layer设置层级
LayerObject.contact.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.distantback.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.middleback.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.bottom.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.closeback.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.normal.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.close.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.cover.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.max.SetZOrder(FristOrder);
};
//初始化数据
function InitData(path) {
m_data = ScriptData.GetFileData(path, function(DataTable, Data) {
//在这里添加一些初始化的默认值
DataTable.wide_mode_camer_vertical_correction <- 0;
DataTable.background_pos <- 80;
while (!Data.Eof()) {
local str = Data.Get();
if (str == "[background pos]") {
DataTable.background_pos <- (Data.Get());
} else if (str == "[map name]") {
DataTable.name <- Data.Get();
} else if (str == "[wide mode camera vertical correction]") {
DataTable.wide_mode_camer_vertical_correction <- Data.Get();
} else if (str == "[tile]") {
DataTable.tile <- [];
while (true) {
local tiledata = Data.Get();
if (tiledata == "[/tile]") break;
DataTable.tile.push(tiledata);
}
} else if (str == "[extended tile]") {
DataTable.extended_tile <- [];
while (true) {
local tiledata = Data.Get();
if (tiledata == "[/extended tile]") break;
DataTable.extended_tile.push(tiledata);
}
} else if (str == "[far sight scroll]") {
DataTable.far_sight_scroll <- (Data.Get());
} else if (str == "[background animation]") {
DataTable.background_animation <- [];
while (true) {
local anidata = Data.Get();
if (anidata == "[/background animation]") break;
if (anidata == "[ani info]") {
local info = {};
Data.Get();
info["filename"] <- Data.Get();
Data.Get();
info["layer"] <- Data.Get().slice(1, -1);
Data.Get();
info["order"] <- Data.Get();
DataTable.background_animation.push(info);
}
}
} else if (str == "[sound]") {
DataTable.sound <- [];
while (true) {
local sounddata = Data.Get();
if (sounddata == "[/sound]") break;
DataTable.sound.push(sounddata);
}
} else if (str == "[animation]") {
DataTable.animation <- [];
while (true) {
local anidata = Data.Get();
if (anidata == "[/animation]") break;
local info = {};
info["filename"] <- anidata;
info["layer"] <- Data.Get().slice(1, -1);
info["xpos"] <- Data.Get();
info["ypos"] <- Data.Get();
info["zpos"] <- Data.Get();
DataTable.animation.push(info);
}
} else if (str == "[NPC]") {
DataTable.npc <- [];
while (true) {
local npcdata = Data.Get();
if (npcdata == "[/NPC]") break;
local info = {};
info["id"] <- npcdata;
info["direction"] <- Data.Get();
info["xpos"] <- Data.Get();
info["ypos"] <- Data.Get();
info["zpos"] <- Data.Get();
DataTable.npc.push(info);
}
} else if (str == "[town movable area]") {
DataTable.town_movable_area <- [];
DataTable.town_movable_area_info <- [];
while (true) {
local areadata = Data.Get();
if (areadata == "[/town movable area]") break;
DataTable.town_movable_area.push(areadata);
for (local i = 0; i< 3; i++) {
DataTable.town_movable_area.push(Data.Get());
}
local T = {
town = Data.Get(),
area = Data.Get(),
}
DataTable.town_movable_area_info.push(T);
}
} else if (str == "[virtual movable area]") {
DataTable.virtual_movable_area <- [];
while (true) {
local areadata = Data.Get();
if (areadata == "[/virtual movable area]") break;
DataTable.virtual_movable_area.push(areadata);
DataTable.virtual_movable_area.push(Data.Get());
DataTable.virtual_movable_area.push(Data.Get());
DataTable.virtual_movable_area.push(Data.Get());
}
}
}
});
m_data.path <- path;
m_data.dirpath <- path.slice(0, path.lastfind("/") + 1);
}
//初始化地板
function InitTile() {
local NormalTileCount = 0;
//普通地板
if ("tile" in m_data) {
NormalTileCount = m_data.tile.len();
//计算地图长度
m_length = NormalTileCount * 224;
foreach(pos, path in m_data.tile) {
local realpath = m_data.dirpath + path.tolower();
local TileObj = Tile(realpath);
TileObj.SetAnchor(0.0, 0.0);
TileObj.SetPosition(pos * 224, -120 - m_data.background_pos);
LayerObject.bottom.Addchild(TileObj);
}
//默认地板 + 摄像机偏移 + 默认需要有一个40的添加地板
m_height = 560;
}
//补充地板
if ("extended_tile" in m_data) {
local ExTileCount = m_data.extended_tile.len();
//计算地图高度
local Buffer = (ExTileCount / NormalTileCount);
//这里默认加了40的高度 然后要读取pvf的 [wide mode camera vertical correction]
m_height += (Buffer< 1 ? 1 : Buffer) * 40;
foreach(pos, path in m_data.extended_tile) {
local realpath = m_data.dirpath + path.tolower();
local TileObj = Tile(realpath);
TileObj.SetAnchor(0.0, 0.0);
//根据基础地板的数量判断是第几排
TileObj.SetPosition((pos % NormalTileCount) * 224, 560 - 120 - m_data.background_pos + ((pos / NormalTileCount) * 40));
LayerObject.bottom.Addchild(TileObj);
}
}
}
//初始化背景动画
function InitBackgroundAnimation() {
local Rate = m_data.rawin("far_sight_scroll") ? (m_data.far_sight_scroll.tofloat() / 100.0) : 1.0;
m_camera.BackgroundMoveSpeed = Rate;
//背景动画
if ("background_animation" in m_data) {
foreach(Info in m_data.background_animation) {
local realpath = m_data.dirpath + Info.filename.tolower();
//先构造一个天空 然后通过宽度 和地图宽度得知还需要再构造多少个
local AniList = [];
local AniObj = Animation(realpath);
local width = AniObj.GetSize().w;
AniList.push(AniObj);
for (local i = 1; i<((m_length * Rate) / width + 1); i++) {
local AniObj = Animation(realpath);
AniList.push(AniObj);
}
foreach(pos, ani in AniList) {
ani.SetAnchor(0.0, 0.0);
ani.SetPosition(pos * AniObj.GetSize().w, -120);
LayerObject[Info.layer].Addchild(ani);
ani.SetZOrder(-1000000);
}
}
}
}
//初始化场景Ani
function InitAnimation() {
foreach(pos, info in m_data.animation) {
local realpath = m_data.dirpath + info.filename.tolower();
local AniObj = AnimationObject(realpath);
AniObj.SetAnchor(0.0, 0.0);
if (info.layer != "normal") AniObj.SetPositionNoLayer(info.xpos, info.ypos, info.zpos);
else AniObj.SetPosition(info.xpos, info.ypos, info.zpos);
LayerObject[info.layer].Addchild(AniObj);
}
}
//添加对象
function AddObject(obj, IsPlayer = false) {
//角色对象
if (typeof obj == "character") {
//如果已经处于某个地图中
if (obj.Parent) {
obj.Parent.Removechild(obj);
}
LayerObject.normal.Addchild(obj);
obj.MySelfMap = this.weakref();
//如果是玩家自己
if (IsPlayer) {
m_camera.SetFromParent(obj);
if (BackGroundMusic == null) BackGroundMusic = {};
foreach(SoundName in m_data.sound) {
local BgMusic = Audio(getconsttable().MUSIC[SoundName]);
BgMusic.Play();
BackGroundMusic[SoundName] <- BgMusic;
}
}
}
}
//移动城镇的添加对象
function AddObjectByChangeTown(obj, FromMapobj) {
//角色对象
if (typeof obj == "character") {
//如果已经处于某个地图中
if (obj.Parent) {
obj.Parent.Removechild(obj);
}
LayerObject.normal.Addchild(obj);
//将地图信息写入角色中
obj.MySelfMap = this.weakref();
//绑定摄像机
m_camera.SetFromParent(obj);
//获取应该设置的坐标
foreach(index, info in m_data.town_movable_area_info) {
if (info.town == FromMapobj.m_town && info.area == FromMapobj.m_mapId) {
local pos = {
x = m_data.town_movable_area[index * 4] + m_data.town_movable_area[index * 4 + 2] / 2,
y = m_data.town_movable_area[index * 4 + 1] + m_data.town_movable_area[index * 4 + 3] / 2,
z = 0
}
obj.SetPosition(pos);
break;
}
}
//获取当前场景
local Stage = sq_GetCurrentStage();
if (GlobalTownManager.CurrentTown) {
Stage.Removechild(GlobalTownManager.CurrentTown);
}
Stage.Addchild(this);
//添加全局
GlobalTownManager.CurrentTown = this.weakref();
//背景音乐处理
BackGroundMusic = {};
if (FromMapobj.BackGroundMusic != null) {
//把老地图的音频先获取过来
foreach(SoundName, Music in FromMapobj.BackGroundMusic) {
//如果有背景音乐是新地图存在的 就添加
if (this.m_data.sound.find(SoundName) != null) {
BackGroundMusic[SoundName] <- Music;
}
}
//销毁老地图的音频列表
FromMapobj.BackGroundMusic = null;
//检查当前地图的背景音乐
foreach(SoundName in this.m_data.sound) {
//如果有一个背景音乐是新地图不存在的 就停止播放
if (!(BackGroundMusic.rawin(SoundName))) {
local BgMusic = Audio(getconsttable().MUSIC[SoundName]);
BgMusic.Play();
BackGroundMusic[SoundName] <- BgMusic;
}
}
}
}
}
constructor(arg) {
base.constructor();
if (typeof arg == "integer") {
} else if (typeof arg == "string") {
InitData(arg);
}
//初始化摄像机
m_camera = MapCamera(this);
//初始化图层
InitLayer();
//初始化地板
InitTile();
//初始化背景动画
InitBackgroundAnimation();
//初始化场景Ani
InitAnimation();
//设置摄像机的最大可行区域
m_camera.MovableAreaX = m_length;
m_camera.MovableAreaY = m_height - m_data.wide_mode_camer_vertical_correction;
m_camera.BackgroundOffset = m_data.background_pos;
// OpenMovableAreaBorder();
}
//DEBUG方法
function OpenMovableAreaBorder() {
for (local i = 0; i< m_data.virtual_movable_area.len(); i += 4) {
local x = m_data.virtual_movable_area[i];
local y = m_data.virtual_movable_area[i + 1];
local w = m_data.virtual_movable_area[i + 2];
local h = m_data.virtual_movable_area[i + 3];
local Ac = Actor();
Ac.SetPosition(x, y);
Ac.SetSize(w, h);
Ac.ShowBorder(true);
LayerObject.max.Addchild(Ac);
}
}
//判断区域是否可行
function CheckMovableArea(gx, gxoffset, gy, gyoffset) {
local pos = {
x = gxoffset,
y = gyoffset
}
//都符合
if (Math.PointIsInSquare(gx + gxoffset, gy + gyoffset, m_data.virtual_movable_area)) {}
//X符合
else if (Math.PointIsInSquare(gx + gxoffset, gy, m_data.virtual_movable_area)) {
pos.y = 0;
}
//Y符合
else if (Math.PointIsInSquare(gx, gy + gyoffset, m_data.virtual_movable_area)) {
pos.x = 0;
} else {
pos.x = 0;
pos.y = 0;
}
return pos;
}
//判断区域是否传送
function CheckMovableAreaTransmit(obj, gx, gy) {
local Index = Math.PointIsInWhichRectangle(gx, gy, m_data.town_movable_area);
//走进了传送阵
if (Index != -1) {
if (!obj.TransmitFlag) {
local info = m_data.town_movable_area_info[Index];
//这里是未加载的城镇
if (!(GlobalTownManager.TownList.rawin(info.town))) {
Town(info.town);
}
local MapObj = GlobalTownManager.TownList[info.town].map[info.area];
MapObj.AddObjectByChangeTown(obj, this);
obj.TransmitFlag = true;
}
} else {
obj.TransmitFlag = false;
}
}
//音乐逻辑
function MusicLogic() {
if (BackGroundMusic == null) return;
foreach(Music in BackGroundMusic) {
if (!Music.IsPlaying()) Music.Play();
}
}
function OnUpdate(Dt) {
base.OnUpdate(Dt);
//更新摄像机
m_camera.OnUpdate(Dt);
//更新音乐逻辑
MusicLogic();
}
}