Rindro-Sqr/Project/NewWorldMap/NewWorldMap.nut

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);