/* 文件名: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); } }