408 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			408 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| /*
 | |
| 文件名:NewWorldMap.nut
 | |
| 路径:Project/NewWorldMap/NewWorldMap.nut
 | |
| 创建日期:2024-10-27	10:24
 | |
| 文件用途:新世界地图
 | |
| */
 | |
| class NewWorldMapC extends LenheartNewUI_Windows {
 | |
|     //调试模式
 | |
|     // DeBugMode = true;
 | |
| 
 | |
|     //不是窗口
 | |
|     // NoWindow = true;
 | |
| 
 | |
|     //是否可见
 | |
|     // Visible = false;
 | |
| 
 | |
|     //世界
 | |
|     World = null;
 | |
|     //区域
 | |
|     Region = null;
 | |
|     //当前自身所在世界
 | |
|     SelfMapWorld = 0;
 | |
|     //当前自身所在区域
 | |
|     SelfMapRegion = 0;
 | |
|     //当前地图浏览区域
 | |
|     MapRegion = -1;
 | |
| 
 | |
|     //Img
 | |
|     WorldMapImg = null;
 | |
|     StepImg = null;
 | |
| 
 | |
|     Ani = null;
 | |
| 
 | |
| 
 | |
|     Timer = Clock();
 | |
| 
 | |
|     constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
 | |
|         Childrens = [];
 | |
|         Region = [];
 | |
|         World = [];
 | |
|         //注册控件
 | |
|         RegisterWidget();
 | |
| 
 | |
|         LenheartNewUI_Windows.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH);
 | |
| 
 | |
|         InitData();
 | |
|         // printT(Region);
 | |
|         LoadImg();
 | |
| 
 | |
|     }
 | |
| 
 | |
|     function LoadImg() {
 | |
|         WorldMapImg = Rindro_Image("worldmap.img");
 | |
|         StepImg = {};
 | |
|     }
 | |
| 
 | |
|     function InitData() {
 | |
|         //读取世界
 | |
|         local WorldLst = R_Utils.GetLstArr("region/world.lst", "region/");
 | |
|         foreach(Path in WorldLst) {
 | |
|             InitWorld(Path);
 | |
|         }
 | |
| 
 | |
|         //读取区域
 | |
|         local RegionLst = R_Utils.GetLstArr("region/region.lst", "region/");
 | |
|         foreach(Path in RegionLst) {
 | |
|             InitRegion(Path);
 | |
|         }
 | |
| 
 | |
|         //读取小地图
 | |
|         InitMiniMap();
 | |
|     }
 | |
| 
 | |
|     function InitWorld(Path) {
 | |
|         local Data = R_Utils.GetFileTableByHandle(Path, function(DataT, IO, i) {
 | |
|             local str = Rindro_Script.UnpackData(IO, i);
 | |
|             i += 5;
 | |
|             //城镇编号
 | |
|             if (str == "[areas]") {
 | |
|                 DataT.Areas <- [];
 | |
|                 while (true) {
 | |
|                     local Ret = Rindro_Script.UnpackData(IO, i);
 | |
|                     i += 5;
 | |
|                     if (Ret == "[/areas]") break;
 | |
|                     DataT.Areas.append((Ret.tointeger() - 9));
 | |
|                 }
 | |
|             }
 | |
|             //背景
 | |
|             else if (str == "[background]") {
 | |
|                 DataT.Background <- {};
 | |
|                 DataT.Background.path <- Rindro_Script.UnpackData(IO, i);
 | |
|                 i += 5;
 | |
|                 DataT.Background.frame <- Rindro_Script.UnpackData(IO, i).tointeger() - 9;
 | |
|                 i += 5;
 | |
|             }
 | |
|             //坐标
 | |
|             else if (str == "[pos]") {
 | |
|                 local Index = Rindro_Script.UnpackData(IO, i).tointeger() - 9;
 | |
|                 i += 5;
 | |
|                 local Path = Rindro_Script.UnpackData(IO, i);
 | |
|                 i += 5;
 | |
|                 DataT["pos_" + Index] <- [];
 | |
|                 DataT["pos_" + Index].append(Path);
 | |
|                 while (true) {
 | |
|                     local Ret = Rindro_Script.UnpackData(IO, i);
 | |
|                     i += 5;
 | |
|                     if (Ret == "[/pos]") break;
 | |
|                     DataT["pos_" + Index].append((Ret.tointeger() - 9));
 | |
|                 }
 | |
|             }
 | |
|             return i;
 | |
|         }.bindenv(this));
 | |
|         World.append(Data);
 | |
|         printT(Data);
 | |
|     }
 | |
