Magic_GameClient/sqr/User/GameClass/MapClass/MapClass.nut

248 lines
8.5 KiB
Plaintext

/*
文件名:MapClass.nut
路径:GameClass/MapClass/MapClass.nut
创建日期:2024-05-09 20:33
文件用途:地图类
*/
class Map extends CL_BaseObject {
//图层对象Map
LayerObject = null;
//地图配置信息
Info = null;
//八叉树碰撞树
octree = null;
//地图对象管理器
ObjectManager = null;
constructor(...) {
local C_Object;
if (vargv.len() == 0) {
C_Object = BaseObject_Create();
} else {
C_Object = vargv[0];
}
base.constructor(C_Object);
//图层ObjMap
LayerObject = {
contact = Actor(),
normal = Actor(),
bottom = Actor(),
close = Actor(),
closeback = Actor(),
middleback = Actor(),
distantback = Actor(),
cover = Actor(),
max = Actor()
};
//把所有图层Obj挂上Map的子对象
foreach(LayerObj in LayerObject) {
Addchild(LayerObj);
}
local FristOrder = 10000;
//按照层级给Layer设置层级
LayerObject.distantback.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.middleback.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.bottom.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.close.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.closeback.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.normal.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.cover.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.contact.SetZOrder(FristOrder);
FristOrder += 50000;
LayerObject.max.SetZOrder(FristOrder);
//将图层与摄像机绑定
BindenvCamera();
// SetPosition(0, 60);
// SetScale(1.5, 1.5);
// SetScale(0.5, 0.5);
}
function BindenvCamera() {
//同步图层与摄像机的移动坐标
LayerObject.distantback.SetUpdateFunc(function(dt) {
SetPosition((-CameraObject.X + 800), -CameraObject.Y + 450 - CameraObject.Z + 60);
})
LayerObject.middleback.SetUpdateFunc(function(dt) {
SetPosition((-CameraObject.X + 800), -CameraObject.Y + 450 - CameraObject.Z + 60);
})
LayerObject.bottom.SetUpdateFunc(function(dt) {
SetPosition(-CameraObject.X + 800, -CameraObject.Y + 450 + CameraObject.Z + 60);
})
LayerObject.close.SetUpdateFunc(function(dt) {
SetPosition(-CameraObject.X + 800, -CameraObject.Y + 450 + CameraObject.Z + 60);
})
LayerObject.closeback.SetUpdateFunc(function(dt) {
SetPosition(-CameraObject.X + 800, -CameraObject.Y + 450 + CameraObject.Z + 60);
})
LayerObject.normal.SetUpdateFunc(function(dt) {
SetPosition(-CameraObject.X + 800, -CameraObject.Y + 450 + CameraObject.Z + 60);
})
LayerObject.cover.SetUpdateFunc(function(dt) {
SetPosition(-CameraObject.X + 800, -CameraObject.Y + 450 + CameraObject.Z + 60);
})
LayerObject.contact.SetUpdateFunc(function(dt) {
SetPosition(-CameraObject.X + 800, -CameraObject.Y + 450 + CameraObject.Z + 60);
})
LayerObject.max.SetUpdateFunc(function(dt) {
SetPosition(-CameraObject.X + 800, -CameraObject.Y + 450 + CameraObject.Z + 60);
})
}
function InitMap(Idx) {
Info = ScriptData.GetMap(Idx);
// Util.PrintTable(Info);
//地图的X轴长度
local MapXLength = Info.tile.len() * 224;
//背景Ani
local backgroundaniLength = 0;
while (true) {
//已经拼接的长度
local LengthBuf = 0;
//一轮拼接
foreach(_Index, AniObj in Info.backgroundani) {
local AniBuf = Animation(AniObj["[filename]"]);
LengthBuf = AniBuf.GetSize().w;
AniBuf.SetPosition(backgroundaniLength, 0);
//拿到图层 并且设置在对应图层里
local LayerConfig = AniObj["[layer]"];
LayerConfig = LayerConfig.slice(1, -1);
LayerObject[LayerConfig].Addchild(AniBuf);
}
backgroundaniLength += LengthBuf;
//拼接长度超过以后就停止
if (backgroundaniLength >= MapXLength) break;
}
//Ani
foreach(_Index, AniObj in Info.animation) {
local AniBuf = Animation(AniObj.path);
local YPos = AniObj.y - AniObj.z;
if (Info["map type"] == "dungeon") YPos += 120;
AniBuf.SetPosition(AniObj.x, YPos);
//拿到图层 并且设置在对应图层里
local LayerConfig = AniObj.layer;
LayerConfig = LayerConfig.slice(1, -1);
LayerObject[LayerConfig].Addchild(AniBuf);
}
//tile
local TileStartXpos = 0;
foreach(TilePath in Info.tile) {
local TileInfo = ScriptData.GetTile(TilePath);
local TileSprite = CL_SpriteObject();
TileSprite.SetFrame(CL_SpriteFrameObject(TileInfo.image.path, TileInfo.image.idx));
local YPos = 0;
if ("pos" in TileInfo) YPos += TileInfo.pos;
TileSprite.SetPosition(TileStartXpos, YPos);
TileStartXpos += 224;
LayerObject["bottom"].Addchild(TileSprite);
}
//Passiveobject
foreach(_index, value in Info.passiveobject) {
local objbuf = PassiveObject();
objbuf.Init(value.id);
objbuf.SetPosition(value.x, value.y, value.z);
// Util.PrintTable(value);
local AddLayer = "normal";
if (objbuf.Layer) AddLayer = objbuf.Layer;
LayerObject[AddLayer].Addchild(objbuf);
}
//构造地图碰撞八叉树
octree = OctreeNode(AABB(0, 0, 0, MapXLength, 1000, 1000));
ObjectManager = [];
}
//添加游戏对象
function AddObject(obj) {
//插入对象管理器
ObjectManager.append(obj);
local AddLayer = "normal";
LayerObject[AddLayer].Addchild(obj);
}
//移除游戏对象
function RemoveObject(obj) {
//移除对象管理器
local Index = ObjectManager.find(obj);
ObjectManager.remove(Index);
}
//检测碰撞
function CheckHitBox() {
//将所有受击框添加到八叉树
foreach(_index, obj in ObjectManager) {
if (obj.DamageBox) { //如果受击框存在 是以数组形式存在所有要遍历传入
foreach(arr in obj.DamageBox) {
local buf = AABB(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], _index);
octree.insert(buf);
}
}
}
local AttackArr = [];
//记录所有攻击框
foreach(_index, obj in ObjectManager) {
if (obj.AttackBox) { //如果受击框存在 是以数组形式存在所有要遍历传入
foreach(arr in obj.AttackBox) {
local buf = AABB(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], _index);
AttackArr.append(buf);
}
}
}
//检查碰撞
foreach(aabbbuf in AttackArr) {
local collidingObjects = octree.checkCollisionWithNode(aabbbuf);
foreach(pdobj in collidingObjects) {
if (pdobj.ObjectIndex != aabbbuf.ObjectIndex) {
// print("碰撞对象: " + ObjectManager[aabbbuf.ObjectIndex].GetName());
// print("被碰撞对象: " + ObjectManager[pdobj.ObjectIndex].GetName());
// if (ObjectManager.len() > aabbbuf.ObjectIndex);
if (ObjectManager.len() > aabbbuf.ObjectIndex && ObjectManager.len() > pdobj.ObjectIndex)
ObjectManager[aabbbuf.ObjectIndex].OnAttack(ObjectManager[pdobj.ObjectIndex]);
}
}
// print("\n");
}
//清空八叉树
octree.clear();
}
function OnUpdate(dt) {
//检测碰撞
CheckHitBox();
//同步摄像机缩放比例
SetScale(CameraObject.CameraRate, CameraObject.CameraRate)
//音效管理器
AudioControl.OnUpdate(dt);
base.OnUpdate(dt);
}
//被添加时
function OnAddchild(parent) {
getroottable().CurrentMap <- this;
base.OnAddchild(parent);
}
}