| 
 | |
|     function InitRegion(Path) {
 | |
|         local RegionData = R_Utils.GetScriptFileReader(Path);
 | |
|         if (RegionData) {
 | |
|             local Data = {};
 | |
|             if (RegionData.Size >= 7) {
 | |
|                 //创建Blob对象
 | |
|                 local IO = Sq_Point2Blob(L_sq_P2I(RegionData.Buffer.C_Object), RegionData.Size);
 | |
|                 //以5为单步从第二位开始遍历字节
 | |
|                 local i = 2;
 | |
|                 while (true) {
 | |
|                     if (i< RegionData.Size && RegionData.Size - i >= 5) {
 | |
|                         local str = Rindro_Script.UnpackData(IO, i);
 | |
|                         i += 5;
 | |
|                         //城镇编号
 | |
|                         if (str == "[towns]") {
 | |
|                             Data.Towns <- {};
 | |
|                             while (true) {
 | |
|                                 local Ret = Rindro_Script.UnpackData(IO, i);
 | |
|                                 i += 5;
 | |
|                                 if (Ret == "[/towns]") break;
 | |
|                                 Data.Towns.rawset((Ret.tointeger() - 9), {});
 | |
|                             }
 | |
|                         }
 | |
|                         //名称
 | |
|                         else if (str == "[name]" || str == "[english name]" || str == "[minimap]") {
 | |
|                             local RealKey = str.slice(1, str.len() - 1);
 | |
|                             local Ret = Rindro_Script.UnpackData(IO, i);
 | |
|                             if (str == "[name]") Ret = Sq_ConvertWideChar(Ret, "big5")
 | |
|                             Data[RealKey] <- Ret;
 | |
|                             i += 5;
 | |
|                         }
 | |
|                     } else break;
 | |
|                 }
 | |
|             }
 | |
|             Region.append(Data);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function InitMiniMap() {
 | |
|         foreach(Pos, Value in Region) {
 | |
|             local Path = "region/" + Value.minimap.tolower();
 | |
|             local MiniMapData = R_Utils.GetScriptFileReader(Path);
 | |
|             if (MiniMapData) {
 | |
|                 local Data = {};
 | |
|                 if (MiniMapData.Size >= 7) {
 | |
|                     //创建Blob对象
 | |
|                     local IO = Sq_Point2Blob(L_sq_P2I(MiniMapData.Buffer.C_Object), MiniMapData.Size);
 | |
|                     //以5为单步从第二位开始遍历字节
 | |
|                     local i = 2;
 | |
|                     while (true) {
 | |
|                         if (i< MiniMapData.Size && MiniMapData.Size - i >= 5) {
 | |
|                             local str = Rindro_Script.UnpackData(IO, i);
 | |
|                             i += 5;
 | |
| 
 | |
|                             //城镇编号
 | |
|                             if (str == "[image]") {
 | |
|                                 Data.Image <- {};
 | |
|                                 while (true) {
 | |
|                                     local Ret = Rindro_Script.UnpackData(IO, i);
 | |
|                                     i += 5;
 | |
|                                     if (Ret == "[/image]") break;
 | |
|                                     Ret = Ret.slice(1, -1);
 | |
| 
 | |
|                                     local imgpath = Rindro_Script.UnpackData(IO, i);
 | |
|                                     i += 5;
 | |
|                                     local imgframe = Rindro_Script.UnpackData(IO, i).tointeger() - 9;
 | |
|                                     i += 5;
 | |
|                                     Data.Image.rawset(Ret, {
 | |
|                                         path = imgpath,
 | |
|                                         frame = imgframe
 | |
|                                     });
 | |
|                                 }
 | |
|                             }
 | |
| 
 | |
|                         } else break;
 | |
|                     }
 | |
|                 }
 | |
|                 Region[Pos].Data <- Data;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function RegisterWidget() {
 | |
|         // //关闭按钮
 | |
|         // local CloseButton = LenheartNewUI_BaseButton(278, 0, 11, 12, "interface/lenheartwindowcommon.img", 276);
 | |
|         // CloseButton.OnClick = function() {
 | |
|         //     this.Visible = false;
 | |
|         // }.bindenv(this);
 | |
|         // Childrens.append(CloseButton);
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     function GetMoveOffset(L, R) {
 | |
|         return (-L) + (L.tofloat() * (R.tofloat() / 100.0)).tointeger()
 | |
|     }
 | |
|     //绘制主界面
 | |
|     function DrawMain(obj) {
 | |
|         local Config = Region[SelfMapRegion];
 | |
| 
 | |
|         //绘制背景
 | |
|         WorldMapImg.DrawExPng(0, 0, -83, 0, 0xffffffff, 0.84, 0.84);
 | |
|         //绘制地图背景
 | |
|         DrawLogic(Config);
 | |
| 
 | |
|         local UniRate = sq_GetAccel(0, 100, Clock() - Timer, 1000);
 | |
|         local AccRate = sq_GetAccel(0, 100, Clock() - Timer, 1000, true);
 | |
|         //绘制左上云1
 | |
|         WorldMapImg.DrawExPng(1, GetMoveOffset(100, AccRate), 0, 0, sq_RGBA(255, 255, 255, ((UniRate.tofloat() / 100.0) * 255.0).tointeger()), 0.84, 0.84);
 | |
|         //绘制左上云2
 | |
|         WorldMapImg.DrawExPng(2, GetMoveOffset(100, AccRate), GetMoveOffset(50, AccRate), 0, sq_RGBA(255, 255, 255, ((UniRate.tofloat() / 100.0) * 255.0).tointeger()), 0.84, 0.84);
 | |
|         //绘制左下云
 | |
|         WorldMapImg.DrawExPng(3, GetMoveOffset(100, AccRate), 404 + GetMoveOffset(-50, AccRate), 0, sq_RGBA(255, 255, 255, ((UniRate.tofloat() / 100.0) * 255.0).tointeger()), 0.84, 0.84);
 | |
|         //绘制右上云
 | |
|         WorldMapImg.DrawExPng(4, 868 + GetMoveOffset(-100, AccRate), 0, 0, sq_RGBA(255, 255, 255, ((UniRate.tofloat() / 100.0) * 255.0).tointeger()), 0.84, 0.84);
 | |
|         //绘制右下云
 | |
|         WorldMapImg.DrawExPng(5, 762 + GetMoveOffset(-100, AccRate), 389 + GetMoveOffset(-50, AccRate), 0, sq_RGBA(255, 255, 255, ((UniRate.tofloat() / 100.0) * 255.0).tointeger()), 0.84, 0.84);
 | |
| 
 | |
| 
 | |
|         // local ani = obj.getVar().GetAnimationMap("test", "common/test.ani");
 | |
|         // sq_SetfRotateAngle(ani, sq_ToRadian(60.0));
 | |
|         // sq_AnimationProc(ani);
 | |
|         // sq_drawCurrentFrame(ani, 200, 200, true);
 | |
| 
 | |
|         // Ani.Draw(400, 400);
 | |
| 
 | |
|         local angle = (GetMoveOffset(135, UniRate).tofloat()) % 360;
 | |
|         //中心点
 | |
|         local centerX = 120.0 * 0.6 / 2;
 | |
|         local centerY = 120.0 * 0.6 / 2;
 | |
|         local Lenght = sqrt(centerX * centerX + centerY * centerY);
 | |
|         local atan = sq_ToDegree(sq_Atan2(centerY, centerX));
 | |
|         local NextAngle = (atan + angle).tointeger();
 | |
| 
 | |
|         local NextX = (Lenght * sq_CosTable(NextAngle));
 | |
|         local NextY = (Lenght * sq_SinTable(NextAngle));
 | |
| 
 | |
|         local newRelX = (centerX - NextX);
 | |
|         local newRelY = (centerY - NextY);
 | |
| 
 | |
|         WorldMapImg.DrawExPng(7, 20, 470, 0, sq_RGBA(255, 255, 255, ((UniRate.tofloat() / 100.0) * 255.0).tointeger()), 0.6, 0.6);
 | |
|         WorldMapImg.DrawExPng(6, 39 + newRelX, 489 + newRelY, sq_ToRadian(-angle.tofloat()), 0xffffffff, 0.6, 0.6);
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
|     function Show(obj) {
 | |
|         DrawMain(obj);
 | |
|         LenheartNewUI_Windows.Show(obj);
 | |
|     }
 | |
| 
 | |
|     function GetImgObject(path) {
 | |
|         if (!(StepImg.rawin(path))) StepImg.rawset(path, Rindro_Image(path));
 | |
|         return StepImg[path];
 | |
|     }
 | |
| 
 | |
| 
 | |
|     // 环绕数法判断点是否在多边形内
 | |
|     function IsPointInPolygonWindingNumber(x, y, polygon) {
 | |
|         local windingNumber = 0;
 | |
|         local n = polygon.len();
 | |
|         for (local i = 0; i< n; ++i) {
 | |
|             local x1 = polygon[i][0];
 | |
|             local y1 = polygon[i][1];
 | |
|             local x2 = polygon[(i + 1) % n][0];
 | |
|             local y2 = polygon[(i + 1) % n][1];
 | |
|             if (y1 <= y) {
 | |
|                 if (y2 > y && ((x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0)) {
 | |
|                     windingNumber++;
 | |
|                 }
 | |
|             } else {
 | |
|                 if (y2 <= y && ((x2 - x1) * (y - y1) - (x - x1) * (y2 - y1)< 0)) {
 | |
|                     windingNumber--;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return windingNumber != 0;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     //绘制世界
 | |
|     function DrawWorld(Config) {
 | |
|         local MapCurIndex = SelfMapWorld;
 | |
|         local BackgroundData = World[MapCurIndex].Background;
 | |
| 
 | |
|         local UniRate = sq_GetAccel(0, 250, Clock() - Timer, 1500);
 | |
| 
 | |
|         local BackgroundDataImgObj = GetImgObject(BackgroundData.path);
 | |
|         BackgroundDataImgObj.DrawExPng(BackgroundData.frame, 0, -60, 0, sq_RGBA(255, 255, 255, UniRate), 1.32, 1.32);
 | |
| 
 | |
|         foreach(index in World[MapCurIndex].Areas) {
 | |
|             // print(index);
 | |
|             if (!(World[MapCurIndex].rawin("pos_" + index))) continue;
 | |
|             local Config = World[MapCurIndex]["pos_" + index];
 | |
|             local BackgroundDataImgObj = GetImgObject(Config[0]);
 | |
|             local PointArr = [];
 | |
|             for (local i = 4; i< Config.len(); i += 2) {
 | |
|                 local Buf = [];
 | |
|                 Buf.append(Config[i]);
 | |
|                 Buf.append(Config[i + 1]);
 | |
|                 PointArr.append(Buf);
 | |
|             }
 | |
|             if (IsPointInPolygonWindingNumber(IMouse.GetXPos().tofloat(), IMouse.GetYPos().tofloat(), PointArr)) {
 | |
|                 BackgroundDataImgObj.DrawExPng(Config[1], Config[2], Config[3] - 60, 0, sq_RGBA(255, 255, 255, UniRate), 1.32, 1.32);
 | |
|             }
 | |
|             foreach(pos in PointArr) {
 | |
|                 L_sq_DrawImg("interface/windowcommon.img", 50, pos[0], pos[1]);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     //绘制区域
 | |
|     function DrawArea(Config) {
 | |
| 
 | |
|     }
 | |
| 
 | |
|     //绘制城镇地图
 | |
|     function DrawTownMap(Config) {
 | |
| 
 | |
|         // local UniRate = sq_GetAccel(250, 0, Clock() - 3000 - Timer, 1000);
 | |
|         // local BackgroundData = Config.Data.Image.background;
 | |
|         // if (!(StepImg.rawin(BackgroundData.path))) StepImg.rawset(BackgroundData.path, Rindro_Image(BackgroundData.path));
 | |
|         // StepImg[BackgroundData.path].DrawExPng(BackgroundData.frame, 0, -8, 0, sq_RGBA(255, 255, 255, UniRate), 1.0, 1.055);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     //绘制逻辑
 | |
|     function DrawLogic(Config) {
 | |
|         //绘制世界
 | |
|         DrawWorld(Config);
 | |
|         //绘制区域
 | |
|         DrawArea(Config);
 | |
|         //绘制城镇
 | |
|         DrawTownMap(Config);
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
|     //同步自身现在在哪个地图区域
 | |
|     function SyncSelfMapRegion() {
 | |
|         local Town = L_sq_GetTownIndex();
 | |
|         foreach(AreaIndex, Areaobj in Region) {
 | |
|             foreach(TownIndex, Townobj in Areaobj.Towns) {
 | |
|                 if (TownIndex == Town) {
 | |
|                     SelfMapRegion = AreaIndex;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     //同步自身现在在哪个地图世界
 | |
|     function SyncSelfMapWorld() {
 | |
|         foreach(WorldIndex, Worldobj in World) {
 | |
|             foreach(AreaIndex, Areaobj in Worldobj.Areas) {
 | |
|                 if (AreaIndex == SelfMapRegion) {
 | |
|                     SelfMapWorld = WorldIndex;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     //逻辑入口
 | |
|     function Proc(obj) {
 | |
|         SyncSelfMapRegion();
 | |
|         SyncSelfMapWorld();
 | |
|         LenheartNewUI_Windows.SyncPos(X, Y);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     //简便性能高的开平方
 | |
|     function sqrt(sum) {
 | |
|         local i = (sum / 2).tofloat();
 | |
| 
 | |
|         local isb = 0;
 | |
|         for (isb = 0; isb< 10; isb++) {
 | |
|             i = (i - ((i * i - sum) / (2 * i))).tofloat();
 | |
|         }
 | |
|         return i;
 | |
| 
 | |
|     }
 | |
| 
 | |
| }
 | |
| getroottable().rawdelete("NewWorldMap_Obj");
 | |
| 
 | |
| function Lenheart_NewWorldMap_Fun(obj) {
 | |
|     local RootTab = getroottable();
 | |
|     if (!RootTab.rawin("NewWorldMap_Obj")) {
 | |
|         RootTab.rawset("NewWorldMap_Obj", true);
 | |
|         LenheartNewUI_CreateWindow(NewWorldMapC, "新世界地图", 0, 0, getroottable().Rindro_Scr_Width, 600, 0);
 | |
|     }
 | |
| }
 | |
| 
 | |
| getroottable()["LenheartFuncTab"].rawset("NewWorldMapFuncN", Lenheart_NewWorldMap_Fun); |