This commit is contained in:
		
						commit
						0667533bc2
					
				|  | @ -0,0 +1,5 @@ | ||||||
|  | ImagePacks2/ | ||||||
|  | SoundPacks/ | ||||||
|  | Yosin_Game_Reloading.Sign | ||||||
|  | Script.pvf | ||||||
|  | Yosin_Engine.pdb | ||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | {"HistoryBestScore":5} | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | {} | ||||||
|  | @ -0,0 +1,19 @@ | ||||||
|  | /* | ||||||
|  | 文件名:ActorObject.nut | ||||||
|  | 路径:BaseClass/ActorObject/ActorObject.nut | ||||||
|  | 创建日期:2024-05-09	21:15 | ||||||
|  | 文件用途:Actor演员 | ||||||
|  | */ | ||||||
|  | class Actor extends CL_BaseObject { | ||||||
|  | 
 | ||||||
|  |     constructor(...) { | ||||||
|  |         local C_Object; | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             C_Object = BaseObject_Create(); | ||||||
|  |             base.constructor(C_Object); | ||||||
|  |         } else { | ||||||
|  |             C_Object = vargv[0]; | ||||||
|  |             base.constructor(C_Object, true); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,210 @@ | ||||||
|  | /* | ||||||
|  | 文件名:AnimationClass.nut | ||||||
|  | 路径:Core/BaseClass/AnimationClass/AnimationClass.nut | ||||||
|  | 创建日期:2024-05-07	23:25 | ||||||
|  | 文件用途:动画类 | ||||||
|  | */ | ||||||
|  | class Animation extends Actor { | ||||||
|  | 
 | ||||||
|  |     //Ani是否可用 | ||||||
|  |     IsUsability = true; | ||||||
|  | 
 | ||||||
|  |     //当前帧数 | ||||||
|  |     CurrentFrameIndex = 0; | ||||||
|  |     //当前帧时间 | ||||||
|  |     CurrentIndexT = 0; | ||||||
|  |     //当前帧 | ||||||
|  |     CurrentFrame = null; | ||||||
|  |     //状态机对象(只有存在时才有KeyFlag) | ||||||
|  |     StateMachine = null; | ||||||
|  | 
 | ||||||
|  |     //Ani的标签 | ||||||
|  |     AnimationFlag = null; | ||||||
|  |     //帧对象数组 | ||||||
|  |     FrameArr = null; | ||||||
|  |     //图片精灵帧对象 | ||||||
|  |     SpriteArr = null; | ||||||
|  | 
 | ||||||
|  |     //Ani类型 | ||||||
|  |     Type = "normal"; | ||||||
|  | 
 | ||||||
|  |     //附加选项 | ||||||
|  |     AdditionalOptions = null; | ||||||
|  | 
 | ||||||
|  |     constructor(...) { | ||||||
|  |         //精灵帧数组 | ||||||
|  |         SpriteArr = []; | ||||||
|  |         //帧数组 | ||||||
|  |         FrameArr = []; | ||||||
|  |         base.constructor(); | ||||||
|  | 
 | ||||||
|  |         //判断是否有特殊处理 | ||||||
|  |         if (vargv.len() > 1) { | ||||||
|  |             AdditionalOptions = vargv[1]; | ||||||
|  |         } | ||||||
|  |         //初始化数据 | ||||||
|  |         InitData(vargv[0]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function InitData(Data) { | ||||||
|  |         local Buf; | ||||||
|  |         if (type(Data) == "table") { | ||||||
|  |             Buf = Data; | ||||||
|  |         } | ||||||
|  |         //从PVF数据加载 | ||||||
|  |         else if (type(Data) == "string") { | ||||||
|  |             Data = String.RegRealPath(Data); | ||||||
|  |             Buf = sq_DeepCopy(ScriptData.GetAni(Data)); | ||||||
|  |             //还需要判断一下有没有als | ||||||
|  |             local AlsBuf = ScriptData.GetFile(Data + ".als"); | ||||||
|  |             if (AlsBuf) { | ||||||
|  |                 local m_data = ScriptData.GetFileData(Data + ".als", function(DataTable, Data) { | ||||||
|  |                     local Anilist = {}; | ||||||
|  |                     while (!Data.Eof()) { | ||||||
|  |                         local Pack = Data.Get(); | ||||||
|  |                         if (Pack == "[use animation]") { | ||||||
|  |                             local AniPath = Data.Get(); | ||||||
|  |                             local AniKey = Data.Get(); | ||||||
|  |                             if (!(AniKey in Anilist)) | ||||||
|  |                                 Anilist[AniKey] <- {}; | ||||||
|  |                             Anilist[AniKey].path <- AniPath; | ||||||
|  |                         } else if (Pack == "[none effect add]") { | ||||||
|  |                             local AniLayer = [Data.Get(), Data.Get()]; | ||||||
|  |                             local AniKey = Data.Get(); | ||||||
|  |                             if (!(AniKey in Anilist)) | ||||||
|  |                                 Anilist[AniKey] <- {}; | ||||||
|  |                             Anilist[AniKey].layer <- AniLayer; | ||||||
|  |                         } else if (Pack == "[add]") { | ||||||
|  |                             local AniLayer = [Data.Get(), Data.Get()]; | ||||||
|  |                             local AniKey = Data.Get(); | ||||||
|  |                             if (!(AniKey in Anilist)) | ||||||
|  |                                 Anilist[AniKey] <- {}; | ||||||
|  |                             Anilist[AniKey].layer <- AniLayer; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     DataTable.Anilist <- Anilist; | ||||||
|  |                     DataTable.dirpath <- DataTable.filepath.slice(0, DataTable.filepath.lastfind("/") + 1); | ||||||
|  |                 }); | ||||||
|  |                 foreach(Index, Info in m_data.Anilist) { | ||||||
|  |                     local anibuf = Animation(m_data.dirpath + Info.path.tolower()); | ||||||
|  |                     anibuf.SetZOrder(Info.layer[1]); | ||||||
|  |                     Addchild(anibuf); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (Buf) { | ||||||
|  |             AnimationFlag = Buf.Flag; | ||||||
|  |             FrameArr = Buf.Frame; | ||||||
|  |             foreach(FrameObj in FrameArr) { | ||||||
|  |                 //如果有附加处理 格式化 | ||||||
|  |                 if (AdditionalOptions && AdditionalOptions.rawin("ImgFormat")) FrameObj.Img_Path = AdditionalOptions["ImgFormat"](FrameObj.Img_Path); | ||||||
|  | 
 | ||||||
|  |                 local SpriteFramebuf = CL_SpriteFrameObject("sprite/" + FrameObj.Img_Path, FrameObj.Img_Index); | ||||||
|  |                 local Spritebuf = CL_SpriteObject(); | ||||||
|  |                 Spritebuf.SetFrame(SpriteFramebuf); | ||||||
|  | 
 | ||||||
|  |                 //线性减淡 | ||||||
|  |                 if ("GRAPHIC_EFFECT_LINEARDODGE" in FrameObj.Flag) { | ||||||
|  |                     Spritebuf.SetMode(0); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 //坐标 | ||||||
|  |                 Spritebuf.SetPosition(FrameObj.Pos); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 SpriteArr.append(Spritebuf); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             error("创建Ani失败,找不到Ani数据"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //初始化完毕设置大小为第0帧大小否则天空 地板等依靠大小的初始化会有问题 | ||||||
|  |         SetSize(SpriteArr[0].GetSize()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //被添加时  要刷新一下当前帧 | ||||||
|  |     function OnAddchild(Parent) { | ||||||
|  |         FlushFrame(0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //重置Ani | ||||||
|  |     function Reset() { | ||||||
|  |         IsUsability = true; | ||||||
|  |         FlushFrame(0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //赋予状态机 | ||||||
|  |     function BindenvStateMachine(gM) { | ||||||
|  |         StateMachine = gM; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获取当前帧信息 | ||||||
|  |     function GetCurrentFrameInfo() { | ||||||
|  |         return FrameArr[CurrentFrameIndex]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function FlushFrame(Index) { | ||||||
|  |         //同步当前帧 | ||||||
|  |         CurrentFrameIndex = Index; | ||||||
|  |         //移除上一帧 | ||||||
|  |         if (CurrentFrame) Removechild(CurrentFrame); | ||||||
|  |         //当前帧更换为本帧 | ||||||
|  |         CurrentFrame = SpriteArr[CurrentFrameIndex]; | ||||||
|  |         Addchild(SpriteArr[CurrentFrameIndex]); | ||||||
|  | 
 | ||||||
|  |         local FlagBuf = FrameArr[CurrentFrameIndex].Flag; | ||||||
|  |         //关键帧 | ||||||
|  |         if ("SET_FLAG" in FlagBuf) { | ||||||
|  |             if (StateMachine && StateMachine.State != -1) StateMachine.ChangeAniKeyFlag(FlagBuf.SET_FLAG); | ||||||
|  |         } | ||||||
|  |         //播放音效 | ||||||
|  |         if ("PLAY_SOUND" in FlagBuf) { | ||||||
|  |             Sq_PlaySoundEffect(FlagBuf.PLAY_SOUND); | ||||||
|  |         } | ||||||
|  |         //缩放 | ||||||
|  |         if ("IMAGE_RATE" in FlagBuf) { | ||||||
|  |             SetScale(FlagBuf.IMAGE_RATE.x, FlagBuf.IMAGE_RATE.y); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //Ani对象的大小同步为精灵帧对象的大小 | ||||||
|  |         if (CurrentFrame) SetSize(CurrentFrame.GetSize()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //override | ||||||
|  |     function OnUpdate(dt) { | ||||||
|  | 
 | ||||||
|  |         //可用性检查 | ||||||
|  |         if (IsUsability) { | ||||||
|  |             //累加当前帧时间 | ||||||
|  |             CurrentIndexT += dt; | ||||||
|  | 
 | ||||||
|  |             //当前帧时间 超过 当前帧延迟就需要切换帧了 | ||||||
|  |             if (CurrentIndexT >= FrameArr[CurrentFrameIndex].Delay) { | ||||||
|  |                 CurrentIndexT = 0; | ||||||
|  |                 //如果当前帧小于总帧数就切换 | ||||||
|  |                 if (CurrentFrameIndex<(FrameArr.len() - 1)) { | ||||||
|  |                     FlushFrame(CurrentFrameIndex + 1); | ||||||
|  |                 } | ||||||
|  |                 //说明播放完毕了 | ||||||
|  |                 else { | ||||||
|  |                     //如果有循环 | ||||||
|  |                     if ("LOOP" in AnimationFlag) { | ||||||
|  |                         FlushFrame(0); | ||||||
|  |                     } | ||||||
|  |                     //没有循环触发状态机回调 | ||||||
|  |                     else { | ||||||
|  |                         //将不再可用 | ||||||
|  |                         IsUsability = false; | ||||||
|  |                         if (StateMachine && StateMachine.State != -1) StateMachine.ChangeAniEndFlag(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         base.OnUpdate(dt); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,221 @@ | ||||||
|  | /* | ||||||
|  | 文件名:AudioClass.nut | ||||||
|  | 路径:Core/BaseClass/AudioClass.nut | ||||||
|  | 创建日期:2024-05-30	20:48 | ||||||
|  | 文件用途:音频类 | ||||||
|  | */ | ||||||
|  | if (!(getroottable().rawin("_Globa_Audio_Volume_"))) _Globa_Audio_Volume_ <- 1.0; | ||||||
|  | if (!(getroottable().rawin("_SoundEffect_List_"))) _SoundEffect_List_ <- []; | ||||||
|  | class Sound extends CL_BaseObject { | ||||||
|  |     //名称 | ||||||
|  |     Name = null; | ||||||
|  |     //路径 | ||||||
|  |     Path = null; | ||||||
|  |     //使用时间 | ||||||
|  |     UseTime = null; | ||||||
|  |     //创建时间 | ||||||
|  |     CreateTime = null; | ||||||
|  | 
 | ||||||
|  |     constructor(gName) { | ||||||
|  |         Path = gName; | ||||||
|  |         local C_Object = Sound_CreateSound(Path); | ||||||
|  |         base.constructor(C_Object); | ||||||
|  | 
 | ||||||
|  |         CreateTime = clock(); | ||||||
|  |         SetVolume(1.0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //播放 | ||||||
|  |     function Play() { | ||||||
|  |         Sound_Play(C_Object); | ||||||
|  |         UseTime = clock(); | ||||||
|  |     } | ||||||
|  |     //暂停 | ||||||
|  |     function Pause() { | ||||||
|  |         Sound_Pause(C_Object); | ||||||
|  |     } | ||||||
|  |     //继续 | ||||||
|  |     function Resume() { | ||||||
|  |         Sound_Resume(C_Object); | ||||||
|  |     } | ||||||
|  |     //关闭并销毁 | ||||||
|  |     function Close() { | ||||||
|  |         Sound_Close(C_Object); | ||||||
|  |     } | ||||||
|  |     //获取音量 | ||||||
|  |     function GetVolume() { | ||||||
|  |         return Sound_GetVolume(C_Object); | ||||||
|  |     } | ||||||
|  |     //设置音量 | ||||||
|  |     function SetVolume(value) { | ||||||
|  |         Sound_SetVolume(C_Object, value * _Globa_Audio_Volume_); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function IsPlaying() { | ||||||
|  |         return Sound_IsPlaying(C_Object); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class SoundEffect extends Sound { | ||||||
|  | 
 | ||||||
|  |     constructor(Name) { | ||||||
|  |         base.constructor(Name); | ||||||
|  | 
 | ||||||
|  |         //加入全局临时音效组 | ||||||
|  |         JoinSoundEffect(); | ||||||
|  |         //默认调用播放 | ||||||
|  |         Play(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //加入全局临时音效组 | ||||||
|  |     function JoinSoundEffect() { | ||||||
|  |         _SoundEffect_List_.append(this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class AudioControlClass { | ||||||
|  | 
 | ||||||
|  |     //当前播放音乐集合 | ||||||
|  |     CurrentMusicList = null; | ||||||
|  |     //音源库 | ||||||
|  |     MusicList = null; | ||||||
|  | 
 | ||||||
|  |     //销毁临时音效的时间Flag | ||||||
|  |     CloseSoundEffectTimeFlag = 0; | ||||||
|  |     //销毁临时音效的间隔时间  //5秒一次 | ||||||
|  |     CloseSoundEffectTime = 5000; | ||||||
|  |     //销毁音乐的时间Flag | ||||||
|  |     CloseMusicTimeFlag = 0; | ||||||
|  |     //销毁音乐的间隔时间  //5秒一次 | ||||||
|  |     CloseMusicTime = 5000; | ||||||
|  | 
 | ||||||
|  |     //待移除音乐 | ||||||
|  |     RemoveMusicQueue = null; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         CurrentMusicList = {}; | ||||||
|  |         MusicList = {}; | ||||||
|  |         RemoveMusicQueue = []; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //预加载音乐 | ||||||
|  |     function PreLoad(Name) { | ||||||
|  |         local Ret = Sound(Name); | ||||||
|  |         MusicList[Name] <- Ret; | ||||||
|  |     } | ||||||
|  |     //加载音乐  加载完成会自动播放 | ||||||
|  |     function Load(Name) { | ||||||
|  |         if (MusicList.rawin(Name)) { | ||||||
|  |             CurrentMusicList[Name] <- MusicList[Name]; | ||||||
|  |             MusicList[Name].Play(); | ||||||
|  |         } else { | ||||||
|  |             local Ret = Sound(Name); | ||||||
|  |             Ret.Play(); | ||||||
|  |             CurrentMusicList[Name] <- Ret; | ||||||
|  |             MusicList[Name] <- Ret; | ||||||
|  |         } | ||||||
|  |         return CurrentMusicList[Name]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //移除音乐 | ||||||
|  |     function Remove(Name) { | ||||||
|  |         CurrentMusicList[Name].Pause(); | ||||||
|  |         delete CurrentMusicList[Name]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //淡出移除音乐 不传值默认倍率  传值设定倍率 | ||||||
|  |     function RemoveByFadeout(Name, ...) { | ||||||
|  |         local realrate = 1.0; | ||||||
|  |         if (vargv.len() > 0) realrate = vargv[0]; | ||||||
|  |         RemoveMusicQueue.append({ | ||||||
|  |             sound = CurrentMusicList[Name], | ||||||
|  |             rate = realrate | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function RemoveMusic(dt) { | ||||||
|  |         for (local i = 0; i< RemoveMusicQueue.len(); i++) { | ||||||
|  |             local Object = RemoveMusicQueue[i]; | ||||||
|  |             local SoundObj = Object.sound; | ||||||
|  |             local Rate = Object.rate; | ||||||
|  |             local SoCurV = SoundObj.GetVolume(); | ||||||
|  |             //音量降到最低了  停止播放 | ||||||
|  |             if (SoCurV == 0) { | ||||||
|  |                 SoundObj.Pause(); | ||||||
|  |                 delete CurrentMusicList[SoundObj.Name]; | ||||||
|  |                 RemoveMusicQueue.remove(i); | ||||||
|  |             } | ||||||
|  |             //渐变设置音量 | ||||||
|  |             else { | ||||||
|  |                 local SetValue = SoCurV - (dt * Rate * 0.0005); | ||||||
|  |                 if (SetValue< 0) SetValue = 0; | ||||||
|  |                 SoundObj.SetVolume(SetValue); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnUpdate(dt, Stage) { | ||||||
|  | 
 | ||||||
|  |         //移除音乐(淡出) | ||||||
|  |         RemoveMusic(dt); | ||||||
|  | 
 | ||||||
|  |         //销毁临时音效 | ||||||
|  |         CloseSoundEffect(dt); | ||||||
|  |         //销毁音乐 | ||||||
|  |         CloseMusic(dt); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function CloseSoundEffect(dt) { | ||||||
|  |         CloseSoundEffectTimeFlag += dt; | ||||||
|  |         if (CloseSoundEffectTimeFlag >= CloseSoundEffectTime) { | ||||||
|  |             for (local i = 0; i< _SoundEffect_List_.len(); i++) { | ||||||
|  |                 local SoundEffectObj = _SoundEffect_List_[i]; | ||||||
|  |                 //播放完成销毁资源 | ||||||
|  |                 if (!SoundEffectObj.IsPlaying()) { | ||||||
|  |                     _SoundEffect_List_.remove(i); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             CloseSoundEffectTimeFlag = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function CloseMusic(dt) { | ||||||
|  |         CloseMusicTimeFlag += dt; | ||||||
|  |         if (CloseMusicTimeFlag >= CloseMusicTime) { | ||||||
|  |             local CurrT = clock(); | ||||||
|  |             //遍历 如果正在播放刷新时间 | ||||||
|  |             foreach(SoundObj in MusicList) { | ||||||
|  |                 if (SoundObj.IsPlaying()) SoundObj.UseTime = CurrT; | ||||||
|  |             } | ||||||
|  |             //遍历判断使用时间距离现在已经超过了500秒就销毁 | ||||||
|  |             local Arr = []; | ||||||
|  |             foreach(SoundObj in MusicList) { | ||||||
|  |                 if (SoundObj.UseTime && (clock() - SoundObj.UseTime) > 500000) { | ||||||
|  |                     Arr.append(SoundObj.Name); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             foreach(Name in Arr) { | ||||||
|  |                 if (CurrentMusicList.rawin(Name)) CurrentMusicList.rawdelete(Name); | ||||||
|  |                 if (MusicList.rawin(Name)) MusicList.rawdelete(Name); | ||||||
|  |             } | ||||||
|  |             CloseMusicTimeFlag = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | if (!(getroottable().rawin("AudioControl"))) _Global_AudioControl_ <- AudioControlClass(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //播放临时音效 | ||||||
|  | function Sq_PlaySoundEffect(Name) { | ||||||
|  |     return SoundEffect(Name); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //全局音效逻辑 | ||||||
|  | function _Yosin_Sound_Logic_(Dt, Stage) { | ||||||
|  |     _Global_AudioControl_.OnUpdate(Dt, Stage); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,268 @@ | ||||||
|  | /* | ||||||
|  | 文件名:BaseObject.nut | ||||||
|  | 路径:BaseClass/BaseObject/BaseObject.nut | ||||||
|  | 创建日期:2024-05-05	00:18 | ||||||
|  | 文件用途:基础对象Class | ||||||
|  | */ | ||||||
|  | class CL_BaseObject { | ||||||
|  | 
 | ||||||
|  |     //父对象 | ||||||
|  |     Parent = null; | ||||||
|  |     //子对象数组 | ||||||
|  |     Children = null; | ||||||
|  |     //C指针 | ||||||
|  |     C_Object = null; | ||||||
|  |     //UpdateCallBack | ||||||
|  |     UpdateCallBackFunc = null; | ||||||
|  |     //已存在的时间 | ||||||
|  |     ExistingTime = 0; | ||||||
|  |     //自身信息存储Map | ||||||
|  |     Var = null; | ||||||
|  |     //销毁状态 | ||||||
|  |     DestroyFlag = false; | ||||||
|  | 
 | ||||||
|  |     constructor(C_Object, ...) { | ||||||
|  |         Children = {}; | ||||||
|  |         Var = {}; | ||||||
|  |         this.C_Object = C_Object; | ||||||
|  |         //如果是新创建的对象注册销毁析构 | ||||||
|  |         if (vargv.len() == 0) Register_Destruction(C_Object, this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置UpdateCallBack | ||||||
|  |     function SetUpdateFunc(Func) { | ||||||
|  |         UpdateCallBackFunc = Func; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //被调用 | ||||||
|  |     function OnUpdate(dt) { | ||||||
|  |         ExistingTime += dt; | ||||||
|  | 
 | ||||||
|  |         //如果CallBack函数存在则调用 | ||||||
|  |         if (UpdateCallBackFunc) UpdateCallBackFunc(this, dt); | ||||||
|  | 
 | ||||||
|  |         //遍历调用所有子对象 | ||||||
|  |         foreach(Id, Object in Children) { | ||||||
|  |             //如果子对象正常就执行Update | ||||||
|  |             if (!Object.DestroyFlag) { | ||||||
|  |                 Object.OnUpdate(dt); | ||||||
|  |             } | ||||||
|  |             //如果子对象的销毁Flag 存在 则移除并销毁 | ||||||
|  |             else { | ||||||
|  |                 Removechild(Object); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //鼠标逻辑处理 | ||||||
|  |     function OnMouseEvent(MouseState, Wheel, MousePos_X, MousePos_Y) { | ||||||
|  |         //遍历调用所有子对象 | ||||||
|  |         foreach(Id, Object in Children) { | ||||||
|  |             Object.OnMouseEvent(MouseState, Wheel, MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //添加子对象 | ||||||
|  |     function Addchild(Child) { | ||||||
|  |         Children[Child.GetId()] <- Child; | ||||||
|  |         Child.Parent = this.weakref(); | ||||||
|  |         //给自己解引用计数 | ||||||
|  | 
 | ||||||
|  |         Child.OnAddchild(this); | ||||||
|  |         BaseObject_Addchild(this.C_Object, Child.C_Object); | ||||||
|  |     } | ||||||
|  |     //移除子对象 | ||||||
|  |     function Removechild(Child) { | ||||||
|  |         try { | ||||||
|  |             delete Children[Child.GetId()]; | ||||||
|  |         } catch (exception) { | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         Child.Parent = null; | ||||||
|  |         Child.OnRemove(this); | ||||||
|  |         BaseObject_Removechild(this.C_Object, Child.C_Object); | ||||||
|  |     } | ||||||
|  |     //从父对象移除自己 | ||||||
|  |     function RemoveSelf() { | ||||||
|  |         DestroyFlag = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //被添加 | ||||||
|  |     function OnAddchild(Parent) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |     //被移除 | ||||||
|  |     function OnRemove(Parent) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置名字 | ||||||
|  |     function SetName(name) { | ||||||
|  |         BaseObject_SetName(this.C_Object, name); | ||||||
|  |     } | ||||||
|  |     //获取名字 | ||||||
|  |     function GetName() { | ||||||
|  |         return BaseObject_GetName(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取Id | ||||||
|  |     function GetId() { | ||||||
|  |         return BaseObject_GetId(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取显示状态 | ||||||
|  |     function IsVisible() { | ||||||
|  |         return BaseObject_IsVisible(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //是否启用级联透明度 | ||||||
|  |     function IsCascadeOpacityEnabled() { | ||||||
|  |         return BaseObject_IsCascadeOpacityEnabled(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //是否启用事件分发 | ||||||
|  |     function IsEventDispatchEnabled() { | ||||||
|  |         return BaseObject_IsEventDispatchEnabled(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取名称的 Hash 值 | ||||||
|  |     function GetHashName() { | ||||||
|  |         return BaseObject_GetHashName(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取 Z 轴顺序 | ||||||
|  |     function GetZOrder() { | ||||||
|  |         return BaseObject_GetZOrder(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取坐标 | ||||||
|  |     function GetPosition() { | ||||||
|  |         return BaseObject_GetPosition(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取世界坐标 | ||||||
|  |     function GetWorldPosition() { | ||||||
|  |         return BaseObject_ConvertToWorld(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取大小 | ||||||
|  |     function GetSize() { | ||||||
|  |         return BaseObject_GetSize(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取缩放后的大小 | ||||||
|  |     function GetScaledSize() { | ||||||
|  |         return BaseObject_GetScaledSize(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取锚点 | ||||||
|  |     function GetAnchor() { | ||||||
|  |         return BaseObject_GetAnchor(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取透明度 | ||||||
|  |     function GetOpacity() { | ||||||
|  |         return BaseObject_GetOpacity(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取显示透明度 | ||||||
|  |     function GetDisplayedOpacity() { | ||||||
|  |         return BaseObject_GetDisplayedOpacity(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取旋转角度 | ||||||
|  |     function GetRotation() { | ||||||
|  |         return BaseObject_GetRotation(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取缩放比例 | ||||||
|  |     function GetScale() { | ||||||
|  |         return BaseObject_GetScale(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取错切角度 | ||||||
|  |     function GetSkew() { | ||||||
|  |         return BaseObject_GetSkew(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取变换 | ||||||
|  |     function GetTransform() { | ||||||
|  |         return BaseObject_GetTransform(this.C_Object); | ||||||
|  |     } | ||||||
|  |     //获取父角色 | ||||||
|  |     function GetParent() { | ||||||
|  |         return Parent; | ||||||
|  |     } | ||||||
|  |     //获取所在舞台 | ||||||
|  |     function GetStage() { | ||||||
|  |         return BaseObject_GetStage(this.C_Object); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置角色是否可见 | ||||||
|  |     function SetVisible(Value) { | ||||||
|  |         BaseObject_SetVisible(this.C_Object, Value); | ||||||
|  |     } | ||||||
|  |     //设置坐标 | ||||||
|  |     function SetPosition(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_SetPosition(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_SetPosition(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //移动坐标 | ||||||
|  |     function MoveTo(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_MoveTo(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_MoveTo(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //移动相对坐标 | ||||||
|  |     function MoveBy(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_MoveBy(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_MoveBy(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //设置缩放比例 | ||||||
|  |     function SetScale(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_SetScale(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_SetScale(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //设置错切角度 | ||||||
|  |     function SetSkew(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_SetSkew(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_SetSkew(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //设置锚点位置 | ||||||
|  |     function SetAnchor(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_SetAnchor(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_SetAnchor(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //修改大小 | ||||||
|  |     function SetSize(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_SetSize(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_SetSize(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //设置旋转角度 | ||||||
|  |     function SetRotation(Value) { | ||||||
|  |         BaseObject_SetRotation(this.C_Object, Value); | ||||||
|  |     } | ||||||
|  |     //设置透明度 | ||||||
|  |     function SetOpacity(Value) { | ||||||
|  |         BaseObject_SetOpacity(this.C_Object, Value); | ||||||
|  |     } | ||||||
|  |     //启用或禁用级联透明度 | ||||||
|  |     function SetCascadeOpacityEnabled(Value) { | ||||||
|  |         BaseObject_SetCascadeOpacityEnabled(this.C_Object, Value); | ||||||
|  |     } | ||||||
|  |     //设置 Z 轴顺序 | ||||||
|  |     function SetZOrder(Value) { | ||||||
|  |         BaseObject_SetZOrder(this.C_Object, Value); | ||||||
|  |     } | ||||||
|  |     //判断点是否在角色内 | ||||||
|  |     function IsContainsPoint(Value) { | ||||||
|  |         if (vargv.len() == 0) | ||||||
|  |             BaseObject_IsContainsPoint(this.C_Object, Value); | ||||||
|  |         else if (vargv.len() == 1) | ||||||
|  |             BaseObject_IsContainsPoint(this.C_Object, Value, vargv[0]); | ||||||
|  |     } | ||||||
|  |     //设置渲染角色边界 | ||||||
|  |     function ShowBorder(Value) { | ||||||
|  |         BaseObject_ShowBorder(this.C_Object, Value); | ||||||
|  |     } | ||||||
|  |     //设置渲染角色边界 | ||||||
|  |     function SetRotate(Duration, Rotation) { | ||||||
|  |         BaseObject_SetRotate(this.C_Object, Duration, Rotation); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,29 @@ | ||||||
|  | /* | ||||||
|  | 文件名:Game_Window_Class.nut | ||||||
|  | 路径:BaseClass/Game_Window_Class.nut | ||||||
|  | 创建日期:2024-11-07	16:06 | ||||||
|  | 文件用途:游戏窗口类 | ||||||
|  | */ | ||||||
|  | class GameWindow { | ||||||
|  |     //窗口标题 | ||||||
|  |     title = "Yosin&Kiwano"; | ||||||
|  |     //背景色 | ||||||
|  |     bg_color = null; | ||||||
|  |     //窗口大小 | ||||||
|  |     size = null; | ||||||
|  |     //垂直同步 | ||||||
|  |     v_sync = true; | ||||||
|  |     //帧率 | ||||||
|  |     frame_interval = 144; | ||||||
|  |     //调试模式 | ||||||
|  |     debug_mode = false; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         bg_color = [255.0, 255.0, 255.0, 255.0]; | ||||||
|  |         size = [1280, 720]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Run(Func) { | ||||||
|  |         WindowRun(title, bg_color, size, v_sync, frame_interval, debug_mode, Func); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,320 @@ | ||||||
|  | /* | ||||||
|  | 文件名:InitAni.nut | ||||||
|  | 路径:Core/BaseClass/ScriptManager/InitAni.nut | ||||||
|  | 创建日期:2024-05-07	17:33 | ||||||
|  | 文件用途:初始化Ani | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | function Get_Ani_Flip_Type(data) { | ||||||
|  |     switch (data) { | ||||||
|  |         case 1: | ||||||
|  |             return "HORIZON"; | ||||||
|  |         case 2: | ||||||
|  |             return "VERTICAL"; | ||||||
|  |         case 3: | ||||||
|  |             return "ALL"; | ||||||
|  |         default: | ||||||
|  |             return ""; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | function Get_Ani_Effect_Type(data) { | ||||||
|  |     switch (data) { | ||||||
|  |         case 0: | ||||||
|  |             return "NONE"; | ||||||
|  |         case 1: | ||||||
|  |             return "DODGE"; | ||||||
|  |         case 2: | ||||||
|  |             return "LINEARDODGE"; | ||||||
|  |         case 3: | ||||||
|  |             return "DARK"; | ||||||
|  |         case 4: | ||||||
|  |             return "XOR"; | ||||||
|  |         case 5: | ||||||
|  |             return "MONOCHROME"; | ||||||
|  |         case 6: | ||||||
|  |             return "SPACEDISTORT"; | ||||||
|  |         default: | ||||||
|  |             return ""; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function Get_Ani_Damage_Type(data) { | ||||||
|  |     switch (data) { | ||||||
|  |         case 0: | ||||||
|  |             return "NORMAL"; | ||||||
|  |         case 1: | ||||||
|  |             return "SUPERARMOR"; | ||||||
|  |         case 2: | ||||||
|  |             return "UNBREAKABLE"; | ||||||
|  |         default: | ||||||
|  |             return ""; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function Get_Ani_Flag(data) { | ||||||
|  |     switch (data) { | ||||||
|  |         case 0: | ||||||
|  |             return "LOOP"; | ||||||
|  |         case 1: | ||||||
|  |             return "SHADOW"; | ||||||
|  |         case 3: | ||||||
|  |             return "COORD"; | ||||||
|  |         case 7: | ||||||
|  |             return "IMAGE_RATE"; | ||||||
|  |         case 8: | ||||||
|  |             return "IMAGE_ROTATE"; | ||||||
|  |         case 9: | ||||||
|  |             return "RGBA"; | ||||||
|  |         case 10: | ||||||
|  |             return "INTERPOLATION"; | ||||||
|  |         case 11: | ||||||
|  |             return "GRAPHIC_EFFECT"; | ||||||
|  |         case 12: | ||||||
|  |             return "DELAY"; | ||||||
|  |         case 13: | ||||||
|  |             return "DAMAGE_TYPE"; | ||||||
|  |         case 14: | ||||||
|  |             return "DAMAGE_BOX"; | ||||||
|  |         case 15: | ||||||
|  |             return "ATTACK_BOX"; | ||||||
|  |         case 16: | ||||||
|  |             return "PLAY_SOUND"; | ||||||
|  |         case 17: | ||||||
|  |             return "PRELOAD"; | ||||||
|  |         case 18: | ||||||
|  |             return "SPECTRUM"; | ||||||
|  |         case 23: | ||||||
|  |             return "SET_FLAG"; | ||||||
|  |         case 24: | ||||||
|  |             return "FLIP_TYPE"; | ||||||
|  |         case 25: | ||||||
|  |             return "LOOP_START"; | ||||||
|  |         case 26: | ||||||
|  |             return "LOOP_END"; | ||||||
|  |         case 27: | ||||||
|  |             return "CLIP"; | ||||||
|  |         case 28: | ||||||
|  |             return "OPERATION"; | ||||||
|  |         default: | ||||||
|  |             return ""; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function InitPvfAni(Ro) { | ||||||
|  |     local AniObject = { | ||||||
|  |         Img_List = [], | ||||||
|  |         Frame = [], | ||||||
|  |         Flag = {} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     local Frame_Max = Ro.GetUShort(); | ||||||
|  |     local Img_Count = Ro.GetUShort(); | ||||||
|  | 
 | ||||||
|  |     //Img的路径读取 存入数组 | ||||||
|  |     for (local index = 0; index< Img_Count; index++) { | ||||||
|  |         local Buf = Ro.GetInt(); | ||||||
|  |         local ImgPath = Ro.GetString(Buf); | ||||||
|  |         //有可能Img有空路径 | ||||||
|  |         AniObject.Img_List.append(ImgPath); | ||||||
|  |     } | ||||||
|  |     //Ani头部标签数量 | ||||||
|  |     local Ani_H_Item_Count = Ro.GetUShort(); | ||||||
|  | 
 | ||||||
|  |     //处理标签 | ||||||
|  |     for (local index = 0; index< Ani_H_Item_Count; index++) { | ||||||
|  |         //标签类型 | ||||||
|  |         local Type = Ro.GetUShort(); | ||||||
|  | 
 | ||||||
|  |         switch (Type) { | ||||||
|  |             case 0: | ||||||
|  |             case 1: { | ||||||
|  |                 local Key = Get_Ani_Flag(Type); | ||||||
|  |                 local Value = Ro.readn('c'); | ||||||
|  |                 AniObject.Flag.rawset(Key, Value); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case 3: | ||||||
|  |             case 28: { | ||||||
|  |                 local Key = Get_Ani_Flag(Type); | ||||||
|  |                 local Value = Ro.GetUShort(); | ||||||
|  |                 AniObject.Flag.rawset(Key, Value); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case 18: | ||||||
|  |                 // print("残影解析"); | ||||||
|  |                 //此处无解析 暂时先保证运行  残影功能暂时用不上 | ||||||
|  |                 Ro.readn('c'); | ||||||
|  |                 Ro.GetInt(); | ||||||
|  |                 Ro.GetInt(); | ||||||
|  |                 Ro.GetInt(); | ||||||
|  |                 Ro.Get256(); | ||||||
|  |                 Ro.Get256(); | ||||||
|  |                 Ro.Get256(); | ||||||
|  |                 Ro.Get256(); | ||||||
|  |                 Ro.GetUShort(); | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //读取每一个Img | ||||||
|  |     for (local index = 0; index< Frame_Max; index++) { | ||||||
|  |         //帧结构体对象 | ||||||
|  |         local FrameObject = { | ||||||
|  |             AttackBox = [], | ||||||
|  |             DamageBox = [], | ||||||
|  |             Flag = {}, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         //碰撞框项目数量 | ||||||
|  |         local Ani_Box_Item_Count = Ro.GetUShort(); | ||||||
|  |         for (local _i = 0; _i< Ani_Box_Item_Count; _i++) { | ||||||
|  |             local Box_Type = Ro.GetUShort(); | ||||||
|  |             local D_Box_b = []; | ||||||
|  |             for (local _k = 0; _k< 6; _k++) { | ||||||
|  |                 D_Box_b.append(Ro.readn('i')); | ||||||
|  |             } | ||||||
|  |             if (Box_Type == 15) { | ||||||
|  |                 FrameObject.AttackBox.append(D_Box_b); | ||||||
|  |             } else { | ||||||
|  |                 FrameObject.DamageBox.append(D_Box_b); | ||||||
|  |             } | ||||||
|  |             // //0是攻击框 1是受击框 | ||||||
|  |             // FrameObject.Box.rawset(15 - Box_Type, D_Box_b); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //调用的第几个Img | ||||||
|  |         local Index_Buf = Ro.GetShort(); | ||||||
|  |         //如果等于-1说明是img路径为空 | ||||||
|  |         if (Index_Buf != 65535) { | ||||||
|  |             FrameObject.Img_Path <- AniObject.Img_List[Index_Buf].tolower(); | ||||||
|  |             //Img中的PNG下标 | ||||||
|  |             FrameObject.Img_Index <- Ro.GetUShort(); | ||||||
|  |         } else { | ||||||
|  |             FrameObject.Img_Path <- ""; | ||||||
|  |             FrameObject.Img_Index <- 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //坐标 | ||||||
|  |         FrameObject.Pos <- { | ||||||
|  |             x = Ro.readn('i'), | ||||||
|  |             y = Ro.readn('i'), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         //Img中的项目数量 | ||||||
|  |         local Img_Flag_Count = Ro.GetUShort(); | ||||||
|  |         for (local _o = 0; _o< Img_Flag_Count; _o++) { | ||||||
|  |             local Img_Flag_Type = Ro.GetUShort(); | ||||||
|  |             local Key; | ||||||
|  |             local Value; | ||||||
|  |             switch (Img_Flag_Type) { | ||||||
|  |                 case 0: | ||||||
|  |                 case 1: | ||||||
|  |                 case 10: | ||||||
|  |                     Key = Get_Ani_Flag(Img_Flag_Type); | ||||||
|  |                     Value = Ro.readn('c'); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 3: | ||||||
|  |                     Key = "COORD"; | ||||||
|  |                     Value = Ro.GetUShort(); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 17: | ||||||
|  |                     Key = "PRELOAD"; | ||||||
|  |                     Value = 1; | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 7: | ||||||
|  |                     Key = "IMAGE_RATE"; | ||||||
|  |                     Value = { | ||||||
|  |                         x = Ro.GetFloat(), | ||||||
|  |                         y = Ro.GetFloat() | ||||||
|  |                     }; | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 8: | ||||||
|  |                     Key = "IMAGE_ROTATE"; | ||||||
|  |                     Value = Ro.GetFloat(); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 9: | ||||||
|  |                     Key = "RGBA"; | ||||||
|  |                     Value = [ | ||||||
|  |                         Ro.Get256(), | ||||||
|  |                         Ro.Get256(), | ||||||
|  |                         Ro.Get256(), | ||||||
|  |                         Ro.Get256(), | ||||||
|  |                     ]; | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 11: | ||||||
|  |                     local Effect_Type = Ro.GetUShort(); | ||||||
|  |                     Key = "GRAPHIC_EFFECT_" + Get_Ani_Effect_Type(Effect_Type); | ||||||
|  |                     switch (Effect_Type) { | ||||||
|  |                         case 5: | ||||||
|  |                             Value = [Ro.Get256(), Ro.Get256(), Ro.Get256()]; | ||||||
|  |                             break; | ||||||
|  |                         case 6: | ||||||
|  |                             Value = [Ro.GetShort(), Ro.GetShort()]; | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 12: | ||||||
|  |                     Value = Ro.GetInt(); | ||||||
|  |                     FrameObject.Delay <- Value; | ||||||
|  |                     break; | ||||||
|  |                 case 13: | ||||||
|  |                     Key = "DAMAGE_TYPE"; | ||||||
|  |                     Value = Get_Ani_Damage_Type(Ro.GetUShort()); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 16: | ||||||
|  |                     local SoundTempSize = Ro.GetInt(); | ||||||
|  |                     Key = "PLAY_SOUND"; | ||||||
|  |                     Value = Ro.GetString(SoundTempSize); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 23: | ||||||
|  |                     Key = "SET_FLAG"; | ||||||
|  |                     Value = Ro.GetInt(); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 24: | ||||||
|  |                     Key = "FLIP_TYPE"; | ||||||
|  |                     Value = Get_Ani_Flip_Type(Ro.GetUShort()); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 25: | ||||||
|  |                     Key = "LOOP_START"; | ||||||
|  |                     FrameObject.Flag.rawset(Key, 1); | ||||||
|  |                     break; | ||||||
|  |                 case 26: | ||||||
|  |                     Key = "LOOP_END"; | ||||||
|  |                     Value = Ro.GetInt(); | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 case 27: | ||||||
|  |                     Key = "CLIP"; | ||||||
|  |                     Value = [ | ||||||
|  |                         Ro.GetShort(), | ||||||
|  |                         Ro.GetShort(), | ||||||
|  |                         Ro.GetShort(), | ||||||
|  |                         Ro.GetShort(), | ||||||
|  |                     ]; | ||||||
|  |                     FrameObject.Flag.rawset(Key, Value); | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //每一帧都是一个结构体 存入数组中 | ||||||
|  |         AniObject.Frame.append(FrameObject); | ||||||
|  |     } | ||||||
|  |     return AniObject; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,207 @@ | ||||||
|  | /* | ||||||
|  | 文件名:ScriptManager.nut | ||||||
|  | 路径:Core/BaseClass/ScriptManager/ScriptManager.nut | ||||||
|  | 创建日期:2024-10-11	12:24 | ||||||
|  | 文件用途:pvf 管理器 | ||||||
|  | */ | ||||||
|  | class Script { | ||||||
|  | 
 | ||||||
|  |     C_Object = null; | ||||||
|  | 
 | ||||||
|  |     constructor(Path = "Script.pvf") { | ||||||
|  |         print("正在初始化PVF..."); | ||||||
|  |         local StartTime = time(); | ||||||
|  | 
 | ||||||
|  |         C_Object = Asset_LoadScript(Path); | ||||||
|  | 
 | ||||||
|  |         print("PVF初始化完毕!!!"); | ||||||
|  |         print("用时: " + (time() - StartTime) + "秒"); | ||||||
|  |         getroottable()._Script_Data_ <- this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function GetFileInfo(Path) { | ||||||
|  |         local size = Asset_GetPvfFileSize(C_Object, Path); | ||||||
|  |         if (size) { | ||||||
|  |             local blobobj = blobex(size); | ||||||
|  |             Asset_GetPvfFile(C_Object, Path, blobobj); | ||||||
|  |             return blobobj; | ||||||
|  |         } else return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetBinString(Key) { | ||||||
|  |         return Asset_GetPvfBinString(C_Object, Key); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetLoadString(Key) { | ||||||
|  |         return Asset_GetPvfLoadString(C_Object, Key); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class _PVF_Data_ { | ||||||
|  |     //数据 | ||||||
|  |     Data = null; | ||||||
|  |     //位置 | ||||||
|  |     Pos = 0; | ||||||
|  |     //最大值 | ||||||
|  |     Max = 0; | ||||||
|  | 
 | ||||||
|  |     function _typeof() { | ||||||
|  |         return "pvf_data"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     constructor(gData) { | ||||||
|  |         Data = gData; | ||||||
|  |         Max = gData.len(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Last() { | ||||||
|  |         if (Pos > 0) { | ||||||
|  |             Pos--; | ||||||
|  |             return Get(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Seek(i) { | ||||||
|  |         if (Pos > 0 && Pos<(Max - 1)) { | ||||||
|  |             Pos = i; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Get() { | ||||||
|  |         local Ret = Data[Pos]; | ||||||
|  |         if (Pos<(Max - 1)) { | ||||||
|  |             Pos++; | ||||||
|  |         } | ||||||
|  |         return Ret; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Eof() { | ||||||
|  |         if (Pos == Max - 1) | ||||||
|  |             return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Next() { | ||||||
|  |         if (Pos<(Max - 1)) { | ||||||
|  |             Pos++; | ||||||
|  |             return Get(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class GlobaData { | ||||||
|  |     //动画文件Map | ||||||
|  |     Ani = null; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         Ani = {}; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获取文件的IO | ||||||
|  |     function GetFile(Path) { | ||||||
|  |         return getroottable()._Script_Data_.GetFileInfo(Path); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获取文件并处理 | ||||||
|  |     function GetFileData(Path, Func) { | ||||||
|  |         local IO = GetFile(Path); | ||||||
|  |         if (IO) { | ||||||
|  |             return ResolvingData(IO, Func, Path); | ||||||
|  |         } else { | ||||||
|  |             print(Path + "找不到文件!"); | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获取动画文件 | ||||||
|  |     function GetAni(Path) { | ||||||
|  |         if (Path in Ani) | ||||||
|  |             return Ani[Path]; | ||||||
|  |         else { | ||||||
|  |             local IO = GetFile(Path); | ||||||
|  |             if (IO) { | ||||||
|  |                 Ani[Path] <- InitPvfAni(IO); | ||||||
|  |                 return Ani[Path]; | ||||||
|  |             } else { | ||||||
|  |                 print(Path + "找不到文件!"); | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function ResolvingData(IO, Func, Path) { | ||||||
|  |         local DataTable = {}; | ||||||
|  |         DataTable.filepath <- Path; | ||||||
|  |         local DataArr = []; | ||||||
|  |         local Length = IO.len(); | ||||||
|  |         if (Length >= 7) { | ||||||
|  |             local i = 2; | ||||||
|  |             while (true) { | ||||||
|  |                 if (i< Length && Length - i >= 5) { | ||||||
|  |                     local str = UnpackData(IO, i); | ||||||
|  |                     i += 5; | ||||||
|  |                     DataArr.push(str); | ||||||
|  |                 } else break; | ||||||
|  |             } | ||||||
|  |             Func(DataTable, _PVF_Data_(DataArr)); | ||||||
|  |             return DataTable; | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function UnpackData(IO, i) { | ||||||
|  |         local out = ""; | ||||||
|  |         IO.seek(i); //内容指示位 | ||||||
|  |         local currentByte = IO.readn('c'); //内容指示位 | ||||||
|  |         local after = IO.GetInt(); | ||||||
|  |         switch (currentByte) { | ||||||
|  |             case 10: { | ||||||
|  |                 IO.seek(i - 4); | ||||||
|  |                 local Before = IO.GetInt(); | ||||||
|  |                 local Buf = getroottable()._Script_Data_.GetBinString(after); | ||||||
|  |                 if (!Buf) { | ||||||
|  |                     Buf = ""; | ||||||
|  |                 } else { | ||||||
|  |                     Buf = "<" + Before + "::" + Buf + "`" + getroottable()._Script_Data_.GetLoadString(Buf) + "`>"; | ||||||
|  |                 } | ||||||
|  |                 Buf = Buf + "\r\n"; | ||||||
|  |                 out += Buf; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case 2: { | ||||||
|  |                 IO.seek(-4, 'c'); | ||||||
|  |                 local ret = IO.readn('i'); | ||||||
|  |                 return ret; | ||||||
|  |             } | ||||||
|  |             case 4: { | ||||||
|  |                 local Bbuf = blob(4); | ||||||
|  |                 Bbuf.writen(after, 'i'); | ||||||
|  |                 Bbuf.seek(0); | ||||||
|  |                 local Buf = Bbuf.readn('f'); | ||||||
|  |                 out += after + '\t'; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case 6: | ||||||
|  |             case 8: | ||||||
|  |             case 7: | ||||||
|  |             case 5: { | ||||||
|  |                 local Buf = getroottable()._Script_Data_.GetBinString(after); | ||||||
|  |                 if (!Buf) Buf = ""; | ||||||
|  |                 return Buf; | ||||||
|  |             } | ||||||
|  |             default: | ||||||
|  |                 out += ""; | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return out; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | getroottable().ScriptData <- GlobaData(); | ||||||
|  | @ -0,0 +1,59 @@ | ||||||
|  | /* | ||||||
|  | 文件名:SpriteClass.nut | ||||||
|  | 路径:BaseClass/SpriteObject/SpriteClass.nut | ||||||
|  | 创建日期:2024-05-05	09:35 | ||||||
|  | 文件用途:精灵类 | ||||||
|  | */ | ||||||
|  | class CL_SpriteObject extends CL_BaseObject { | ||||||
|  | 
 | ||||||
|  |     SpriteFrame = null; | ||||||
|  | 
 | ||||||
|  |     constructor(...) { | ||||||
|  |         local C_Object; | ||||||
|  |         //创建空精灵 | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             C_Object = Sprite_Create(); | ||||||
|  |             base.constructor(C_Object); | ||||||
|  |         } | ||||||
|  |         //通过精灵指针创建 | ||||||
|  |         else if (vargv.len() == 1) { | ||||||
|  |             C_Object = vargv[0]; | ||||||
|  |             base.constructor(C_Object, true); | ||||||
|  |         } | ||||||
|  |         //通过路径创建 | ||||||
|  |         else if (vargv.len() == 2) { | ||||||
|  |             C_Object = Sprite_Create(); | ||||||
|  |             base.constructor(C_Object); | ||||||
|  |             local Path = vargv[0]; | ||||||
|  |             local Idx = vargv[1]; | ||||||
|  |             local Sf = CL_SpriteFrameObject(Path, Idx); | ||||||
|  |             SetFrame(Sf); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置精灵帧 | ||||||
|  |     function SetFrame(SpriteFrame) { | ||||||
|  |         this.SpriteFrame = SpriteFrame; | ||||||
|  |         Sprite_SetFrame(this.C_Object, SpriteFrame.C_Object); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置混合模式 | ||||||
|  |     function SetMode(Mode) { | ||||||
|  |         Sprite_SetMode(this.C_Object, Mode); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置裁切 | ||||||
|  |     function SetCropRect(Parameter1, Parameter2, ...) { | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             local Point1 = Parameter1; | ||||||
|  |             local Point2 = Parameter2; | ||||||
|  |             Sprite_SetCropRect(this.C_Object, Point1, Point2); | ||||||
|  |         } else if (vargv.len() == 2) { | ||||||
|  |             local X1 = Parameter1; | ||||||
|  |             local Y1 = Parameter2; | ||||||
|  |             local X2 = vargv[0]; | ||||||
|  |             local Y2 = vargv[1]; | ||||||
|  |             Sprite_SetCropRect(this.C_Object, X1, Y1, X2, Y2); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | /* | ||||||
|  | 文件名:SpriteFrameClass.nut | ||||||
|  | 路径:BaseClass/SpriteObject/SpriteFrameClass.nut | ||||||
|  | 创建日期:2024-05-05	09:36 | ||||||
|  | 文件用途:精灵帧类 | ||||||
|  | */ | ||||||
|  | class CL_SpriteFrameObject extends CL_BaseObject { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     constructor(...) { | ||||||
|  |         if (vargv.len() == 2) { | ||||||
|  |             local Path = vargv[0]; | ||||||
|  |             local Index = vargv[1]; | ||||||
|  |             C_Object = SpriteFrame_Create(Path, Index); | ||||||
|  |         } else { | ||||||
|  |             C_Object = vargv[0]; | ||||||
|  |         } | ||||||
|  |         // base.constructor(C_Object); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,42 @@ | ||||||
|  | /* | ||||||
|  | 文件名:StageClass.nut | ||||||
|  | 路径:BaseClass/StageClass/StageClass.nut | ||||||
|  | 创建日期:2024-05-05	00:22 | ||||||
|  | 文件用途:舞台类 | ||||||
|  | */ | ||||||
|  | class CL_StageObject extends CL_BaseObject { | ||||||
|  | 
 | ||||||
|  |     constructor(...) { | ||||||
|  |         local C_Object; | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             C_Object = Stage_Create(); | ||||||
|  |             base.constructor(C_Object); | ||||||
|  |         } else { | ||||||
|  |             C_Object = vargv[0]; | ||||||
|  |             base.constructor(C_Object, true); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //绑定Update | ||||||
|  |     function BindenvUpdate() { | ||||||
|  |         Stage_BindenvUpdate(C_Object, this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Enter(...) { | ||||||
|  |         if (vargv.len() == 1) vargv[0](this); | ||||||
|  |         Director_EnterStage(this.C_Object); | ||||||
|  |         //如果进入场景要绑定Update | ||||||
|  |         BindenvUpdate(); | ||||||
|  | 
 | ||||||
|  |         //并且绑定摄像机 先移除父对象在绑定 | ||||||
|  |         // if (CameraObject.ParentId) CameraObject.RemoveSelf(); | ||||||
|  |         // Addchild(CameraObject); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnUpdate(Dt) { | ||||||
|  |         base.OnUpdate(Dt); | ||||||
|  |         //调用音效管理器逻辑 | ||||||
|  |         _Yosin_Sound_Logic_(Dt, this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,54 @@ | ||||||
|  | /* | ||||||
|  | 文件名:Font.nut | ||||||
|  | 路径:Core/BaseClass/TextObject/Font.nut | ||||||
|  | 创建日期:2024-12-01	19:54 | ||||||
|  | 文件用途:字体对象 | ||||||
|  | */ | ||||||
|  | __Font__Map__ <- {}; | ||||||
|  | class Font extends CL_BaseObject { | ||||||
|  | 
 | ||||||
|  |     function _typeof() { | ||||||
|  |         return "font_data"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 构造函数 | ||||||
|  |      * @参数 不传参默认使用系统默认字体 | ||||||
|  |      * @参数 1: 字体名称 | ||||||
|  |      * @参数 2: 字体大小 | ||||||
|  |      * @参数 3: 字体粗细    (可选) | ||||||
|  |      * @参数 4: 字体倾斜    (可选) | ||||||
|  |      * @参数 5: 字体拉伸    (可选) | ||||||
|  |      * @返回值 | ||||||
|  |      */ | ||||||
|  |     constructor(...) { | ||||||
|  |         local vargc = vargv.len(); | ||||||
|  |         //通过参数构造字体 | ||||||
|  |         if (vargc > 0) { | ||||||
|  |             local family_name = vargv[0]; | ||||||
|  |             local size = vargv[1]; | ||||||
|  |             local weight = FontWeight.Normal; | ||||||
|  |             if (vargc >= 3) weight = vargv[2]; | ||||||
|  |             local posture = FontPosture.Normal; | ||||||
|  |             if (vargc >= 4) posture = vargv[3]; | ||||||
|  |             local stretch = FontStretch.Normal; | ||||||
|  |             if (vargc >= 5) stretch = vargv[4]; | ||||||
|  |             C_Object = Font_CreateFont(family_name, size, weight, posture, stretch); | ||||||
|  |         } | ||||||
|  |         //初始化系统默认字体 | ||||||
|  |         else { | ||||||
|  |             C_Object = Font_CreateFont(); | ||||||
|  |         } | ||||||
|  |         base.constructor(C_Object); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function PreLoad(name) { | ||||||
|  |         Font_PreloadFont(name); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //注册到全局表 | ||||||
|  |     function Register(Id) { | ||||||
|  |         __Font__Map__[Id] <- this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,46 @@ | ||||||
|  | /* | ||||||
|  | 文件名:TextActor.nut | ||||||
|  | 路径:Core/BaseClass/TextObject/TextActor.nut | ||||||
|  | 创建日期:2024-12-01	19:51 | ||||||
|  | 文件用途:文本样式 | ||||||
|  | */ | ||||||
|  | class TextActor extends CL_BaseObject { | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 构造文本精灵 | ||||||
|  |      * @参数 font 可传入全局font Id 或 传入 font对象 | ||||||
|  |      * @参数 textstyle Map 可选对象: | ||||||
|  |         alignment 对其方式 | ||||||
|  |         wrap_width 自动换行宽度 | ||||||
|  |         line_spacing 行间距 | ||||||
|  |         show_underline 显示下划线 | ||||||
|  |         show_strikethrough 	显示删除线 | ||||||
|  |         color 颜色 | ||||||
|  |      * @返回值 | ||||||
|  |     */ | ||||||
|  |     constructor(font, textstyle = {}) { | ||||||
|  |         switch (typeof font) { | ||||||
|  |             case "integer": | ||||||
|  |                 C_Object = TextActor_Create(__Font__Map__[font].C_Object, textstyle); | ||||||
|  |                 break; | ||||||
|  |             case "font_data": | ||||||
|  |                 C_Object = TextActor_Create(font.C_Object, textstyle); | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 C_Object = TextActor_Create(Font().C_Object, textstyle); | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |         //传递字体类 | ||||||
|  |         base.constructor(C_Object); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置文本内容 | ||||||
|  |     function SetText(str) { | ||||||
|  |         TextActor_SetText(this.C_Object, str); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置描边 | ||||||
|  |     function SetOutline(width, color = Color.Black, cap = CapStyle.Square, line_join = LineJoinStyle.Round, dash = DashStyle.Solid) { | ||||||
|  |         TextActor_SetOutLine(this.C_Object, width, color, cap, line_join, dash); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,68 @@ | ||||||
|  | /* | ||||||
|  | 文件名:UserStorage.nut | ||||||
|  | 路径:Core/BaseClass/UserStorage.nut | ||||||
|  | 创建日期:2024-11-14	08:43 | ||||||
|  | 文件用途:用户存档类 | ||||||
|  | */ | ||||||
|  | class Storage { | ||||||
|  | 
 | ||||||
|  |     Data = null; | ||||||
|  | 
 | ||||||
|  |     // 构造函数 | ||||||
|  |     constructor() { | ||||||
|  |         Data = {}; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //储存数据 | ||||||
|  |     function SetItem(Key, Value) { | ||||||
|  |         Data.rawset(Key, Value); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //储存数据列表 | ||||||
|  |     function SetItemList(T) { | ||||||
|  |         foreach(Key, Value in T) { | ||||||
|  |             Data.rawset(Key, Value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获取数据 | ||||||
|  |     function GetItem(Key) { | ||||||
|  |         if (Data.rawin(Key)) return Data.rawget(Key); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获取数据列表 | ||||||
|  |     function GetItemList(KeyList) { | ||||||
|  |         local T = {}; | ||||||
|  |         foreach(Key in KeyList) { | ||||||
|  |             local Buf = GetItem(Key); | ||||||
|  |             T.Key <- Buf; | ||||||
|  |         } | ||||||
|  |         return T; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Load(Path) { | ||||||
|  |         try { | ||||||
|  |             local FileObj = file(Path, "r"); | ||||||
|  |             local IO = blobex(FileObj.readblob(FileObj.len())); | ||||||
|  |             local SaveStr = IO.GetString(IO.len()); | ||||||
|  |             Data = Json.Decode(SaveStr); | ||||||
|  |             FileObj.close(); | ||||||
|  |             return true; | ||||||
|  |         } catch (exception) { | ||||||
|  |             print("未读取到存档文件"); | ||||||
|  |             print(exception); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Save(Path) { | ||||||
|  |         local SaveStr = Json.Encode(Data); | ||||||
|  |         local FileObj = file(Path, "w"); | ||||||
|  |         foreach(char in SaveStr) { | ||||||
|  |             FileObj.writen(char, 'b'); | ||||||
|  |         } | ||||||
|  |         FileObj.flush(); | ||||||
|  |         FileObj.close(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,38 @@ | ||||||
|  | /* | ||||||
|  |  * @函数作用: 输出函数 | ||||||
|  |  * @参数 any | ||||||
|  |  */ | ||||||
|  | function print(Object) { | ||||||
|  |     switch (typeof Object) { | ||||||
|  |         case "table": | ||||||
|  |         case "array": { | ||||||
|  |             local str = Json.Encode(Object); | ||||||
|  |             OutPutTable(str); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case "string": | ||||||
|  |         case "integer": { | ||||||
|  |             output(Object); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         default: | ||||||
|  |             output(Object); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * @函数作用: 深拷贝Table | ||||||
|  |  */ | ||||||
|  | function sq_DeepCopy(original) { | ||||||
|  |     local Ret = Json.Encode(original); | ||||||
|  |     Ret = Json.Decode(Ret); | ||||||
|  |     return Ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * @函数作用: 返回颜色的十六进制数 | ||||||
|  |  */ | ||||||
|  | function sq_RGBA(R, G, B, A) { | ||||||
|  |     return (A << 24) + (R << 16) + (G << 8) + B; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,67 @@ | ||||||
|  | /* | ||||||
|  | 文件名:BlobExClass.nut | ||||||
|  | 路径:BaseClass/BaseTool/BlobExClass.nut | ||||||
|  | 创建日期:2024-05-07	17:34 | ||||||
|  | 文件用途:拓展的Blob类 | ||||||
|  | */ | ||||||
|  | class blobex extends blob { | ||||||
|  | 
 | ||||||
|  |     //-----------------Metamethods--------------------// | ||||||
|  |     function _typeof() { | ||||||
|  |         return "blobex"; | ||||||
|  |     } | ||||||
|  |     //-----------------Metamethods--------------------// | ||||||
|  | 
 | ||||||
|  |     constructor(arg) { | ||||||
|  |         //通过blob构造 | ||||||
|  |         if (typeof arg == "blob") { | ||||||
|  |             base.constructor(arg.len()); | ||||||
|  |             writeblob(arg); | ||||||
|  |         } | ||||||
|  |         //直接构造 | ||||||
|  |         else { | ||||||
|  |             base.constructor(arg); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function writeblob(B) { | ||||||
|  |         base.writeblob(B); | ||||||
|  |         seek(0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetUShort() { | ||||||
|  |         return readn('w'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetShort() { | ||||||
|  |         return readn('s'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function charPtrToInt(arr) { | ||||||
|  |         local value = ((arr[0]) << 0) | | ||||||
|  |             ((arr[1]) << 8) | | ||||||
|  |             ((arr[2]) << 16) | | ||||||
|  |             ((arr[3]) << 24); | ||||||
|  |         return value; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetInt() { | ||||||
|  |         local CurTPos = tell(); | ||||||
|  |         local Ret = charPtrToInt([this[CurTPos], this[CurTPos + 1], this[CurTPos + 2], this[CurTPos + 3]]); | ||||||
|  |         seek(4, 'c'); | ||||||
|  |         return Ret; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Get256() { | ||||||
|  |         local Buf = readn('c'); | ||||||
|  |         return (256.0 + Buf.tofloat()) % 256.0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetFloat() { | ||||||
|  |         return readn('f'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetString(count) { | ||||||
|  |         return stream_myreadstring(count); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,13 @@ | ||||||
|  | //Json类 | ||||||
|  | class Json { | ||||||
|  |     //Table 转 String | ||||||
|  |     function Encode(Table) { | ||||||
|  |         return JSONEncoder.encode(Table); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //String 转 Table | ||||||
|  |     function Decode(Str) { | ||||||
|  | 
 | ||||||
|  |         return JSONParser.parse(Str); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,702 @@ | ||||||
|  | /** | ||||||
|  |  * JSON Parser | ||||||
|  |  * | ||||||
|  |  * @author Mikhail Yurasov <mikhail@electricimp.com> | ||||||
|  |  * @package JSONParser | ||||||
|  |  * @version 1.0.1 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * JSON Parser | ||||||
|  |  * @package JSONParser | ||||||
|  |  */ | ||||||
|  | class JSONParser { | ||||||
|  | 
 | ||||||
|  |     // should be the same for all components within JSONParser package | ||||||
|  |     static version = "1.0.1"; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Parse JSON string into data structure | ||||||
|  |      * | ||||||
|  |      * @param {string} str | ||||||
|  |      * @param {function({string} value[, "number"|"string"])|null} converter | ||||||
|  |      * @return {*} | ||||||
|  |      */ | ||||||
|  |     function parse(str, converter = null) { | ||||||
|  | 
 | ||||||
|  |         local state; | ||||||
|  |         local stack = [] | ||||||
|  |         local container; | ||||||
|  |         local key; | ||||||
|  |         local value; | ||||||
|  | 
 | ||||||
|  |         // actions for string tokens | ||||||
|  |         local string = { | ||||||
|  |             go = function() { | ||||||
|  |                 state = "ok"; | ||||||
|  |             }, | ||||||
|  |             firstokey = function() { | ||||||
|  |                 key = value; | ||||||
|  |                 state = "colon"; | ||||||
|  |             }, | ||||||
|  |             okey = function() { | ||||||
|  |                 key = value; | ||||||
|  |                 state = "colon"; | ||||||
|  |             }, | ||||||
|  |             ovalue = function() { | ||||||
|  |                 value = this._convert(value, "string", converter); | ||||||
|  |                 state = "ocomma"; | ||||||
|  |             }.bindenv(this), | ||||||
|  |             firstavalue = function() { | ||||||
|  |                 value = this._convert(value, "string", converter); | ||||||
|  |                 state = "acomma"; | ||||||
|  |             }.bindenv(this), | ||||||
|  |             avalue = function() { | ||||||
|  |                 value = this._convert(value, "string", converter); | ||||||
|  |                 state = "acomma"; | ||||||
|  |             }.bindenv(this) | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         // the actions for number tokens | ||||||
|  |         local number = { | ||||||
|  |             go = function() { | ||||||
|  |                 state = "ok"; | ||||||
|  |             }, | ||||||
|  |             ovalue = function() { | ||||||
|  |                 value = this._convert(value, "number", converter); | ||||||
|  |                 state = "ocomma"; | ||||||
|  |             }.bindenv(this), | ||||||
|  |             firstavalue = function() { | ||||||
|  |                 value = this._convert(value, "number", converter); | ||||||
|  |                 state = "acomma"; | ||||||
|  |             }.bindenv(this), | ||||||
|  |             avalue = function() { | ||||||
|  |                 value = this._convert(value, "number", converter); | ||||||
|  |                 state = "acomma"; | ||||||
|  |             }.bindenv(this) | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         // action table | ||||||
|  |         // describes where the state machine will go from each given state | ||||||
|  |         local action = { | ||||||
|  | 
 | ||||||
|  |             "{": { | ||||||
|  |                 go = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         state = "ok" | ||||||
|  |                     }); | ||||||
|  |                     container = {}; | ||||||
|  |                     state = "firstokey"; | ||||||
|  |                 }, | ||||||
|  |                 ovalue = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         container = container, | ||||||
|  |                         state = "ocomma", | ||||||
|  |                         key = key | ||||||
|  |                     }); | ||||||
|  |                     container = {}; | ||||||
|  |                     state = "firstokey"; | ||||||
|  |                 }, | ||||||
|  |                 firstavalue = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         container = container, | ||||||
|  |                         state = "acomma" | ||||||
|  |                     }); | ||||||
|  |                     container = {}; | ||||||
|  |                     state = "firstokey"; | ||||||
|  |                 }, | ||||||
|  |                 avalue = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         container = container, | ||||||
|  |                         state = "acomma" | ||||||
|  |                     }); | ||||||
|  |                     container = {}; | ||||||
|  |                     state = "firstokey"; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             "}": { | ||||||
|  |                 firstokey = function() { | ||||||
|  |                     local pop = stack.pop(); | ||||||
|  |                     value = container; | ||||||
|  |                     container = ("container" in pop) ? pop.container : null; | ||||||
|  |                     key = ("key" in pop) ? pop.key : null; | ||||||
|  |                     state = pop.state; | ||||||
|  |                 }, | ||||||
|  |                 ocomma = function() { | ||||||
|  |                     local pop = stack.pop(); | ||||||
|  |                     container[key] <- value; | ||||||
|  |                     value = container; | ||||||
|  |                     container = ("container" in pop) ? pop.container : null; | ||||||
|  |                     key = ("key" in pop) ? pop.key : null; | ||||||
|  |                     state = pop.state; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             "[": { | ||||||
|  |                 go = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         state = "ok" | ||||||
|  |                     }); | ||||||
|  |                     container = []; | ||||||
|  |                     state = "firstavalue"; | ||||||
|  |                 }, | ||||||
|  |                 ovalue = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         container = container, | ||||||
|  |                         state = "ocomma", | ||||||
|  |                         key = key | ||||||
|  |                     }); | ||||||
|  |                     container = []; | ||||||
|  |                     state = "firstavalue"; | ||||||
|  |                 }, | ||||||
|  |                 firstavalue = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         container = container, | ||||||
|  |                         state = "acomma" | ||||||
|  |                     }); | ||||||
|  |                     container = []; | ||||||
|  |                     state = "firstavalue"; | ||||||
|  |                 }, | ||||||
|  |                 avalue = function() { | ||||||
|  |                     stack.push({ | ||||||
|  |                         container = container, | ||||||
|  |                         state = "acomma" | ||||||
|  |                     }); | ||||||
|  |                     container = []; | ||||||
|  |                     state = "firstavalue"; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             "]": { | ||||||
|  |                 firstavalue = function() { | ||||||
|  |                     local pop = stack.pop(); | ||||||
|  |                     value = container; | ||||||
|  |                     container = ("container" in pop) ? pop.container : null; | ||||||
|  |                     key = ("key" in pop) ? pop.key : null; | ||||||
|  |                     state = pop.state; | ||||||
|  |                 }, | ||||||
|  |                 acomma = function() { | ||||||
|  |                     local pop = stack.pop(); | ||||||
|  |                     container.push(value); | ||||||
|  |                     value = container; | ||||||
|  |                     container = ("container" in pop) ? pop.container : null; | ||||||
|  |                     key = ("key" in pop) ? pop.key : null; | ||||||
|  |                     state = pop.state; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             ":": { | ||||||
|  |                 colon = function() { | ||||||
|  |                     // Check if the key already exists | ||||||
|  |                     // NOTE previous code used 'if (key in container)...' | ||||||
|  |                     //      but this finds table ('container') member methods too | ||||||
|  |                     local err = false; | ||||||
|  |                     foreach(akey, avalue in container) { | ||||||
|  |                         if (akey == key) err = true; | ||||||
|  |                         break | ||||||
|  |                     } | ||||||
|  |                     if (err) throw "Duplicate key \"" + key + "\""; | ||||||
|  |                     state = "ovalue"; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             ",": { | ||||||
|  |                 ocomma = function() { | ||||||
|  |                     container[key] <- value; | ||||||
|  |                     state = "okey"; | ||||||
|  |                 }, | ||||||
|  |                 acomma = function() { | ||||||
|  |                     container.push(value); | ||||||
|  |                     state = "avalue"; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             "true": { | ||||||
|  |                 go = function() { | ||||||
|  |                     value = true; | ||||||
|  |                     state = "ok"; | ||||||
|  |                 }, | ||||||
|  |                 ovalue = function() { | ||||||
|  |                     value = true; | ||||||
|  |                     state = "ocomma"; | ||||||
|  |                 }, | ||||||
|  |                 firstavalue = function() { | ||||||
|  |                     value = true; | ||||||
|  |                     state = "acomma"; | ||||||
|  |                 }, | ||||||
|  |                 avalue = function() { | ||||||
|  |                     value = true; | ||||||
|  |                     state = "acomma"; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             "false": { | ||||||
|  |                 go = function() { | ||||||
|  |                     value = false; | ||||||
|  |                     state = "ok"; | ||||||
|  |                 }, | ||||||
|  |                 ovalue = function() { | ||||||
|  |                     value = false; | ||||||
|  |                     state = "ocomma"; | ||||||
|  |                 }, | ||||||
|  |                 firstavalue = function() { | ||||||
|  |                     value = false; | ||||||
|  |                     state = "acomma"; | ||||||
|  |                 }, | ||||||
|  |                 avalue = function() { | ||||||
|  |                     value = false; | ||||||
|  |                     state = "acomma"; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  | 
 | ||||||
|  |             "null": { | ||||||
|  |                 go = function() { | ||||||
|  |                     value = null; | ||||||
|  |                     state = "ok"; | ||||||
|  |                 }, | ||||||
|  |                 ovalue = function() { | ||||||
|  |                     value = null; | ||||||
|  |                     state = "ocomma"; | ||||||
|  |                 }, | ||||||
|  |                 firstavalue = function() { | ||||||
|  |                     value = null; | ||||||
|  |                     state = "acomma"; | ||||||
|  |                 }, | ||||||
|  |                 avalue = function() { | ||||||
|  |                     value = null; | ||||||
|  |                     state = "acomma"; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         // | ||||||
|  | 
 | ||||||
|  |         state = "go"; | ||||||
|  |         stack = []; | ||||||
|  | 
 | ||||||
|  |         // current tokenizeing position | ||||||
|  |         local start = 0; | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             local | ||||||
|  |             result, | ||||||
|  |             token, | ||||||
|  |             tokenizer = _JSONTokenizer(); | ||||||
|  | 
 | ||||||
|  |             while (token = tokenizer.nextToken(str, start)) { | ||||||
|  | 
 | ||||||
|  |                 if ("ptfn" == token.type) { | ||||||
|  |                     // punctuation/true/false/null | ||||||
|  |                     action[token.value][state](); | ||||||
|  |                 } else if ("number" == token.type) { | ||||||
|  |                     // number | ||||||
|  |                     value = token.value; | ||||||
|  |                     number[state](); | ||||||
|  |                 } else if ("string" == token.type) { | ||||||
|  |                     // string | ||||||
|  |                     value = tokenizer.unescape(token.value); | ||||||
|  |                     string[state](); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 start += token.length; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } catch (e) { | ||||||
|  |             state = e; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // check is the final state is not ok | ||||||
|  |         // or if there is somethign left in the str | ||||||
|  |         if (state != "ok" || regexp("[^\\s]").capture(str, start)) { | ||||||
|  |             local min = @(a, b) a< b ? a : b; | ||||||
|  |             local near = str.slice(start, min(str.len(), start + 10)); | ||||||
|  |             throw "JSON Syntax Error near `" + near + "`"; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return value; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Convert strings/numbers | ||||||
|  |      * Uses custom converter function | ||||||
|  |      * | ||||||
|  |      * @param {string} value | ||||||
|  |      * @param {string} type | ||||||
|  |      * @param {function|null} converter | ||||||
|  |      */ | ||||||
|  |     function _convert(value, type, converter) { | ||||||
|  |         if ("function" == typeof converter) { | ||||||
|  | 
 | ||||||
|  |             // # of params for converter function | ||||||
|  | 
 | ||||||
|  |             local parametercCount = 2; | ||||||
|  | 
 | ||||||
|  |             // .getinfos() is missing on ei platform | ||||||
|  |             if ("getinfos" in converter) { | ||||||
|  |                 parametercCount = converter.getinfos().parameters.len() - | ||||||
|  |                     1 /* "this" is also included */ ; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (parametercCount == 1) { | ||||||
|  |                 return converter(value); | ||||||
|  |             } else if (parametercCount == 2) { | ||||||
|  |                 return converter(value, type); | ||||||
|  |             } else { | ||||||
|  |                 throw "Error: converter function must take 1 or 2 parameters" | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } else if ("number" == type) { | ||||||
|  |             return (value.find(".") == null && value.find("e") == null && value.find("E") == null) ? value.tointeger() : value.tofloat(); | ||||||
|  |         } else { | ||||||
|  |             return value; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * JSON Tokenizer | ||||||
|  |  * @package JSONParser | ||||||
|  |  */ | ||||||
|  | class _JSONTokenizer { | ||||||
|  | 
 | ||||||
|  |     _ptfnRegex = null; | ||||||
|  |     _numberRegex = null; | ||||||
|  |     _stringRegex = null; | ||||||
|  |     _ltrimRegex = null; | ||||||
|  |     _unescapeRegex = null; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         // punctuation/true/false/null | ||||||
|  |         this._ptfnRegex = regexp("^(?:\\,|\\:|\\[|\\]|\\{|\\}|true|false|null)"); | ||||||
|  | 
 | ||||||
|  |         // numbers | ||||||
|  |         this._numberRegex = regexp("^(?:\\-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)"); | ||||||
|  | 
 | ||||||
|  |         // strings | ||||||
|  |         this._stringRegex = regexp("^(?:\\\"((?:[^\\r\\n\\t\\\\\\\"]|\\\\(?:[\"\\\\\\/trnfb]|u[0-9a-fA-F]{4}))*)\\\")"); | ||||||
|  | 
 | ||||||
|  |         // ltrim pattern | ||||||
|  |         this._ltrimRegex = regexp("^[\\s\\t\\n\\r]*"); | ||||||
|  | 
 | ||||||
|  |         // string unescaper tokenizer pattern | ||||||
|  |         this._unescapeRegex = regexp("\\\\(?:(?:u\\d{4})|[\\\"\\\\/bfnrt])"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get next available token | ||||||
|  |      * @param {string} str | ||||||
|  |      * @param {integer} start | ||||||
|  |      * @return {{type,value,length}|null} | ||||||
|  |      */ | ||||||
|  |     function nextToken(str, start = 0) { | ||||||
|  | 
 | ||||||
|  |         local | ||||||
|  |         m, | ||||||
|  |         type, | ||||||
|  |         token, | ||||||
|  |         value, | ||||||
|  |         length, | ||||||
|  |         whitespaces; | ||||||
|  | 
 | ||||||
|  |         // count # of left-side whitespace chars | ||||||
|  |         whitespaces = this._leadingWhitespaces(str, start); | ||||||
|  |         start += whitespaces; | ||||||
|  | 
 | ||||||
|  |         if (m = this._ptfnRegex.capture(str, start)) { | ||||||
|  |             // punctuation/true/false/null | ||||||
|  |             value = str.slice(m[0].begin, m[0].end); | ||||||
|  |             type = "ptfn"; | ||||||
|  |         } else if (m = this._numberRegex.capture(str, start)) { | ||||||
|  |             // number | ||||||
|  |             value = str.slice(m[0].begin, m[0].end); | ||||||
|  |             type = "number"; | ||||||
|  |         } else if (m = this._stringRegex.capture(str, start)) { | ||||||
|  |             // string | ||||||
|  |             value = str.slice(m[1].begin, m[1].end); | ||||||
|  |             type = "string"; | ||||||
|  |         } else { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         token = { | ||||||
|  |             type = type, | ||||||
|  |             value = value, | ||||||
|  |             length = m[0].end - m[0].begin + whitespaces | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         return token; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Count # of left-side whitespace chars | ||||||
|  |      * @param {string} str | ||||||
|  |      * @param {integer} start | ||||||
|  |      * @return {integer} number of leading spaces | ||||||
|  |      */ | ||||||
|  |     function _leadingWhitespaces(str, start) { | ||||||
|  |         local r = this._ltrimRegex.capture(str, start); | ||||||
|  | 
 | ||||||
|  |         if (r) { | ||||||
|  |             return r[0].end - r[0].begin; | ||||||
|  |         } else { | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // unesacape() replacements table | ||||||
|  |     _unescapeReplacements = { | ||||||
|  |         "b": "\b", | ||||||
|  |         "f": "\f", | ||||||
|  |         "n": "\n", | ||||||
|  |         "r": "\r", | ||||||
|  |         "t": "\t" | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Unesacape string escaped per JSON standard | ||||||
|  |      * @param {string} str | ||||||
|  |      * @return {string} | ||||||
|  |      */ | ||||||
|  |     function unescape(str) { | ||||||
|  |         local start = 0; | ||||||
|  |         local res = ""; | ||||||
|  | 
 | ||||||
|  |         while (start< str.len()) { | ||||||
|  |             local m = this._unescapeRegex.capture(str, start); | ||||||
|  | 
 | ||||||
|  |             if (m) { | ||||||
|  |                 local token = str.slice(m[0].begin, m[0].end); | ||||||
|  | 
 | ||||||
|  |                 // append chars before match | ||||||
|  |                 local pre = str.slice(start, m[0].begin); | ||||||
|  |                 res += pre; | ||||||
|  | 
 | ||||||
|  |                 if (token.len() == 6) { | ||||||
|  |                     // unicode char in format \uhhhh, where hhhh is hex char code | ||||||
|  |                     // todo: convert \uhhhh chars | ||||||
|  |                     res += token; | ||||||
|  |                 } else { | ||||||
|  |                     // escaped char | ||||||
|  |                     // @see http://www.json.org/ | ||||||
|  |                     local char = token.slice(1); | ||||||
|  | 
 | ||||||
|  |                     if (char in this._unescapeReplacements) { | ||||||
|  |                         res += this._unescapeReplacements[char]; | ||||||
|  |                     } else { | ||||||
|  |                         res += char; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } else { | ||||||
|  |                 // append the rest of the source string | ||||||
|  |                 res += str.slice(start); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             start = m[0].end; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return res; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // Copyright (c) 2017 Electric Imp | ||||||
|  | // This file is licensed under the MIT License | ||||||
|  | // http://opensource.org/licenses/MIT | ||||||
|  | 
 | ||||||
|  | class JSONEncoder { | ||||||
|  | 
 | ||||||
|  |     static VERSION = "2.0.0"; | ||||||
|  | 
 | ||||||
|  |     // max structure depth | ||||||
|  |     // anything above probably has a cyclic ref | ||||||
|  |     static _maxDepth = 32; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Encode value to JSON | ||||||
|  |      * @param {table|array|*} value | ||||||
|  |      * @returns {string} | ||||||
|  |      */ | ||||||
|  |     function encode(value) { | ||||||
|  |         return this._encode(value); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @param {table|array} val | ||||||
|  |      * @param {integer=0} depth – current depth level | ||||||
|  |      * @private | ||||||
|  |      */ | ||||||
|  |     function _encode(val, depth = 0) { | ||||||
|  | 
 | ||||||
|  |         // detect cyclic reference | ||||||
|  |         if (depth > this._maxDepth) { | ||||||
|  |             throw "Possible cyclic reference"; | ||||||
|  |         } | ||||||
|  |         local | ||||||
|  |         r = "", | ||||||
|  |             s = "", | ||||||
|  |             i = 0; | ||||||
|  | 
 | ||||||
|  |         switch (typeof val) { | ||||||
|  | 
 | ||||||
|  |             case "table": | ||||||
|  |             case "class": | ||||||
|  |                 s = ""; | ||||||
|  | 
 | ||||||
|  |                 // serialize properties, but not functions | ||||||
|  |                 foreach(k, v in val) { | ||||||
|  |                     if (typeof v != "function") { | ||||||
|  |                         s += ",\"" + k + "\":" + this._encode(v, depth + 1); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 s = s.len() > 0 ? s.slice(1) : s; | ||||||
|  |                 r += "{" + s + "}"; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "array": | ||||||
|  |                 s = ""; | ||||||
|  | 
 | ||||||
|  |                 for (i = 0; i< val.len(); i++) { | ||||||
|  |                     s += "," + this._encode(val[i], depth + 1); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 s = (i > 0) ? s.slice(1) : s; | ||||||
|  |                 r += "[" + s + "]"; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "integer": | ||||||
|  |             case "float": | ||||||
|  |             case "bool": | ||||||
|  |                 r += val; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "null": | ||||||
|  |                 r += "null"; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "instance": | ||||||
|  | 
 | ||||||
|  |                 if ("_serializeRaw" in val && typeof val._serializeRaw == "function") { | ||||||
|  | 
 | ||||||
|  |                     // include value produced by _serializeRaw() | ||||||
|  |                     r += val._serializeRaw().tostring(); | ||||||
|  | 
 | ||||||
|  |                 } else if ("_serialize" in val && typeof val._serialize == "function") { | ||||||
|  | 
 | ||||||
|  |                     // serialize instances by calling _serialize method | ||||||
|  |                     r += this._encode(val._serialize(), depth + 1); | ||||||
|  | 
 | ||||||
|  |                 } else { | ||||||
|  | 
 | ||||||
|  |                     s = ""; | ||||||
|  | 
 | ||||||
|  |                     try { | ||||||
|  | 
 | ||||||
|  |                         // iterate through instances which implement _nexti meta-method | ||||||
|  |                         foreach(k, v in val) { | ||||||
|  |                             s += ",\"" + k + "\":" + this._encode(v, depth + 1); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                     } catch (e) { | ||||||
|  | 
 | ||||||
|  |                         // iterate through instances w/o _nexti | ||||||
|  |                         // serialize properties, but not functions | ||||||
|  |                         foreach(k, v in val.getclass()) { | ||||||
|  |                             if (typeof v != "function") { | ||||||
|  |                                 s += ",\"" + k + "\":" + this._encode(val[k], depth + 1); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     s = s.len() > 0 ? s.slice(1) : s; | ||||||
|  |                     r += "{" + s + "}"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "blob": | ||||||
|  |                 // This is a workaround for a known bug: | ||||||
|  |                 // on device side Blob.tostring() returns null | ||||||
|  |                 // (instaead of an empty string) | ||||||
|  |                 r += "\"" + (val.len() ? this._escape(val.tostring()) : "") + "\""; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |                 // strings and all other | ||||||
|  |             case "string": | ||||||
|  |                 r += "\"" + this._escape(val) + "\""; | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 r += "\"" + this._escape(val.tostring()) + "\""; | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return r; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Escape strings according to http://www.json.org/ spec | ||||||
|  |      * @param {string} str | ||||||
|  |      */ | ||||||
|  |     function _escape(str) { | ||||||
|  |         local res = ""; | ||||||
|  | 
 | ||||||
|  |         for (local i = 0; i< str.len(); i++) { | ||||||
|  | 
 | ||||||
|  |             local ch1 = (str[i] & 0xFF); | ||||||
|  | 
 | ||||||
|  |             if ((ch1 & 0x80) == 0x00) { | ||||||
|  |                 // 7-bit Ascii | ||||||
|  | 
 | ||||||
|  |                 ch1 = format("%c", ch1); | ||||||
|  | 
 | ||||||
|  |                 if (ch1 == "\"") { | ||||||
|  |                     res += "\\\""; | ||||||
|  |                 } else if (ch1 == "\\") { | ||||||
|  |                     res += "\\\\"; | ||||||
|  |                 } else if (ch1 == "/") { | ||||||
|  |                     res += "\\/"; | ||||||
|  |                 } else if (ch1 == "\b") { | ||||||
|  |                     res += "\\b"; | ||||||
|  |                 } else if (ch1 == "\f") { | ||||||
|  |                     res += "\\f"; | ||||||
|  |                 } else if (ch1 == "\n") { | ||||||
|  |                     res += "\\n"; | ||||||
|  |                 } else if (ch1 == "\r") { | ||||||
|  |                     res += "\\r"; | ||||||
|  |                 } else if (ch1 == "\t") { | ||||||
|  |                     res += "\\t"; | ||||||
|  |                 } else if (ch1 == "\0") { | ||||||
|  |                     res += "\\u0000"; | ||||||
|  |                 } else { | ||||||
|  |                     res += ch1; | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  | 
 | ||||||
|  |                 if ((ch1 & 0xE0) == 0xC0) { | ||||||
|  |                     // 110xxxxx = 2-byte unicode | ||||||
|  |                     local ch2 = (str[++i] & 0xFF); | ||||||
|  |                     res += format("%c%c", ch1, ch2); | ||||||
|  |                 } else if ((ch1 & 0xF0) == 0xE0) { | ||||||
|  |                     // 1110xxxx = 3-byte unicode | ||||||
|  |                     local ch2 = (str[++i] & 0xFF); | ||||||
|  |                     local ch3 = (str[++i] & 0xFF); | ||||||
|  |                     res += format("%c%c%c", ch1, ch2, ch3); | ||||||
|  |                     // return str; | ||||||
|  |                 } else if ((ch1 & 0xF8) == 0xF0) { | ||||||
|  |                     // 11110xxx = 4 byte unicode | ||||||
|  |                     local ch2 = (str[++i] & 0xFF); | ||||||
|  |                     local ch3 = (str[++i] & 0xFF); | ||||||
|  |                     local ch4 = (str[++i] & 0xFF); | ||||||
|  |                     res += format("%c%c%c%c", ch1, ch2, ch3, ch4); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return res; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,406 @@ | ||||||
|  | /* | ||||||
|  | 文件名:MathClass.nut | ||||||
|  | 路径:System/BaseTool/MathClass.nut | ||||||
|  | 创建日期:2024-05-10	16:02 | ||||||
|  | 文件用途:数学库 | ||||||
|  | */ | ||||||
|  | class Math { | ||||||
|  | 
 | ||||||
|  |     function getDirectionToTargetX(objX, x) { | ||||||
|  |         if (objX > x) | ||||||
|  |             return 0; | ||||||
|  |         else | ||||||
|  |             return 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 取随机值 左闭右闭 | ||||||
|  |      * @参数 name | ||||||
|  |      * @返回值 | ||||||
|  |      */ | ||||||
|  |     function Rand(Min, Max) { | ||||||
|  |         local In = rand(); | ||||||
|  |         local Ret = (Min + (Max - Min + 1) * (In / (RAND_MAX + 1).tofloat())).tointeger(); | ||||||
|  |         return Ret; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function getCollisionByObjBox(obj, box) { | ||||||
|  |         local x = obj.X; | ||||||
|  |         local y = obj.Y; | ||||||
|  |         local z = obj.Z; | ||||||
|  | 
 | ||||||
|  |         local ArrBuf = []; | ||||||
|  |         if (obj.Direction == 1) { | ||||||
|  |             local pleft = [x + box[0], y + box[1], z + box[2]]; | ||||||
|  |             local pright = [x + box[0] + box[3], y + box[1] + box[4], z + box[2] + box[5]]; | ||||||
|  | 
 | ||||||
|  |             ArrBuf.extend(pleft); | ||||||
|  |             ArrBuf.extend(pright); | ||||||
|  |         } else { | ||||||
|  |             local pleft = [x - box[0], y + box[1], z + box[2]]; | ||||||
|  |             local pright = [x - box[0] - box[3], y + box[1] + box[4], z + box[2] + box[5]]; | ||||||
|  | 
 | ||||||
|  |             ArrBuf.extend(pleft); | ||||||
|  |             ArrBuf.extend(pright); | ||||||
|  |         } | ||||||
|  |         return ArrBuf; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function GetDistancePos(startX, direction, offsetX) { | ||||||
|  |         if (direction == 0) | ||||||
|  |             return startX - offsetX; | ||||||
|  | 
 | ||||||
|  |         return startX + offsetX; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //通过坐标获得两点旋转角度 | ||||||
|  |     function getRorateAngleByCurrentPos(x1, y1, z1, x2, y2, z2) { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //贝塞尔曲线构造的抛物线运动,支持开始z轴(obj,curT,lastZ,moveT) | ||||||
|  |     function sq_BParabola(currentT, maxT, initZPos, jumpHeight, lastZPos) { | ||||||
|  |         local z = getBeizeri(currentT, maxT, initZPos, initZPos + jumpHeight, initZPos + jumpHeight, lastZPos); | ||||||
|  |         return z.tointeger(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获得抛物线(不支持开始z轴) | ||||||
|  |     function sq_Parabola(x, b, c) { | ||||||
|  |         local a = (-b.tofloat() * 4) / (c.tofloat() * c.tofloat()); | ||||||
|  |         return a.tofloat() * (x.tofloat() - c.tofloat() / 2) * (x.tofloat() - c.tofloat() / 2) + b.tofloat(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获得两点之间平面的距离. | ||||||
|  |     function Get2D_Distance(x1, y1, x2, y2) { | ||||||
|  |         local offsetX = x1 - x2; | ||||||
|  |         local offsetY = (y1 - y2) * 0.29; | ||||||
|  | 
 | ||||||
|  |         return sqrt(offsetX * offsetX + offsetY * offsetY); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //判断给定的角度是否在startA和endA角度之间(startA与endA形成的锐角内) | ||||||
|  |     function CheckAngleIsInArea(judge, startA, endA) { | ||||||
|  | 
 | ||||||
|  |         if (startA< 0) | ||||||
|  |             startA = startA + 360.0; | ||||||
|  | 
 | ||||||
|  |         if (endA< 0) | ||||||
|  |             endA = endA + 360.0; | ||||||
|  | 
 | ||||||
|  |         if (startA > 360.0) | ||||||
|  |             startA = startA - 360.0; | ||||||
|  | 
 | ||||||
|  |         if (endA > 360.0) | ||||||
|  |             endA = endA - 360.0; | ||||||
|  | 
 | ||||||
|  |         if (startA > 0 && startA< 90 && endA > 270 && endA< 360) { | ||||||
|  |             if (judge > 270 && judge< 360) { | ||||||
|  |                 if (endA< judge && judge< startA + 360) | ||||||
|  |                     return true; | ||||||
|  |             } else if (judge< 90) { | ||||||
|  |                 if (endA< judge + 360 && judge + 360< startA + 360) | ||||||
|  |                     return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } else { | ||||||
|  |             if (endA > judge && judge > startA) | ||||||
|  |                 return true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //弧度制转为角度制 | ||||||
|  |     function toDegree(x) { | ||||||
|  |         return x * 57.29577; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //角度转为弧度 | ||||||
|  |     function toRadian(x) { | ||||||
|  |         return x * 0.01745; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //立方体与立方体之间碰撞 暂未测试 | ||||||
|  |     function CubeAndCubeCollection(c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ) { | ||||||
|  | 
 | ||||||
|  |         if (pointIsInCubeArea(c1StartX, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1StartX, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1StartX, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1StartX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1StartX, (c1StartY + c1EndY) / 2, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1StartX, (c1StartY + c1EndY) / 2, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, (c1StartY + c1EndY) / 2, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, (c1StartY + c1EndY) / 2, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1StartX, c1StartY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1StartX, c1EndY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, c1StartY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c1EndX, c1EndY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, (c2StartY + c2EndY) / 2, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, (c2StartY + c2EndY) / 2, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, (c2StartY + c2EndY) / 2, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, (c2StartY + c2EndY) / 2, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, c2StartY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2StartX, c2EndY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, c2StartY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea(c2EndX, c2EndY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c1StartX + c1EndX) / 2, (c1StartY + c1EndY) / 2, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ)) | ||||||
|  |             return true; | ||||||
|  |         if (pointIsInCubeArea((c2StartX + c2EndX) / 2, (c2StartY + c2EndY) / 2, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ)) | ||||||
|  |             return true; | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     //判断该点是否在给定参数的立方体内 | ||||||
|  |     function pointIsInCubeArea(px, py, pz, startX, startY, startZ, endX, endY, endZ) { | ||||||
|  | 
 | ||||||
|  |         local cubeCenterX = (startX + endX) / 2; | ||||||
|  |         local cubeXLen = abs(startX - endX) / 2; | ||||||
|  | 
 | ||||||
|  |         local cubeCenterY = (startY + endY) / 2; | ||||||
|  |         local cubeYLen = abs(startY - endY) / 2; | ||||||
|  | 
 | ||||||
|  |         local cubeCenterZ = (startZ + endZ) / 2; | ||||||
|  |         local cubeZLen = abs(startZ - endZ) / 2; | ||||||
|  | 
 | ||||||
|  |         if (abs(px - cubeCenterX) <= cubeXLen && abs(py - cubeCenterY) <= cubeYLen && abs(pz - cubeCenterZ) <= cubeZLen) | ||||||
|  |             return true; | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //判断(px,py)是否在这个四边形内,如果在就返回true,否则返回false, | ||||||
|  |     //一定要注意,1,2,3,4的坐标必须能首尾组成四边形,不能跳坐标!!!!否则判断会直接失效!!! | ||||||
|  |     function pointIsIn4PointArea(px, py, x1, y1, x2, y2, x3, y3, x4, y4) { | ||||||
|  |         local area = get4PointArea(x1, y1, x2, y2, x3, y3, x4, y4); | ||||||
|  |         local pointArea1 = get3PointArea(x1, y1, x2, y2, px, py); | ||||||
|  |         local pointArea2 = get3PointArea(x2, y2, x3, y3, px, py); | ||||||
|  |         local pointArea3 = get3PointArea(x3, y3, x4, y4, px, py); | ||||||
|  |         local pointArea4 = get3PointArea(x4, y4, x1, y1, px, py); | ||||||
|  | 
 | ||||||
|  |         if (abs(area - pointArea1 - pointArea2 - pointArea3 - pointArea4)< 10.0) | ||||||
|  |             return true; | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     //获得给定4个点形成的四边形面积 | ||||||
|  |     function get4PointArea(x1, y1, x2, y2, x3, y3, x4, y4) { | ||||||
|  |         local area1 = get3PointArea(x1, y1, x2, y2, x3, y3) | ||||||
|  |         local area2 = get3PointArea(x2, y2, x3, y3, x4, y4) | ||||||
|  |         return area1 + area2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获得给定3个点形成的三角形面积 | ||||||
|  |     function get3PointArea(x1, y1, x2, y2, x3, y3) { | ||||||
|  | 
 | ||||||
|  |         return abs(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2; | ||||||
|  | 
 | ||||||
|  |         /* | ||||||
|  |         local l1 = sqrt(pow((x1- x2), 2) + pow((y1- y2), 2)); | ||||||
|  |         local l2 = sqrt(pow((x1- x3), 2) + pow((y1- y3), 2)); | ||||||
|  |         local l3 = sqrt(pow((x2- x3), 2) + pow((y2- y3), 2)); | ||||||
|  | 
 | ||||||
|  |         return sqrt((l1 + l2 + l3) * (l1 + l2- l3) * (l1- l2 + l3) * (l2 + l3- l1)) / 4; | ||||||
|  |         */ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     //获得该数的符号 | ||||||
|  |     function getSign(var) { | ||||||
|  |         if (var< 0) | ||||||
|  |             return 1; | ||||||
|  |         else if (var > 0) | ||||||
|  |             return -1; | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //简便性能高的开平方 | ||||||
|  |     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; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //四舍五入 | ||||||
|  |     function Round(var) { | ||||||
|  |         local v = | ||||||
|  |             var - | ||||||
|  |             var.tointeger(); | ||||||
|  |         if (v< 0.5) | ||||||
|  |             return var.tointeger(); | ||||||
|  |         return var.tointeger() + 1; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //currentRate 越接近maxRate ,返回值由sv越接近ev | ||||||
|  |     function getUniformVelocity(sv, ev, currentRate, maxRate) { | ||||||
|  | 
 | ||||||
|  |         local rate = currentRate.tofloat() / maxRate.tofloat(); | ||||||
|  | 
 | ||||||
|  |         local varyValue = ev - sv; | ||||||
|  | 
 | ||||||
|  |         return sv + varyValue * rate; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function sq_GetAccel(sv, ev, currentRate, maxRate, increaseFeature) { | ||||||
|  | 
 | ||||||
|  |         local rate = currentRate.tofloat() / maxRate.tofloat(); | ||||||
|  | 
 | ||||||
|  |         local varyValue = ev - sv; | ||||||
|  | 
 | ||||||
|  |         local increaseRate = 1.0; | ||||||
|  | 
 | ||||||
|  |         if (increaseFeature) { | ||||||
|  |             increaseRate = pow(50, rate) / 50; //慢->快 | ||||||
|  |         } else { | ||||||
|  |             increaseRate = pow(rate, 0.05); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         return sv + varyValue * increaseRate; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function getMax(a, b) { | ||||||
|  |         if (a< b) | ||||||
|  |             return b; | ||||||
|  |         return a; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function getMin(a, b) { | ||||||
|  |         if (a > b) | ||||||
|  |             return b; | ||||||
|  |         return a; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获得贝塞尔曲线(2阶) | ||||||
|  |     function getBeizeri(var1, var2, p0, p1, p2, p3) { | ||||||
|  |         local t = var1.tofloat() / var2.tofloat(); | ||||||
|  |         local t1 = 1.0 - t; | ||||||
|  | 
 | ||||||
|  |         local v1 = t1 * t1 * t1; | ||||||
|  |         local v2 = t1 * t1; | ||||||
|  |         local v3 = t1; | ||||||
|  |         local v4 = t * t * t; | ||||||
|  | 
 | ||||||
|  |         local ret = p0 * v1; | ||||||
|  |         ret = ret + 3.0 * p1 * t * v2; | ||||||
|  |         ret = ret + 3.0 * p2 * t * t * v3; | ||||||
|  |         ret = ret + p3 * v4; | ||||||
|  | 
 | ||||||
|  |         return ret; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //获得贝塞尔曲线角度 | ||||||
|  |     function getBeizeriAngle(var1, var2, p0, p1, p2, p3) { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         local t = var1.tofloat() / var2.tofloat(); | ||||||
|  |         local t1 = 1.0 - t; | ||||||
|  | 
 | ||||||
|  |         local v1 = t1 * t1; | ||||||
|  |         local v2 = t1; | ||||||
|  |         local v3 = t1; | ||||||
|  |         local v4 = t * t; | ||||||
|  | 
 | ||||||
|  |         local ret = 2.0 * p0 * v1; | ||||||
|  |         ret = ret + 6.0 * p1 * t * v2; | ||||||
|  |         ret = ret + 6.0 * p2 * t * v3; | ||||||
|  |         ret = ret + 2.0 * p3 * v4; | ||||||
|  | 
 | ||||||
|  |         return ret; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function IsIntersectRect(x1, y1, width1, height1, x2, y2, width2, height2) { | ||||||
|  |         // 计算矩形1的边界 | ||||||
|  |         local right1 = x1 + width1; | ||||||
|  |         local bottom1 = y1 + height1; | ||||||
|  |         // 计算矩形2的边界 | ||||||
|  |         local right2 = x2 + width2; | ||||||
|  |         local bottom2 = y2 + height2; | ||||||
|  |         // 检查是否有重叠 | ||||||
|  |         return !(right1< x2 || bottom1< y2 || x1 > right2 || y1 > bottom2); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | //初始化随机数 | ||||||
|  | srand(time()); | ||||||
|  | Math.Rand(0, 1); | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | /* | ||||||
|  | 文件名:String.nut | ||||||
|  | 路径:Core/BaseTool/String.nut | ||||||
|  | 创建日期:2024-11-28	23:05 | ||||||
|  | 文件用途: | ||||||
|  | */ | ||||||
|  | class String { | ||||||
|  | 
 | ||||||
|  |     //将含有../的路径转为真实路径 | ||||||
|  |     function RegRealPath(Path) { | ||||||
|  |         if (Path.find("../") != null) { | ||||||
|  |             while (true) { | ||||||
|  |                 local rbuf = regexp("[^/]+/../"); | ||||||
|  |                 local Ret = rbuf.capture(Path); | ||||||
|  |                 if (Ret) { | ||||||
|  |                     Path = Path.slice(0, Ret[0].begin) + Path.slice(Ret[0].end); | ||||||
|  |                 } else { | ||||||
|  |                     return Path; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return Path; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | /* | ||||||
|  | 文件名:ENUM_KEY.nut | ||||||
|  | 路径:Core/ENUM/ENUM_KEY.nut | ||||||
|  | 创建日期:2024-11-13	16:31 | ||||||
|  | 文件用途:按键枚举 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | enum MOUSE_KEY { | ||||||
|  |     LEFT, ///< 鼠标左键 | ||||||
|  |     RIGHT, ///< 鼠标右键 | ||||||
|  |     MIDDLE, ///< 鼠标中键 | ||||||
|  | 
 | ||||||
|  |     LAST | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,234 @@ | ||||||
|  | /* | ||||||
|  | 文件名:enum_system.nut | ||||||
|  | 路径:Core/ENUM/enum_system.nut | ||||||
|  | 创建日期:2024-12-01	20:34 | ||||||
|  | 文件用途:系统枚举 | ||||||
|  | */ | ||||||
|  | _DEBUG_ <- true; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | enum MouseButton { | ||||||
|  |     Left ///< 鼠标左键 | ||||||
|  |     Right ///< 鼠标右键 | ||||||
|  |     Middle ///< 鼠标中键 | ||||||
|  | 
 | ||||||
|  |     Last | ||||||
|  | }; | ||||||
|  | enum KeyCode { | ||||||
|  |     nknown ///< 未知 | ||||||
|  |     p ///< 上键 | ||||||
|  |     Left ///< 左键 | ||||||
|  |     Right ///< 右键 | ||||||
|  |     Down ///< 下键 | ||||||
|  |     Enter ///< 回车键 | ||||||
|  |     Space ///< 空格键 | ||||||
|  |     Esc ///< 退出键 | ||||||
|  |     Ctrl ///< CTRL键 | ||||||
|  |     Shift ///< SHIFT键 | ||||||
|  |     Alt ///< ALT键 | ||||||
|  |     Tab ///< TAB键 | ||||||
|  |     Delete ///< 删除键 | ||||||
|  |     Back ///< 退格键 | ||||||
|  |     Super ///< Cmd|Super|Windows键 | ||||||
|  | 
 | ||||||
|  |     A ///< A键 | ||||||
|  |     B ///< B键 | ||||||
|  |     C ///< C键 | ||||||
|  |     D ///< D键 | ||||||
|  |     E ///< E键 | ||||||
|  |     F ///< F键 | ||||||
|  |     G ///< G键 | ||||||
|  |     H ///< H键 | ||||||
|  |     I ///< I键 | ||||||
|  |     J ///< J键 | ||||||
|  |     K ///< K键 | ||||||
|  |     L ///< L键 | ||||||
|  |     M ///< M键 | ||||||
|  |     N ///< N键 | ||||||
|  |     O ///< O键 | ||||||
|  |     P ///< P键 | ||||||
|  |     Q ///< Q键 | ||||||
|  |     R ///< R键 | ||||||
|  |     S ///< S键 | ||||||
|  |     T ///< T键 | ||||||
|  | 
 | ||||||
|  |     V ///< V键 | ||||||
|  |     W ///< W键 | ||||||
|  |     X ///< X键 | ||||||
|  |     Y ///< Y键 | ||||||
|  |     Z ///< Z键 | ||||||
|  | 
 | ||||||
|  |     Num0 ///< 数字0键 | ||||||
|  |     Num1 ///< 数字1键 | ||||||
|  |     Num2 ///< 数字2键 | ||||||
|  |     Num3 ///< 数字3键 | ||||||
|  |     Num4 ///< 数字4键 | ||||||
|  |     Num5 ///< 数字5键 | ||||||
|  |     Num6 ///< 数字6键 | ||||||
|  |     Num7 ///< 数字7键 | ||||||
|  |     Num8 ///< 数字8键 | ||||||
|  |     Num9 ///< 数字9键 | ||||||
|  | 
 | ||||||
|  |     Numpad0 ///< 数字小键盘0键 | ||||||
|  |     Numpad1 ///< 数字小键盘1键 | ||||||
|  |     Numpad2 ///< 数字小键盘2键 | ||||||
|  |     Numpad3 ///< 数字小键盘3键 | ||||||
|  |     Numpad4 ///< 数字小键盘4键 | ||||||
|  |     Numpad5 ///< 数字小键盘5键 | ||||||
|  |     Numpad6 ///< 数字小键盘6键 | ||||||
|  |     Numpad7 ///< 数字小键盘7键 | ||||||
|  |     Numpad8 ///< 数字小键盘8键 | ||||||
|  |     Numpad9 ///< 数字小键盘9键 | ||||||
|  | 
 | ||||||
|  |     F1 ///< F1键 | ||||||
|  |     F2 ///< F2键 | ||||||
|  |     F3 ///< F3键 | ||||||
|  |     F4 ///< F4键 | ||||||
|  |     F5 ///< F5键 | ||||||
|  |     F6 ///< F6键 | ||||||
|  |     F7 ///< F7键 | ||||||
|  |     F8 ///< F8键 | ||||||
|  |     F9 ///< F9键 | ||||||
|  |     F10 ///< F10键 | ||||||
|  |     F11 ///< F11键 | ||||||
|  |     F12 ///< F12键 | ||||||
|  | 
 | ||||||
|  |     Last | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum SOCKET_CALLBACK_TYPE { | ||||||
|  |     onConnect ///< 连接成功 | ||||||
|  |     onReceive ///< 接收到数据 | ||||||
|  |     onReceiveBinary ///< 接收到二进制数据 | ||||||
|  |     onClose ///< 连接关闭 | ||||||
|  | 
 | ||||||
|  |     Last | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * \~chinese | ||||||
|  |  * @brief 字体粗细值 | ||||||
|  |  */ | ||||||
|  | enum FontWeight { | ||||||
|  |     Thin = 100 | ||||||
|  |     ExtraLight = 200 | ||||||
|  |     Light = 300 | ||||||
|  |     Normal = 400 ///< 正常 | ||||||
|  |     Medium = 500 | ||||||
|  |     Bold = 700 ///< 加粗 | ||||||
|  |     ExtraBold = 800 | ||||||
|  |     Black = 900 | ||||||
|  |     ExtraBlack = 950 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * \~chinese | ||||||
|  |  * @brief 字体形态 | ||||||
|  |  */ | ||||||
|  | enum FontPosture { | ||||||
|  |     Normal ///< 正常 | ||||||
|  |     Oblique ///< 倾斜体 | ||||||
|  |     Italic ///< 斜体 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * \~chinese | ||||||
|  |  * @brief 字体拉伸 | ||||||
|  |  */ | ||||||
|  | enum FontStretch { | ||||||
|  |     Unknown | ||||||
|  |     UltraCondensed | ||||||
|  |     ExtraCondensed | ||||||
|  |     Condensed ///< 压缩 | ||||||
|  |     SemiCondensed | ||||||
|  |     Normal ///< 正常 | ||||||
|  |     SemiExpanded | ||||||
|  |     Expanded ///< 扩大 | ||||||
|  |     ExtraExpanded | ||||||
|  |     UltraExpanded | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /// \~chinese | ||||||
|  | /// @brief 常见颜色枚举 | ||||||
|  | enum Color { | ||||||
|  |     Black = 0x000000 | ||||||
|  |     Blue = 0x0000FF | ||||||
|  |     BlueViolet = 0x8A2BE2 | ||||||
|  |     Brown = 0xA52A2A | ||||||
|  |     Chocolate = 0xD2691E | ||||||
|  |     DarkBlue = 0x00008B | ||||||
|  |     DarkGray = 0xA9A9A9 | ||||||
|  |     DarkGreen = 0x006400 | ||||||
|  |     DarkOrange = 0xFF8C00 | ||||||
|  |     DarkRed = 0x8B0000 | ||||||
|  |     DarkViolet = 0x9400D3 | ||||||
|  |     ForestGreen = 0x228B22 | ||||||
|  |     Gold = 0xFFD700 | ||||||
|  |     Gray = 0x808080 | ||||||
|  |     Green = 0x008000 | ||||||
|  |     GreenYellow = 0xADFF2F | ||||||
|  |     LightBlue = 0xADD8E6 | ||||||
|  |     LightCyan = 0xE0FFFF | ||||||
|  |     LightGreen = 0x90EE90 | ||||||
|  |     LightGray = 0xD3D3D3 | ||||||
|  |     LightPink = 0xFFB6C1 | ||||||
|  |     LightSeaGreen = 0x20B2AA | ||||||
|  |     LightSkyBlue = 0x87CEFA | ||||||
|  |     LightYellow = 0xFFFFE0 | ||||||
|  |     Orange = 0xFFA500 | ||||||
|  |     OrangeRed = 0xFF4500 | ||||||
|  |     Pink = 0xFFC0CB | ||||||
|  |     Purple = 0x800080 | ||||||
|  |     Red = 0xFF0000 | ||||||
|  |     Silver = 0xC0C0C0 | ||||||
|  |     SkyBlue = 0x87CEEB | ||||||
|  |     Snow = 0xFFFAFA | ||||||
|  |     Violet = 0xEE82EE | ||||||
|  |     Wheat = 0xF5DEB3 | ||||||
|  |     White = 0xFFFFFF | ||||||
|  |     WhiteSmoke = 0xF5F5F5 | ||||||
|  |     Wood = 0xDEB887 | ||||||
|  |     Yellow = 0xFFFF00 | ||||||
|  |     YellowGreen = 0x9ACD32 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * \~chinese | ||||||
|  |  * @brief 文本对齐方式 | ||||||
|  |  */ | ||||||
|  | enum TextAlign { | ||||||
|  |     Left ///< 左对齐 | ||||||
|  |     Right ///< 右对齐 | ||||||
|  |     Center ///< 居中对齐 | ||||||
|  |     Justified ///< 两端对齐 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /// \~chinese | ||||||
|  | /// @brief 线条端点样式 | ||||||
|  | /// @details 线条端点样式表示线段端点部分的形状 | ||||||
|  | enum CapStyle { | ||||||
|  |     Flat ///< 扁端点 | ||||||
|  |     Square ///< 方形端点,方形突出部分等于线段宽度的一半 | ||||||
|  |     Round ///< 圆形端点,圆直径等于线段宽度 | ||||||
|  |     Triangle ///< 三角样式,三角斜边长度等于线段宽度 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /// \~chinese | ||||||
|  | /// @brief 线条交点样式 | ||||||
|  | /// @details 线条交点样式表示两条线相交部分的形状 | ||||||
|  | enum LineJoinStyle { | ||||||
|  |     Miter ///< 斜切样式 | ||||||
|  |     Bevel ///< 斜角样式 | ||||||
|  |     Round ///< 圆角样式 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /// \~chinese | ||||||
|  | /// @brief 线条虚线样式 | ||||||
|  | /// @details 线条虚线样式表示线段的间隙 | ||||||
|  | enum DashStyle { | ||||||
|  |     Solid ///< 无间断的实线 | ||||||
|  |     Dash ///< 斜角样式 | ||||||
|  |     Dot ///< 圆角样式 | ||||||
|  |     DashDot ///< 圆角样式 | ||||||
|  |     DashDotDot ///< 圆角样式 | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,48 @@ | ||||||
|  | /* | ||||||
|  | 文件名:Socket.nut | ||||||
|  | 路径:Core/ExtraCalss/Socket/Socket.nut | ||||||
|  | 创建日期:2024-11-30	19:55 | ||||||
|  | 文件用途: | ||||||
|  | */ | ||||||
|  | _Socket_Map_ <- []; | ||||||
|  | class Socket { | ||||||
|  |     //监听器 | ||||||
|  |     Listeners = null; | ||||||
|  |     //客户端 | ||||||
|  |     Client = null; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         //创建监听器 | ||||||
|  |         this.Listeners = Socket_CreateListener(); | ||||||
|  |         //创建客户端 | ||||||
|  |         this.Client = Socket_CreateClient(this.Listeners); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 绑定函数 | ||||||
|  |      * @参数 Type 绑定类型 | ||||||
|  |      * @参数 Func 绑定函数 | ||||||
|  |      */ | ||||||
|  |     function BindFunc(Type, Func) { | ||||||
|  |         Socket_BindFunc(Client, Type, Func); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 连接到服务器 | ||||||
|  |      * @参数 IpAddr 服务器IP地址 | ||||||
|  |      * @参数 Port 服务器端口 | ||||||
|  |      * @参数 AsyncConnect 是否异步连接 | ||||||
|  |      * @返回值 连接结果 | ||||||
|  |      */ | ||||||
|  |     function Connect(IpAddr, Port, AsyncConnect) { | ||||||
|  |         _Socket_Map_.push(this); | ||||||
|  |         return Socket_Connect(this.Client, IpAddr, Port, AsyncConnect); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 执行包逻辑 | ||||||
|  |      */ | ||||||
|  |     function DispatchPacket() { | ||||||
|  |         Socket_DispatchPacket(this.Client); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | /* | ||||||
|  | 文件名:Game_Proc.nut | ||||||
|  | 路径:Core/Game_Proc/Game_Proc.nut | ||||||
|  | 创建日期:2024-12-01	12:25 | ||||||
|  | 文件用途:游戏进程 | ||||||
|  | */ | ||||||
|  | function _Yosin_Game_Logic_(Dt, GameLister) { | ||||||
|  |     //Socket连接嗅探处理包 | ||||||
|  |     foreach(SocketObj in _Socket_Map_) { | ||||||
|  |         SocketObj.DispatchPacket(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,429 @@ | ||||||
|  | /* | ||||||
|  | 文件名:UI_Core.nut | ||||||
|  | 路径:Core/UI_Class/UI_Core.nut | ||||||
|  | 创建日期:2024-11-08	03:25 | ||||||
|  | 文件用途:UI核心类 | ||||||
|  | */ | ||||||
|  | //窗口队列 | ||||||
|  | _SYS_WINDOW_LIST_ <- []; | ||||||
|  | //基础窗口类 所有UI类继承与本类 | ||||||
|  | class Yosin_BaseWindow extends Actor { | ||||||
|  |     //父控件 | ||||||
|  |     ParentFlag = null; | ||||||
|  |     //子控件 | ||||||
|  |     UI_Childrens = null; | ||||||
|  |     //刷新函数 | ||||||
|  |     UpdateFunc = null; | ||||||
|  |     //是否可见 | ||||||
|  |     Visible = true; | ||||||
|  |     //销毁Flag | ||||||
|  |     DestroyFlag = false; | ||||||
|  |     //X坐标 | ||||||
|  |     X = null; | ||||||
|  |     B_X = null; | ||||||
|  |     //Y坐标 | ||||||
|  |     Y = null; | ||||||
|  |     B_Y = null; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         //构造函数 创建一个空Actor | ||||||
|  |         base.constructor(); | ||||||
|  | 
 | ||||||
|  |         //子控件list初始化 | ||||||
|  |         UI_Childrens = []; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //鼠标事件回调 | ||||||
|  |     function OnMouseProc(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseProc(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标左键按下回调 | ||||||
|  |     function OnMouseLbDown(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseLbDown(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标左键单击回调 | ||||||
|  |     function OnMouseLbClick(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseLbClick(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标左键弹起回调 | ||||||
|  |     function OnMouseLbUp(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseLbUp(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标右键按下回调 | ||||||
|  |     function OnMouseRbDown(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseRbDown(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标右键单击回调 | ||||||
|  |     function OnMouseRbClick(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseRbClick(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标右键弹起回调 | ||||||
|  |     function OnMouseRbUp(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseRbUp(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标中键按下回调 | ||||||
|  |     function OnMouseMbDown(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseMbDown(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标中键单击回调 | ||||||
|  |     function OnMouseMbClick(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseMbClick(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标中键弹起回调 | ||||||
|  |     function OnMouseMbUp(MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseMbUp(MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标滚轮事件回调 | ||||||
|  |     function OnMouseWheel(Wheel, MousePos_X, MousePos_Y) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             Window.OnMouseWheel(Wheel, MousePos_X, MousePos_Y); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //设置回调事件 | ||||||
|  |     function SetUpdateFunc(Func) { | ||||||
|  |         CallBackFunc = Func; | ||||||
|  |     } | ||||||
|  |     //逻辑 | ||||||
|  |     function Proc(Dt) { | ||||||
|  |         foreach(Window in UI_Childrens) { | ||||||
|  |             // if (Window.CallBackFunc) Window.CallBackFunc(Window); | ||||||
|  |             Window.Proc(Dt); | ||||||
|  |         } | ||||||
|  |         //显示才调用Update | ||||||
|  |         if (Visible) base.OnUpdate(Dt); | ||||||
|  |     } | ||||||
|  |     //同步坐标 | ||||||
|  |     function SyncPos(X, Y) { | ||||||
|  |         this.X = X; | ||||||
|  |         this.Y = Y; | ||||||
|  |         SetPosition(X, Y); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //游戏窗口类 | ||||||
|  | class Yosin_Window extends Yosin_BaseWindow { | ||||||
|  |     //窗口名称 | ||||||
|  |     ObjectId = null; | ||||||
|  |     //宽度 | ||||||
|  |     Width = null; | ||||||
|  |     //高度 | ||||||
|  |     Height = null; | ||||||
|  |     //标题高度 | ||||||
|  |     TitleH = null; | ||||||
|  | 
 | ||||||
|  |     //调试模式 | ||||||
|  |     DeBugMode = false; | ||||||
|  |     //鼠标相对位置 | ||||||
|  |     M_Xpos = null; | ||||||
|  |     M_Ypos = null; | ||||||
|  |     //移动Flag | ||||||
|  |     MoveFlag = false; | ||||||
|  | 
 | ||||||
|  |     constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) { | ||||||
|  |         ObjectId = gObjectId; | ||||||
|  |         //宽度 | ||||||
|  |         Width = gWidth; | ||||||
|  |         //高度 | ||||||
|  |         Height = gHeight; | ||||||
|  |         //标题高度 | ||||||
|  |         TitleH = gTitleH; | ||||||
|  | 
 | ||||||
|  |         //X坐标 | ||||||
|  |         X = gX; | ||||||
|  |         //Y坐标 | ||||||
|  |         Y = gY; | ||||||
|  | 
 | ||||||
|  |         //调用原生方法 | ||||||
|  |         base.constructor(); | ||||||
|  | 
 | ||||||
|  |         SetSize(Width, Height); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //切换到最上层窗口 即得到焦点时 全局窗口才调用 子窗口请不要调用此函数 | ||||||
|  |     function ResetFocus() { | ||||||
|  |         this.Visible = true; | ||||||
|  |         //遍历全局窗口数组将自己移除重新添加在末尾 | ||||||
|  |         foreach(Index, WindowObj in _SYS_WINDOW_LIST_) { | ||||||
|  |             WindowObj.SetZOrder(10000000 + Index); | ||||||
|  |             if (WindowObj.ObjectId == this.ObjectId) { | ||||||
|  |                 _SYS_WINDOW_LIST_.remove(Index); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         _SYS_WINDOW_LIST_.append(this); | ||||||
|  |         SetZOrder(10000000 + _SYS_WINDOW_LIST_.len()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 移除子对象 | ||||||
|  |      * @参数 子对象名称 | ||||||
|  |      * @返回值 是否有移除了子对象 | ||||||
|  |      */ | ||||||
|  |     function RemoveUIChild(ChildName) { | ||||||
|  |         foreach(_Index, _Child in UI_Childrens) { | ||||||
|  |             if (_Child.ObjectId == ChildName) { | ||||||
|  |                 UI_Childrens.remove(_Index); | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 移除子对象类 | ||||||
|  |      * @参数 类   如果传入第二个参数false 则移除所有非该类的子对象 | ||||||
|  |      * @返回值 | ||||||
|  |      */ | ||||||
|  |     function RemoveUIChilds(ClassName, ...) { | ||||||
|  |         local RemoveIndexArr = []; | ||||||
|  |         if (vargc == 1 && vargv[0] == false) { | ||||||
|  |             foreach(_Index, _Child in UI_Childrens) { | ||||||
|  |                 if (!(_Child instanceof ClassName)) { | ||||||
|  |                     RemoveIndexArr.append(_Index - RemoveIndexArr.len()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             foreach(_Index, _Child in UI_Childrens) { | ||||||
|  |                 if (_Child instanceof ClassName) { | ||||||
|  |                     RemoveIndexArr.append(_Index - RemoveIndexArr.len()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         foreach(SaveIndex in RemoveIndexArr) { | ||||||
|  |             UI_Childrens.remove(SaveIndex); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 添加子对象 | ||||||
|  |      * @参数 name | ||||||
|  |      */ | ||||||
|  |     function AddUIChild(gChild) { | ||||||
|  |         this.UI_Childrens.append(gChild); | ||||||
|  |         Addchild(gChild); | ||||||
|  |         // gChild.Parent = this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //关闭窗口 -并没有销毁只是隐藏 | ||||||
|  |     function CloseWindow() { | ||||||
|  |         this.Visible = false; | ||||||
|  |     } | ||||||
|  |     //销毁全局UI中的窗口 子窗口只要父窗口被销毁就会被销毁 | ||||||
|  |     function DestroyWindow() { | ||||||
|  |         this.Visible = false; | ||||||
|  |         this.DestroyFlag = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //开启Debug模式 | ||||||
|  |     function OpenDeBug() { | ||||||
|  |         ShowBorder(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //override | ||||||
|  |     function OnMouseProc(MousePos_X, MousePos_Y) { | ||||||
|  |         if (!Visible) return; | ||||||
|  |         //设定拖动逻辑 | ||||||
|  |         if (MoveFlag) { | ||||||
|  |             //左键拖动 | ||||||
|  |             X = B_X - (M_Xpos - MousePos_X); | ||||||
|  |             Y = B_Y - (M_Ypos - MousePos_Y); | ||||||
|  |         } | ||||||
|  |         //调用原生方法 | ||||||
|  |         base.OnMouseProc(MousePos_X, MousePos_Y); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //override | ||||||
|  |     //鼠标左键按下回调 | ||||||
|  |     function OnMouseLbDown(MousePos_X, MousePos_Y) { | ||||||
|  |         if (!Visible) return; | ||||||
|  |         //如果点击事件在窗口内 | ||||||
|  |         if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, X, Y, Width, Height)) { | ||||||
|  |             ResetFocus(); | ||||||
|  |             //如果点下去在标题栏 | ||||||
|  |             if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, X, Y, Width, TitleH)) { | ||||||
|  |                 MoveFlag = true; | ||||||
|  |                 M_Xpos = MousePos_X; //原始鼠标位置数据 | ||||||
|  |                 M_Ypos = MousePos_Y; | ||||||
|  |                 B_X = X; //原始窗口位置 | ||||||
|  |                 B_Y = Y; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         //调用原生方法 | ||||||
|  |         base.OnMouseLbDown(MousePos_X, MousePos_Y); | ||||||
|  |     } | ||||||
|  |     //override | ||||||
|  |     //鼠标左键弹起回调 | ||||||
|  |     function OnMouseLbUp(MousePos_X, MousePos_Y) { | ||||||
|  |         if (!Visible) return; | ||||||
|  |         if (MoveFlag) { | ||||||
|  |             MoveFlag = false; | ||||||
|  |             M_Xpos = null; | ||||||
|  |             M_Ypos = null; | ||||||
|  |             B_X = null; | ||||||
|  |             B_Y = null; | ||||||
|  |         } | ||||||
|  |         //调用原生方法 | ||||||
|  |         base.OnMouseLbUp(MousePos_X, MousePos_Y); | ||||||
|  |     } | ||||||
|  |     //override | ||||||
|  |     //鼠标右键按下回调 | ||||||
|  |     function OnMouseRbDown(MousePos_X, MousePos_Y) { | ||||||
|  |         if (!Visible) return; | ||||||
|  |         //调用原生方法 | ||||||
|  |         base.OnMouseRbDown(MousePos_X, MousePos_Y); | ||||||
|  |     } | ||||||
|  |     //override | ||||||
|  |     //鼠标右键弹起回调 | ||||||
|  |     function OnMouseRbUp(MousePos_X, MousePos_Y) { | ||||||
|  |         if (!Visible) return; | ||||||
|  |         //调用原生方法 | ||||||
|  |         base.OnMouseRbUp(MousePos_X, MousePos_Y); | ||||||
|  |     } | ||||||
|  |     //override | ||||||
|  |     //鼠标滚轮事件回调 | ||||||
|  |     function OnMouseWheel(Flag, MousePos_X, MousePos_Y) { | ||||||
|  |         if (!Visible) return; | ||||||
|  |         //调用原生方法 | ||||||
|  |         base.OnMouseWheel(Flag, MousePos_X, MousePos_Y); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //创建窗口 | ||||||
|  | function Sq_CreateWindow(ClassName, gObjectId, gX, gY, gWidth, gHeight, gTitleH) { | ||||||
|  |     foreach(Index, WindowObj in _SYS_WINDOW_LIST_) { | ||||||
|  |         if (WindowObj.ObjectId == gObjectId) { | ||||||
|  |             return WindowObj; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     local WindowObj = ClassName(gObjectId, gX, gY, gWidth, gHeight, gTitleH); | ||||||
|  |     WindowObj.ResetFocus(); | ||||||
|  |     return WindowObj; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //窗口逻辑入口  C回调 | ||||||
|  | function _Yosin_Windows_Logic_(Dt, Ui_Layer) { | ||||||
|  |     local UiObject = Actor(Ui_Layer); | ||||||
|  |     //遍历窗口队列 如果可见则调用Show | ||||||
|  |     for (local i = 0; i< _SYS_WINDOW_LIST_.len(); i++) { | ||||||
|  |         local Window = _SYS_WINDOW_LIST_[i]; | ||||||
|  |         //根据是否显示 决定是否添加到舞台 | ||||||
|  |         if (!Window.Visible && Window.ParentFlag) { | ||||||
|  |             Window.ParentFlag = null; | ||||||
|  |             UiObject.Removechild(Window); | ||||||
|  |             if (Window.DestroyFlag) { | ||||||
|  |                 _SYS_WINDOW_LIST_.remove(i); | ||||||
|  |                 i--; | ||||||
|  |             } | ||||||
|  |         } else if (Window.Visible && (!Window.ParentFlag)) { | ||||||
|  |             Window.ParentFlag = true; | ||||||
|  |             UiObject.Addchild(Window); | ||||||
|  |         } | ||||||
|  |         //无论窗口是否显示都需要调用Proc | ||||||
|  |         Window.Proc(Dt); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //鼠标点击Flag | ||||||
|  | _Mouse_Click_Flag <- {}; | ||||||
|  | //鼠标逻辑入口 | ||||||
|  | function _Yosin_Windows_Mouse_Logic_(MouseState, Wheel, MousePos_X, MousePos_Y) { | ||||||
|  |     //克隆一遍窗口列表 | ||||||
|  |     local WindowListF = clone(_SYS_WINDOW_LIST_); | ||||||
|  |     WindowListF.reverse(); | ||||||
|  | 
 | ||||||
|  |     foreach(Window in WindowListF) { | ||||||
|  |         if (Window.Visible) { | ||||||
|  |             switch (MouseState) { | ||||||
|  |                 //常规或者拖动事件 | ||||||
|  |                 case 0x305: { | ||||||
|  |                     Window.OnMouseProc(MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 //左键按下 | ||||||
|  |                 case 0x101: { | ||||||
|  |                     _Mouse_Click_Flag.LbFlag <- true; | ||||||
|  |                     Window.OnMouseLbDown(MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 //左键松开 | ||||||
|  |                 case 0x001: { | ||||||
|  |                     //左键单击 | ||||||
|  |                     if (_Mouse_Click_Flag.LbFlag == true) { | ||||||
|  |                         _Mouse_Click_Flag.LbFlag <- false; | ||||||
|  |                         Window.OnMouseLbClick(MousePos_X, MousePos_Y); | ||||||
|  |                     } | ||||||
|  |                     Window.OnMouseLbUp(MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 //右键按下 | ||||||
|  |                 case 0x102: { | ||||||
|  |                     _Mouse_Click_Flag.RbFlag <- true; | ||||||
|  |                     Window.OnMouseRbDown(MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 //右键松开 | ||||||
|  |                 case 0x002: { | ||||||
|  |                     //右键单击 | ||||||
|  |                     if (_Mouse_Click_Flag.RbFlag == true) { | ||||||
|  |                         _Mouse_Click_Flag.RbFlag <- false; | ||||||
|  |                         Window.OnMouseRbClick(MousePos_X, MousePos_Y); | ||||||
|  |                     } | ||||||
|  |                     Window.OnMouseRbUp(MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 //中键按下 | ||||||
|  |                 case 0x103: { | ||||||
|  |                     _Mouse_Click_Flag.MbFlag <- true; | ||||||
|  |                     Window.OnMouseMbDown(MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 //中键松开 | ||||||
|  |                 case 0x003: { | ||||||
|  |                     //中键单击 | ||||||
|  |                     if (_Mouse_Click_Flag.MbFlag == true) { | ||||||
|  |                         _Mouse_Click_Flag.MbFlag <- false; | ||||||
|  |                         Window.OnMouseMbClick(MousePos_X, MousePos_Y); | ||||||
|  |                     } | ||||||
|  |                     Window.OnMouseMbUp(MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 //滚轮事件 | ||||||
|  |                 case 0x406: { | ||||||
|  |                     Window.OnMouseWheel(Wheel, MousePos_X, MousePos_Y); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, Window.X, Window.Y, Window.Width, Window.Height)) return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //输入逻辑函数Map | ||||||
|  | _Imm_Input_Func_ <- {}; | ||||||
|  | //输入逻辑入口 | ||||||
|  | function _Yosin_Imm_Input_Logic_(Str) { | ||||||
|  |     foreach(Func in _Imm_Input_Func_) { | ||||||
|  |         Func(Str); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,138 @@ | ||||||
|  | /* | ||||||
|  | 文件名:UI_Widget.nut | ||||||
|  | 路径:Core/UI_Class/UI_Widget.nut | ||||||
|  | 创建日期:2024-11-08	14:24 | ||||||
|  | 文件用途: 控件基类 | ||||||
|  | */ | ||||||
|  | //基础UI | ||||||
|  | class Yosin_CommonUi extends Yosin_BaseWindow { | ||||||
|  | 
 | ||||||
|  |     ObjectId = null; | ||||||
|  | 
 | ||||||
|  |     Localtion_X = 0; | ||||||
|  |     Localtion_Y = 0; | ||||||
|  |     Width = null; | ||||||
|  |     Height = null; | ||||||
|  | 
 | ||||||
|  |     isLBDown = false; | ||||||
|  |     //是否悬停 | ||||||
|  |     isInRect = false; | ||||||
|  | 
 | ||||||
|  |     OnClick = null; | ||||||
|  |     OnClickSound = null; | ||||||
|  | 
 | ||||||
|  |     Data = null; | ||||||
|  | 
 | ||||||
|  |     constructor(x, y, width, height) { | ||||||
|  |         this.Localtion_X = x; | ||||||
|  |         this.Localtion_Y = y; | ||||||
|  |         this.Width = width; | ||||||
|  |         this.Height = height; | ||||||
|  | 
 | ||||||
|  |         ObjectId = clock(); | ||||||
|  |         base.constructor(); | ||||||
|  |         //构造时第一次同步坐标 | ||||||
|  |         SyncPos(x, y); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //override | ||||||
|  |     //鼠标事件回调 | ||||||
|  |     function OnMouseProc(MousePos_X, MousePos_Y) { | ||||||
|  |         local Pos = GetWorldPosition(); | ||||||
|  |         if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, Pos.x, Pos.y, Width, Height)) isInRect = true; | ||||||
|  |         else isInRect = false; | ||||||
|  |     } | ||||||
|  |     //鼠标左键按下回调 | ||||||
|  |     function OnMouseLbDown(MousePos_X, MousePos_Y) { | ||||||
|  |         local Pos = GetWorldPosition(); | ||||||
|  |         if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, Pos.x, Pos.y, Width, Height)) { | ||||||
|  |             isLBDown = true; | ||||||
|  |             //如果有配置按键音效 | ||||||
|  |             if (OnClickSound) { | ||||||
|  |                 Sq_PlaySoundEffect(OnClickSound); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //鼠标左键弹起回调 | ||||||
|  |     function OnMouseLbUp(MousePos_X, MousePos_Y) { | ||||||
|  |         isLBDown = false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //鼠标左键单击回调 | ||||||
|  |     function OnMouseLbClick(MousePos_X, MousePos_Y) { | ||||||
|  |         local Pos = GetWorldPosition(); | ||||||
|  |         if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, Pos.x, Pos.y, Width, Height)) { | ||||||
|  |             if (OnClick) OnClick(this); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //基础按钮 | ||||||
|  | class Yosin_BaseButton extends Yosin_CommonUi { | ||||||
|  |     //按钮状态 | ||||||
|  |     State = 0; | ||||||
|  |     DWidth = null; | ||||||
|  |     Path = null; | ||||||
|  |     Idx = null; | ||||||
|  | 
 | ||||||
|  |     Sprite = null; | ||||||
|  |     SpriteState = -1; | ||||||
|  |     FrameList = null; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     constructor(X, Y, W, H, Path, Idx) { | ||||||
|  |         this.DWidth = W; | ||||||
|  |         this.Path = Path; | ||||||
|  |         this.Idx = Idx; | ||||||
|  |         base.constructor(X, Y, W, H); | ||||||
|  | 
 | ||||||
|  |         FrameList = []; | ||||||
|  |         Sprite = CL_SpriteObject(); | ||||||
|  |         // Sprite.ShowBorder(true); | ||||||
|  |         Addchild(Sprite); | ||||||
|  | 
 | ||||||
|  |         for (local i = 0; i< 4; i++) { | ||||||
|  |             local Sf = CL_SpriteFrameObject(this.Path, this.Idx + i); | ||||||
|  |             FrameList.push(Sf); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function ChangeFrame() { | ||||||
|  |         //状态更改 刷新精灵帧 | ||||||
|  |         if (State != SpriteState) { | ||||||
|  |             //如果按下 调整Y坐标向下一个单位 | ||||||
|  |             if (State == 2) { | ||||||
|  |                 Y += 1; | ||||||
|  |                 SyncPos(X, Y); | ||||||
|  |             } else if (SpriteState == 2) { | ||||||
|  |                 Y -= 1; | ||||||
|  |                 SyncPos(X, Y); | ||||||
|  |             } | ||||||
|  |             SpriteState = State; | ||||||
|  |             Sprite.SetFrame(FrameList[SpriteState]); | ||||||
|  |             Sprite.SetPosition(0, 0); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Proc(Dt) { | ||||||
|  |         //不可用 | ||||||
|  |         if (State == 3) { | ||||||
|  | 
 | ||||||
|  |         } else { | ||||||
|  |             //按下 | ||||||
|  |             if (isLBDown) { | ||||||
|  |                 State = 2; | ||||||
|  |             } | ||||||
|  |             //悬停 | ||||||
|  |             else if (isInRect) { | ||||||
|  |                 State = 1; | ||||||
|  |             } | ||||||
|  |             //普通 | ||||||
|  |             else { | ||||||
|  |                 State = 0; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         ChangeFrame(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,60 @@ | ||||||
|  | sqr/Core/ENUM/ENUM_KEY.nut | ||||||
|  | sqr/Core/ENUM/enum_system.nut | ||||||
|  | sqr/Core/BaseTool/BaseTool.nut | ||||||
|  | sqr/Core/BaseTool/Math.nut | ||||||
|  | sqr/Core/BaseTool/String.nut | ||||||
|  | sqr/Core/BaseTool/BlobExClass.nut | ||||||
|  | sqr/Core/BaseTool/JsonClass/JsonClass.nut | ||||||
|  | sqr/Core/BaseTool/JsonClass/Json.nut | ||||||
|  | sqr/Core/BaseClass/ScriptManager/ScriptManager.nut | ||||||
|  | sqr/Core/BaseClass/ScriptManager/InitAni.nut | ||||||
|  | sqr/Core/BaseClass/Game_Window_Class.nut | ||||||
|  | sqr/Core/BaseClass/BaseObject.nut | ||||||
|  | sqr/Core/BaseClass/AudioClass.nut | ||||||
|  | sqr/Core/BaseClass/StageClass.nut | ||||||
|  | sqr/Core/BaseClass/ActorObject.nut | ||||||
|  | sqr/Core/BaseClass/UserStorage.nut | ||||||
|  | sqr/Core/BaseClass/SpriteObject/SpriteFrameClass.nut | ||||||
|  | sqr/Core/BaseClass/SpriteObject/SpriteClass.nut | ||||||
|  | sqr/Core/BaseClass/TextObject/Font.nut | ||||||
|  | sqr/Core/BaseClass/TextObject/TextActor.nut | ||||||
|  | sqr/Core/BaseClass/AnimationClass/AnimationClass.nut | ||||||
|  | 
 | ||||||
|  | sqr/Core/ExtraCalss/Socket/Socket.nut | ||||||
|  | 
 | ||||||
|  | sqr/Core/Game_Proc/Game_Proc.nut | ||||||
|  | 
 | ||||||
|  | sqr/Core/UI_Class/UI_Core.nut | ||||||
|  | sqr/Core/UI_Class/UI_Widget.nut | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | sqr/User/_ENUM/enum_game.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/Socket/Socket.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/Asset/AssetManager.nut | ||||||
|  | sqr/User/Asset/FontAsset.nut | ||||||
|  | sqr/User/Object/StateMachine/StateMachineClass.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/Object/Object/BaseObject.nut | ||||||
|  | sqr/User/Object/Object/AnimationObject.nut | ||||||
|  | sqr/User/Object/Map/TileObject.nut | ||||||
|  | sqr/User/Object/Map/MapObject.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/Object/ActiveObject/StaticObjectClass.nut | ||||||
|  | sqr/User/Object/ActiveObject/ActiveObjectClass.nut | ||||||
|  | sqr/User/Object/ActiveObject/PassiveObjectClass.nut | ||||||
|  | sqr/User/Object/ActiveObject/MonsterObjectClass.nut | ||||||
|  | sqr/User/Object/ActiveObject/CharacterObjectClass.nut | ||||||
|  | sqr/User/Object/ActiveObject/CharacterObjectClass_AI.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/Socket/Socket.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/Stage/LodingStage.nut | ||||||
|  | sqr/User/Stage/TestStage.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/UI/Widget/InputBox.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/UI/Window/0_Login.nut | ||||||
|  | 
 | ||||||
|  | sqr/User/main.nut | ||||||
|  | @ -0,0 +1,123 @@ | ||||||
|  | /* | ||||||
|  | 文件名:AssetManager.nut | ||||||
|  | 路径:User/Asset/AssetManager.nut | ||||||
|  | 创建日期:2024-11-24	08:44 | ||||||
|  | 文件用途: 资源管理器 | ||||||
|  | */ | ||||||
|  | class _AssetManager_ { | ||||||
|  | 
 | ||||||
|  |     //角色列表 | ||||||
|  |     CharacterList = null; | ||||||
|  |     //角色信息表 | ||||||
|  |     CharacterInfoList = null; | ||||||
|  |     //地图列表 | ||||||
|  |     MapList = null; | ||||||
|  | 
 | ||||||
|  |     function InitMapList() { | ||||||
|  |         MapList = ScriptData.GetFileData("map/map.lst", function(DataTable, Data) { | ||||||
|  |             while (!Data.Eof()) { | ||||||
|  |                 local Key = Data.Get(); | ||||||
|  |                 DataTable.rawset(Key, Data.Get()); | ||||||
|  |             } | ||||||
|  |             if (_DEBUG_) print("加载地图List完成, 共" + DataTable.len() + "个"); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function InitCharacter() { | ||||||
|  |         CharacterList = ScriptData.GetFileData("character/character.lst", function(DataTable, Data) { | ||||||
|  |             local dirpath = DataTable.filepath.slice(0, DataTable.filepath.lastfind("/") + 1); | ||||||
|  |             while (!Data.Eof()) { | ||||||
|  |                 local Index = Data.Get(); | ||||||
|  |                 local Path = Data.Get(); | ||||||
|  |                 DataTable.rawset(Index, dirpath + Path.tolower()); | ||||||
|  |             } | ||||||
|  |             if (_DEBUG_) print("加载角色List完成, 共" + DataTable.len() + "个"); | ||||||
|  |         }); | ||||||
|  |         CharacterInfoList = []; | ||||||
|  |         foreach(Index, Path in CharacterList) { | ||||||
|  |             if (Index == "filepath") continue; | ||||||
|  |             local Info = ScriptData.GetFileData(Path, function(DataTable, Data) { | ||||||
|  |                 local dirpath = DataTable.filepath.slice(0, DataTable.filepath.lastfind("/") + 1); | ||||||
|  |                 while (!Data.Eof()) { | ||||||
|  |                     local Key = Data.Get(); | ||||||
|  |                     if (Key == "[job]") { | ||||||
|  |                         DataTable.job <- Data.Get().slice(1, -1); | ||||||
|  |                     } else if (Key == "[growtype name]") { | ||||||
|  |                         DataTable.growtype <- array(6, {}); | ||||||
|  |                         for (local i = 0; i< 5; i++) { | ||||||
|  |                             local name = Data.Get(); | ||||||
|  |                             DataTable.growtype[i].name <- name; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     //基础属性 | ||||||
|  |                     else if (Key == "[HP MAX]]" || Key == "[MP MAX]]" || Key == "[physical attack]]" || Key == "[physical defense]]" || Key == "[magical attack]]" || Key == "[magical defense]]" || Key == "[inventory limit]]" || Key == "[MP regen speed]]" || Key == "[move speed]]" || Key == "[attack speed]]" || Key == "[cast speed]]" || Key == "[hit recovery]]" || Key == "[jump power]]" || Key == "[weight]]" || Key == "[jump speed]]") { | ||||||
|  |                         local RealKey = Key.slice(1, Key.len() - 1); | ||||||
|  |                         DataTable[RealKey] <- Data.Get().tofloat(); | ||||||
|  | 
 | ||||||
|  |                     } | ||||||
|  |                     //基础Ani | ||||||
|  |                     else if (Key == "[waiting motion]" || Key == "[move motion]" || Key == "[sit motion]" || Key == "[damage motion 1]" || Key == "[damage motion 2]" || Key == "[down motion]" || Key == "[overturn motion]" || Key == "[jump motion]" || Key == "[jumpattack motion]" || Key == "[rest motion]" || Key == "[throw motion 1-1]" || Key == "[throw motion 1-2]" || Key == "[throw motion 2-1]" || Key == "[throw motion 2-2]" || Key == "[throw motion 3-1]" || Key == "[throw motion 3-2]" || Key == "[throw motion 4-1]" || Key == "[throw motion 4-2]" || Key == "[dash motion]" || Key == "[dashattack motion]" || Key == "[getitem motion]" || Key == "[buff motion]" || Key == "[simple rest motion]" || Key == "[simple move motion]" || Key == "[back motion]") { | ||||||
|  |                         local RealKey = Key.slice(1, Key.len() - 1); | ||||||
|  |                         DataTable[RealKey] <- dirpath + Data.Get().tolower(); | ||||||
|  |                     } | ||||||
|  |                     //普攻Ani | ||||||
|  |                     else if (Key == "[attack motion]") { | ||||||
|  |                         DataTable.attack_motion <- []; | ||||||
|  |                         while (true) { | ||||||
|  |                             local Ret = Data.Get(); | ||||||
|  |                             if (Ret == "[/attack motion]") break; | ||||||
|  |                             DataTable.attack_motion.append(dirpath + Ret.tolower()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     //进阶Ani | ||||||
|  |                     else if (Key == "[etc motion]") { | ||||||
|  |                         DataTable.etc_motion <- []; | ||||||
|  |                         while (true) { | ||||||
|  |                             local Ret = Data.Get(); | ||||||
|  |                             if (Ret == "[/etc motion]") break; | ||||||
|  |                             DataTable.etc_motion.append(dirpath + Ret.tolower()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     //基础Atk | ||||||
|  |                     else if (Key == "[jumpattack info]" || Key == "[dashattack info]") { | ||||||
|  |                         local RealKey = Key.slice(1, Key.len() - 1); | ||||||
|  |                         DataTable[RealKey] <- (dirpath + Data.Get().tolower()); | ||||||
|  |                     } | ||||||
|  |                     //普攻Atk | ||||||
|  |                     else if (Key == "[attack info]") { | ||||||
|  |                         DataTable.attack_info <- []; | ||||||
|  |                         while (true) { | ||||||
|  |                             local Ret = Data.Get(); | ||||||
|  |                             if (Ret == "[/attack info]") break; | ||||||
|  |                             DataTable.attack_info.append(dirpath + Ret.tolower()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     //进阶Atk | ||||||
|  |                     else if (Key == "[etc attack info]") { | ||||||
|  |                         DataTable.etc_attack_info <- []; | ||||||
|  |                         while (true) { | ||||||
|  |                             local Ret = Data.Get(); | ||||||
|  |                             if (Ret == "[/etc attack info]") break; | ||||||
|  |                             DataTable.etc_attack_info.append(dirpath + Ret.tolower()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 // print(DataTable); | ||||||
|  |                 if (_DEBUG_) print("初始化角色" + DataTable.job); | ||||||
|  |             }); | ||||||
|  |             CharacterInfoList.push(Info); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         //初始化地图列表 | ||||||
|  |         InitMapList(); | ||||||
|  |         //初始化角色 | ||||||
|  |         InitCharacter(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         getroottable().AssetManager <- this; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,36 @@ | ||||||
|  | /* | ||||||
|  | 文件名:FontAsset.nut | ||||||
|  | 路径:User/Asset/FontAsset.nut | ||||||
|  | 创建日期:2024-12-10	11:37 | ||||||
|  | 文件用途: | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | class _FontAssetManager_ { | ||||||
|  | 
 | ||||||
|  |     //初始化字体 | ||||||
|  |     function InitFont() { | ||||||
|  |         //普通宋体小字 | ||||||
|  |         Font.PreLoad("Fonts/GasinamuNew.ttf"); | ||||||
|  |         Font("gasinamuM", 11.5).Register(0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  | 
 | ||||||
|  |         //初始化字体 | ||||||
|  |         InitFont(); | ||||||
|  | 
 | ||||||
|  |         getroottable().FontAssetManager <- this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //生成普通宋体小字 | ||||||
|  |     function GenerateNormal(text, rgba, stroke) { | ||||||
|  |         //登录按钮文本 | ||||||
|  |         local TextActor = TextActor(0, { | ||||||
|  |             color = rgba | ||||||
|  |         }); | ||||||
|  |         TextActor.SetText(text); | ||||||
|  |         if (stroke) | ||||||
|  |             TextActor.SetOutline(3.0); | ||||||
|  |         return TextActor; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,197 @@ | ||||||
|  | /* | ||||||
|  | 文件名:ActiveObjectClass.nut | ||||||
|  | 路径:User/Object/ActiveObject/ActiveObjectClass.nut | ||||||
|  | 创建日期:2024-11-29	23:05 | ||||||
|  | 文件用途:动态Obj对象 | ||||||
|  | */ | ||||||
|  | class ActiveObject extends BaseObject { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     Info = null; | ||||||
|  |     //动画组 | ||||||
|  |     AnimationArr = null; | ||||||
|  |     //攻击信息组 | ||||||
|  |     AttackinfoArr = null; | ||||||
|  |     //当前动画 | ||||||
|  |     CurrentAni = null; | ||||||
|  |     //当前攻击信息 | ||||||
|  |     Attackinfo = null; | ||||||
|  |     //图层信息 | ||||||
|  |     Layer = null; | ||||||
|  |     //状态机 | ||||||
|  |     StateMachine = null; | ||||||
|  |     //状态信息包 | ||||||
|  |     StateVar = null; | ||||||
|  |     //受击框 | ||||||
|  |     DamageBox = null; | ||||||
|  |     //攻击框 | ||||||
|  |     AttackBox = null; | ||||||
|  | 
 | ||||||
|  |     //队伍 | ||||||
|  |     Team = 0; | ||||||
|  | 
 | ||||||
|  |     //各方向加速度 | ||||||
|  |     XSpeed = 0; | ||||||
|  |     YSpeed = 0; | ||||||
|  |     ZSpeed = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function Init(Info) { | ||||||
|  |         //如果存在Ani 初始化所有Ani | ||||||
|  |         if ("animotion" in Info) { | ||||||
|  |             AnimationArr = []; | ||||||
|  |             foreach(_index, path in Info.animotion) { | ||||||
|  |                 local AniBuf = Animation(path); | ||||||
|  |                 // AniBuf.ShowBorder(true); | ||||||
|  |                 AnimationArr.append(AniBuf); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         //如果存在Atk 初始化所有Atk | ||||||
|  |         if ("attackinfo" in Info) { | ||||||
|  |             AttackinfoArr = []; | ||||||
|  |             foreach(_index, path in Info.attackinfo) { | ||||||
|  |                 local AtkBuf = AttackInfo(path); | ||||||
|  |                 AttackinfoArr.append(AtkBuf); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //动态对象 绑定状态机 | ||||||
|  |         StateMachine = FiniteStateMachineClass(); | ||||||
|  |         //增加状态信息包 | ||||||
|  |         StateVar = {}; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置Ani | ||||||
|  |     function SetAnimation(Ani) { | ||||||
|  |         //如果已经有Ani了 | ||||||
|  |         if (CurrentAni) { | ||||||
|  |             Removechild(CurrentAni); | ||||||
|  |         } | ||||||
|  |         if (type(Ani) == "integer") { | ||||||
|  |             CurrentAni = AnimationArr[Ani]; | ||||||
|  |         } else { | ||||||
|  |             CurrentAni = Ani; | ||||||
|  |         } | ||||||
|  |         //重置Ani | ||||||
|  |         CurrentAni.Reset(); | ||||||
|  |         //绑定状态机 | ||||||
|  |         CurrentAni.BindenvStateMachine(StateMachine); | ||||||
|  |         Addchild(CurrentAni); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置Atk | ||||||
|  |     function SetAttackinfo(Idx) { | ||||||
|  |         Attackinfo = AttackinfoArr[Idx]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 设置状态 | ||||||
|  |      * @参数 gState 将要设置的状态 | ||||||
|  |      */ | ||||||
|  |     function SetState(gState) { | ||||||
|  |         //调用状态机设定状态 | ||||||
|  |         return StateMachine.ChangeState(gState); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 获取状态 | ||||||
|  |      */ | ||||||
|  |     function GetState() { | ||||||
|  |         //调用状态机设定状态 | ||||||
|  |         return StateMachine.State; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //同步碰撞框 | ||||||
|  |     function SyncObjectBox() { | ||||||
|  |         //同步受击框 和 攻击框 | ||||||
|  |         DamageBox = null; | ||||||
|  |         AttackBox = null; | ||||||
|  |         //当前有Ani存在则同步 此处为怪物和被动对象的碰撞框同步逻辑 角色类override | ||||||
|  |         if (CurrentAni) { | ||||||
|  |             local Info = CurrentAni.GetCurrentFrameInfo(); | ||||||
|  |             if (Info.DamageBox.len() > 0) { | ||||||
|  |                 DamageBox = []; | ||||||
|  |                 foreach(Box in Info.DamageBox) { | ||||||
|  |                     local NewBox = [Box[0] + X, Box[1] + Y, Box[2] + Z, Box[3] + X, Box[4] + Y, Box[5] + Z]; | ||||||
|  |                     DamageBox.append(NewBox); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if (Info.AttackBox.len() > 0) { | ||||||
|  |                 AttackBox = []; | ||||||
|  |                 foreach(Box in Info.AttackBox) { | ||||||
|  |                     local NewBox = [Box[0] + X, Box[1] + Y, Box[2] + Z, Box[3] + X, Box[4] + Y, Box[5] + Z]; | ||||||
|  |                     AttackBox.append(NewBox); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 设置附着速度 | ||||||
|  |      */ | ||||||
|  |     function SetSpeed(Type, Value) { | ||||||
|  |         switch (Type) { | ||||||
|  |             case 0: | ||||||
|  |                 XSpeed = Value; | ||||||
|  |                 break; | ||||||
|  |             case 1: | ||||||
|  |                 YSpeed = Value; | ||||||
|  |                 break; | ||||||
|  |             case 2: | ||||||
|  |                 ZSpeed = Value; | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |      * @函数作用: 设置附着速度 | ||||||
|  |      */ | ||||||
|  |     function SetXSpeedWithDirection(gSpeed) { | ||||||
|  |         if (Direction == 0) | ||||||
|  |             SetSpeed(0, -gSpeed); | ||||||
|  |         else | ||||||
|  |             SetSpeed(0, gSpeed); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //计算自身加速度 | ||||||
|  |     function CalculateAcceleration(dt) { | ||||||
|  |         if (XSpeed != 0 || YSpeed != 0 || ZSpeed != 0) { | ||||||
|  |             MoveBy(XSpeed * dt * 0.001, YSpeed * dt * 0.001, ZSpeed * dt * 0.001); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnUpdate(dt) { | ||||||
|  |         //同步碰撞框 | ||||||
|  |         SyncObjectBox(); | ||||||
|  |         //状态机 | ||||||
|  |         StateMachine.OnUpdate(dt); | ||||||
|  |         //计算自身加速度 | ||||||
|  |         CalculateAcceleration(dt); | ||||||
|  | 
 | ||||||
|  |         base.OnUpdate(dt); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //攻击到其他对象时 | ||||||
|  |     function OnAttack(Damager) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     //销毁自身 | ||||||
|  |     function DestroySelf() { | ||||||
|  |         getroottable().CurrentMap.RemoveObject(this); | ||||||
|  |         base.DestroySelf(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //基于自身召唤Obj | ||||||
|  |     function CreatePassiveObject(Id, Offset_X, Offset_Y, Offset_Z, Pack) { | ||||||
|  |         local objbuf = PassiveObject(); | ||||||
|  |         objbuf.Init(Id); | ||||||
|  |         objbuf.SetPosition(X + Offset_X, Y + Offset_Y, Z + Offset_Z); | ||||||
|  |         objbuf.StateVar = Pack; | ||||||
|  |         objbuf.Team = Team; | ||||||
|  |         getroottable().CurrentMap.AddObject(objbuf); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,332 @@ | ||||||
|  | /* | ||||||
|  | 文件名:CharacterObjectClass.nut | ||||||
|  | 路径:User/GameClass/ObjectClass/CharacterObjectClass.nut | ||||||
|  | 创建日期:2024-05-11	21:03 | ||||||
|  | 文件用途:角色类 | ||||||
|  | */ | ||||||
|  | class Character extends ActiveObject { | ||||||
|  | 
 | ||||||
|  |     hair = null; //头部 | ||||||
|  |     cap = null; //帽子 | ||||||
|  |     face = null; //脸部 | ||||||
|  |     neck = null; //胸部 | ||||||
|  |     coat = null; //上衣 | ||||||
|  |     skin = null; //皮肤 | ||||||
|  |     belt = null; //腰部 | ||||||
|  |     pants = null; //下装 | ||||||
|  |     shoes = null; //鞋子 | ||||||
|  |     weapon = null; //武器 | ||||||
|  | 
 | ||||||
|  |     //当前动画组 | ||||||
|  |     CurrentAni = null; | ||||||
|  | 
 | ||||||
|  |     //等待Ani | ||||||
|  |     WaitingAni = null; | ||||||
|  |     //移动Ani | ||||||
|  |     MoveAni = null; | ||||||
|  |     //蹲下Ani | ||||||
|  |     SitAni = null; | ||||||
|  |     //受伤Ani | ||||||
|  |     DamageAni1 = null; | ||||||
|  |     DamageAni2 = null; | ||||||
|  |     //倒地Ani | ||||||
|  |     DownAni = null; | ||||||
|  |     //被击后退Ani | ||||||
|  |     OverturnAni = null; | ||||||
|  |     //跳跃Ani | ||||||
|  |     JumoAni = null; | ||||||
|  |     //跳跃攻击Ani | ||||||
|  |     JumpAttackAni = null; | ||||||
|  |     //站立Ani | ||||||
|  |     RestAni = null; | ||||||
|  |     //引导Ani | ||||||
|  |     ThrowAni1_1 = null; | ||||||
|  |     ThrowAni1_2 = null; | ||||||
|  |     ThrowAni2_1 = null; | ||||||
|  |     ThrowAni2_2 = null; | ||||||
|  |     ThrowAni3_1 = null; | ||||||
|  |     ThrowAni3_2 = null; | ||||||
|  |     ThrowAni4_1 = null; | ||||||
|  |     ThrowAni4_2 = null; | ||||||
|  |     //奔跑Ani | ||||||
|  |     DashAni = null; | ||||||
|  |     //奔跑攻击Ani | ||||||
|  |     DashAttackAni = null; | ||||||
|  |     //拾取Ani | ||||||
|  |     GetItemAni = null; | ||||||
|  |     //释放BUFFAni | ||||||
|  |     BuffAni = null; | ||||||
|  |     //普通攻击Ani | ||||||
|  |     AttackAni = null; | ||||||
|  | 
 | ||||||
|  |     //属性对象 | ||||||
|  |     Attribute = null; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function Init(Idx) { | ||||||
|  |         //初始化动画组 | ||||||
|  |         CurrentAni = []; | ||||||
|  |         //获取角色职业信息 | ||||||
|  |         Info = sq_DeepCopy(AssetManager.CharacterInfoList[Idx]); | ||||||
|  |         base.Init(Info); | ||||||
|  | 
 | ||||||
|  |   | ||||||
|  |         //初始化基础Ani | ||||||
|  |         InitBaseAni(); | ||||||
|  | 
 | ||||||
|  |         //构造属性对象 | ||||||
|  |         // Attribute = AttributeClass(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function SyncObjectBox() { | ||||||
|  |         //同步受击框 和 攻击框 | ||||||
|  |         DamageBox = null; | ||||||
|  |         AttackBox = null; | ||||||
|  |         //皮肤同步受击框 武器同步攻击框 | ||||||
|  |         foreach(AniObj in CurrentAni) { | ||||||
|  |             if (AniObj.Type == "skin") { | ||||||
|  |                 local Info = AniObj.GetCurrentFrameInfo(); | ||||||
|  |                 if (Info.DamageBox.len() > 0) { | ||||||
|  |                     DamageBox = []; | ||||||
|  |                     foreach(Box in Info.DamageBox) { | ||||||
|  |                         local NewBox = [Box[0] + X, Box[1] + Y, Box[2] + Z, Box[3] + X, Box[4] + Y, Box[5] + Z]; | ||||||
|  |                         DamageBox.append(NewBox); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } else if (AniObj.Type == "weapon") { | ||||||
|  |                 local Info = AniObj.GetCurrentFrameInfo(); | ||||||
|  |                 if (Info.AttackBox.len() > 0) { | ||||||
|  |                     AttackBox = []; | ||||||
|  |                     foreach(Box in Info.AttackBox) { | ||||||
|  |                         local NewBox = [Box[0] + X, Box[1] + Y, Box[2] + Z, Box[3] + X, Box[4] + Y, Box[5] + Z]; | ||||||
|  |                         AttackBox.append(NewBox); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // function OnUpdate(dt) { | ||||||
|  |     //     //原始逻辑 | ||||||
|  |     //     base.OnUpdate(dt); | ||||||
|  |     // } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     //设置Ani | ||||||
|  |     function SetAnimation(Ani) { | ||||||
|  |         //因为是Ani组所以要foreach调用 | ||||||
|  |         //如果已经有Ani了 | ||||||
|  |         if (CurrentAni) { | ||||||
|  |             foreach(AniObj in CurrentAni) { | ||||||
|  |                 Removechild(AniObj); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (type(Ani) == "integer") { | ||||||
|  |             //TODO 进阶ANI | ||||||
|  |         } else { | ||||||
|  |             CurrentAni = Ani; | ||||||
|  |         } | ||||||
|  |         //重置Ani 并添加子对象 | ||||||
|  |         foreach(AniObj in CurrentAni) { | ||||||
|  |             AniObj.Reset(); | ||||||
|  |             Addchild(AniObj); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function FormatAvatarAniImgPath(AniInfo, FormatValue1, FormatValue2) { | ||||||
|  |         for (local i = 0; i< AniInfo.Frame.len(); i++) { | ||||||
|  |             AniInfo.Frame[i].Img_Path = format(AniInfo.Frame[i].Img_Path, FormatValue1, FormatValue2); | ||||||
|  |         } | ||||||
|  |         return AniInfo; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function ReadAndSetAni(AniObj, Src) { | ||||||
|  |         //如果有这个标签Ani则初始化 | ||||||
|  |         if (Info.rawin(Src)) Src = Info[Src]; | ||||||
|  |         else return; | ||||||
|  | 
 | ||||||
|  |         //如果Ani组不存在就初始化数组 | ||||||
|  |         if (this[AniObj] == null) this[AniObj] = []; | ||||||
|  | 
 | ||||||
|  |         foreach(Type in getconsttable().AvatarType) { | ||||||
|  |             //如果有时装就初始化Ani | ||||||
|  |             //除了皮肤 在没有的情况下初始化0 | ||||||
|  |             if (Type == "skin") { | ||||||
|  |                 local SkinAni; | ||||||
|  |                 if (this[Type] == null) { | ||||||
|  |                     local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src)); | ||||||
|  |                     local Ao = { | ||||||
|  |                         ImgVariation = [0, 0], | ||||||
|  |                         ImgFormat = function(ImgPath) { | ||||||
|  |                             if (ImgVariation[0] > 0) { | ||||||
|  |                                 local Pos = ImgPath.find("%04d"); | ||||||
|  |                                 ImgPath = ImgPath.slice(0, Pos) + "%02d%02d" + ImgPath.slice(Pos + 4); | ||||||
|  |                                 return format(ImgPath, ImgVariation[0], ImgVariation[1]); | ||||||
|  |                             } else { | ||||||
|  |                                 return format(ImgPath, ImgVariation[1]); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     SkinAni = Animation(BufInfo, Ao); | ||||||
|  |                 } else { | ||||||
|  |                     local AvaInfo = ScriptData.GetEquipment(this[Type]); | ||||||
|  |                     local JobInfo = AvaInfo["Ani_" + Info["job"]]; | ||||||
|  |                     local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src)); | ||||||
|  |                     local Ao = { | ||||||
|  |                         ImgVariation = JobInfo["variation"], | ||||||
|  |                         ImgFormat = function(ImgPath) { | ||||||
|  |                             if (ImgVariation[0] > 0) { | ||||||
|  |                                 local Pos = ImgPath.find("%04d"); | ||||||
|  |                                 ImgPath = ImgPath.slice(0, Pos) + "%02d%02d" + ImgPath.slice(Pos + 4); | ||||||
|  |                                 return format(ImgPath, ImgVariation[0], ImgVariation[1]); | ||||||
|  |                             } else { | ||||||
|  |                                 return format(ImgPath, ImgVariation[1]); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     SkinAni = Animation(BufInfo, Ao); | ||||||
|  |                 } | ||||||
|  |                 //如果是皮肤Ani 绑定状态机 确保唯一性 | ||||||
|  |                 SkinAni.BindenvStateMachine(StateMachine); | ||||||
|  |                 //将Ani类型设置为皮肤 | ||||||
|  |                 SkinAni.Type = "skin"; | ||||||
|  |                 //加入组 | ||||||
|  |                 this[AniObj].append(SkinAni); | ||||||
|  |             } else { | ||||||
|  |                 if (this[Type] != null) { | ||||||
|  | 
 | ||||||
|  |                     local AvaInfo = ScriptData.GetEquipment(this[Type]); | ||||||
|  |                     local JobInfo = AvaInfo["Ani_" + Info["job"]]; | ||||||
|  |                     foreach(_index, value in JobInfo["layer_variation"]) { | ||||||
|  |                         local BufInfo = sq_DeepCopy(ScriptData.GetAni(AvaInfo["DirPath"] + value["Path"] + Src.slice(Src.find("/")))); | ||||||
|  |                         local Ao = { | ||||||
|  |                             ImgVariation = JobInfo["variation"], | ||||||
|  |                             ImgFormat = function(ImgPath) { | ||||||
|  |                                 return format(ImgPath, ImgVariation[0], ImgVariation[1]); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         local AniBuf = Animation(BufInfo, Ao); | ||||||
|  |                         //设置Ani类型 | ||||||
|  |                         AniBuf.Type = Type; | ||||||
|  |                         AniBuf.SetZOrder(value["Zorder"]); | ||||||
|  |                         this[AniObj].append(AniBuf); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function ReadAndSetAttackAni() { | ||||||
|  |         local AttackAniArrSrc = Info["attack_motion"]; | ||||||
|  |         AttackAni = array(AttackAniArrSrc.len()); | ||||||
|  |         foreach(_Index, Path in AttackAniArrSrc) { | ||||||
|  |             local Src = Path; | ||||||
|  |             AttackAni[_Index] = []; | ||||||
|  |             foreach(Type in getconsttable().AvatarType) { | ||||||
|  |                 //如果有时装就初始化Ani | ||||||
|  |                 //除了皮肤 在没有的情况下初始化0 | ||||||
|  |                 if (Type == "skin") { | ||||||
|  |                     local SkinAni; | ||||||
|  |                     if (this[Type] == null) { | ||||||
|  |                         local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src)); | ||||||
|  |                         local Ao = { | ||||||
|  |                             ImgVariation = [0, 0], | ||||||
|  |                             ImgFormat = function(ImgPath) { | ||||||
|  |                                 if (ImgVariation[0] > 0) { | ||||||
|  |                                     local Pos = ImgPath.find("%04d"); | ||||||
|  |                                     ImgPath = ImgPath.slice(0, Pos) + "%02d%02d" + ImgPath.slice(Pos + 4); | ||||||
|  |                                     return format(ImgPath, ImgVariation[0], ImgVariation[1]); | ||||||
|  |                                 } else { | ||||||
|  |                                     return format(ImgPath, ImgVariation[1]); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         SkinAni = Animation(BufInfo, Ao); | ||||||
|  |                     } else { | ||||||
|  |                         local AvaInfo = ScriptData.GetEquipment(this[Type]); | ||||||
|  |                         local JobInfo = AvaInfo["Ani_" + Info["job"]]; | ||||||
|  |                         local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src)); | ||||||
|  |                         local Ao = { | ||||||
|  |                             ImgVariation = JobInfo["variation"], | ||||||
|  |                             ImgFormat = function(ImgPath) { | ||||||
|  |                                 return format(ImgPath, ImgVariation[0], ImgVariation[1]); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         SkinAni = Animation(BufInfo, Ao); | ||||||
|  |                     } | ||||||
|  |                     //如果是皮肤Ani 绑定状态机 确保唯一性 | ||||||
|  |                     SkinAni.BindenvStateMachine(StateMachine); | ||||||
|  |                     //将Ani类型设置为皮肤 | ||||||
|  |                     SkinAni.Type = "skin"; | ||||||
|  |                     //加入组 | ||||||
|  |                     AttackAni[_Index].append(SkinAni); | ||||||
|  |                 } else { | ||||||
|  |                     if (this[Type] != null) { | ||||||
|  | 
 | ||||||
|  |                         local AvaInfo = ScriptData.GetEquipment(this[Type]); | ||||||
|  |                         local JobInfo = AvaInfo["Ani_" + Info["job"]]; | ||||||
|  |                         foreach(_index, value in JobInfo["layer_variation"]) { | ||||||
|  |                             local BufInfo = sq_DeepCopy(ScriptData.GetAni(AvaInfo["DirPath"] + value["Path"] + Src.slice(Src.find("/")))); | ||||||
|  |                             local Ao = { | ||||||
|  |                                 ImgVariation = JobInfo["variation"], | ||||||
|  |                                 ImgFormat = function(ImgPath) { | ||||||
|  |                                     return format(ImgPath, ImgVariation[0], ImgVariation[1]); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                             local AniBuf = Animation(BufInfo, Ao); | ||||||
|  |                             //设置Ani类型 | ||||||
|  |                             AniBuf.Type = Type; | ||||||
|  |                             AniBuf.SetZOrder(value["Zorder"]); | ||||||
|  |                             AttackAni[_Index].append(AniBuf); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function InitBaseAni() { | ||||||
|  |         //读取并设置 等待Ani | ||||||
|  |         ReadAndSetAni("WaitingAni", "waiting motion"); | ||||||
|  |         //读取并设置 移动Ani | ||||||
|  |         ReadAndSetAni("MoveAni", "move motion"); | ||||||
|  |         //读取并设置 蹲下Ani | ||||||
|  |         ReadAndSetAni("SitAni", "sit motion"); | ||||||
|  |         //读取并设置 受伤Ani | ||||||
|  |         ReadAndSetAni("DamageAni1", "damage motion 1"); | ||||||
|  |         //读取并设置 受伤Ani | ||||||
|  |         ReadAndSetAni("DamageAni2", "damage motion 2"); | ||||||
|  |         //读取并设置 倒地Ani | ||||||
|  |         ReadAndSetAni("DownAni", "down motion"); | ||||||
|  |         //读取并设置 被击后退Ani | ||||||
|  |         ReadAndSetAni("OverturnAni", "overturn motion"); | ||||||
|  |         //读取并设置 跳跃Ani | ||||||
|  |         ReadAndSetAni("JumoAni", "jump motion"); | ||||||
|  |         //读取并设置 跳跃攻击Ani | ||||||
|  |         ReadAndSetAni("JumpAttackAni", "jumpattack motion"); | ||||||
|  |         //读取并设置 站立Ani | ||||||
|  |         ReadAndSetAni("RestAni", "rest motion"); | ||||||
|  |         //读取并设置 引导Ani | ||||||
|  |         ReadAndSetAni("ThrowAni1_1", "throw motion 1-1"); | ||||||
|  |         ReadAndSetAni("ThrowAni1_2", "throw motion 1-2"); | ||||||
|  |         ReadAndSetAni("ThrowAni2_1", "throw motion 2-1"); | ||||||
|  |         ReadAndSetAni("ThrowAni2_2", "throw motion 2-2"); | ||||||
|  |         ReadAndSetAni("ThrowAni3_1", "throw motion 3-1"); | ||||||
|  |         ReadAndSetAni("ThrowAni3_2", "throw motion 3-2"); | ||||||
|  |         ReadAndSetAni("ThrowAni4_1", "throw motion 4-1"); | ||||||
|  |         ReadAndSetAni("ThrowAni4_2", "throw motion 4-2"); | ||||||
|  |         //读取并设置 奔跑Ani | ||||||
|  |         ReadAndSetAni("DashAni", "dash motion"); | ||||||
|  |         //读取并设置 奔跑攻击Ani | ||||||
|  |         ReadAndSetAni("DashAttackAni", "dashattack motion"); | ||||||
|  |         //读取并设置 拾取Ani | ||||||
|  |         ReadAndSetAni("GetItemAni", "getitem motion"); | ||||||
|  |         //读取并设置 释放BUFFAni | ||||||
|  |         ReadAndSetAni("BuffAni", "buff motion"); | ||||||
|  |         //读取并设置 AttackAni | ||||||
|  |         ReadAndSetAttackAni(); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,73 @@ | ||||||
|  | /* | ||||||
|  | 文件名:AiCharacterObjectClass.nut | ||||||
|  | 路径:User/GameClass/ObjectClass/AiCharacterObjectClass.nut | ||||||
|  | 创建日期:2024-05-14	10:05 | ||||||
|  | 文件用途:APC | ||||||
|  | */ | ||||||
|  | class AICharacter extends Character { | ||||||
|  | 
 | ||||||
|  |     //职业 | ||||||
|  |     Job = null; | ||||||
|  |     //APC编号 | ||||||
|  |     Id = null; | ||||||
|  | 
 | ||||||
|  |     function Init(Idx) { | ||||||
|  | 
 | ||||||
|  |         Id = Idx; | ||||||
|  |         Info = sq_DeepCopy(ScriptData.GetAICharacter(Idx)); | ||||||
|  |         //因为Info会被重新赋值 这里copy一下 下面读取属性要用 | ||||||
|  |         local ScriptInfo = sq_DeepCopy(Info); | ||||||
|  | 
 | ||||||
|  |         Job = ScriptInfo["minimum info"][1]; | ||||||
|  | 
 | ||||||
|  |         //根据脚本穿上装备 | ||||||
|  |         ReloadEquipment(); | ||||||
|  | 
 | ||||||
|  |         //根据职业构造基础角色  注意这一步会直接重新赋值Info | ||||||
|  |         base.Init(Job); | ||||||
|  | 
 | ||||||
|  |         //加载脚本属性 | ||||||
|  |         Attribute.Init(ScriptInfo.Attributes, this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //重载装备 | ||||||
|  |     function ReloadEquipment() { | ||||||
|  |         // Util.PrintTable(Info); | ||||||
|  |         for (local i = 0; i< Info["equipment"].len(); i += 3) { | ||||||
|  |             local EquiId = Info["equipment"][i]; | ||||||
|  |             local EquiInfo = ScriptData.GetEquipment(EquiId); | ||||||
|  | 
 | ||||||
|  |             if (EquiInfo.type.path == "skin avatar") skin = Info["equipment"][i]; | ||||||
|  |             else if (EquiInfo.type.path == "weapon") weapon = Info["equipment"][i]; | ||||||
|  |             else if (EquiInfo.type.path == "cap avatar") cap = Info["equipment"][i]; | ||||||
|  |             else if (EquiInfo.type.path == "hair avatar") hair = Info["equipment"][i]; | ||||||
|  |             else if (EquiInfo.type.path == "coat avatar") coat = Info["equipment"][i]; | ||||||
|  |             else if (EquiInfo.type.path == "pants avatar") pants = Info["equipment"][i]; | ||||||
|  |             else if (EquiInfo.type.path == "shoes avatar") shoes = Info["equipment"][i]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function OnAddchild(Parent) { | ||||||
|  |         if (getroottable().AiCharacterObjectFunction.rawin("AiCharacterObject_Create_" + Id)) | ||||||
|  |             getroottable().AiCharacterObjectFunction["AiCharacterObject_Create_" + Id](this, Parent); | ||||||
|  |         base.OnAddchild(Parent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnRemove(Parent) { | ||||||
|  |         if (getroottable().AiCharacterObjectFunction.rawin("AiCharacterObject_Destroy_" + Id)) | ||||||
|  |             getroottable().AiCharacterObjectFunction["AiCharacterObject_Destroy_" + Id](this, Parent); | ||||||
|  |         base.OnRemove(Parent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //被调用 | ||||||
|  |     function OnUpdate(dt) { | ||||||
|  |         //如果有APC的Proc脚本则调用 | ||||||
|  |         if (getroottable().AiCharacterObjectFunction.rawin("AiCharacterObject_Proc_" + Id)) | ||||||
|  |             getroottable().AiCharacterObjectFunction["AiCharacterObject_Proc_" + Id](this, dt); | ||||||
|  |         //属性更新 | ||||||
|  |         if (Attribute) Attribute.Proc(this, dt); | ||||||
|  | 
 | ||||||
|  |         base.OnUpdate(dt); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,62 @@ | ||||||
|  | /* | ||||||
|  | 文件名:MonsterObjectClass.nut | ||||||
|  | 路径:User/GameClass/ObjectClass/MonsterObjectClass.nut | ||||||
|  | 创建日期:2024-05-10	19:40 | ||||||
|  | 文件用途:怪物对象类 | ||||||
|  | */ | ||||||
|  | class Monster extends ActiveObject { | ||||||
|  | 
 | ||||||
|  |     Attackinfo = null; | ||||||
|  |     //怪物Id | ||||||
|  |     Id = null; | ||||||
|  | 
 | ||||||
|  |     //属性表 | ||||||
|  |     Attribute = null; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function Init(Idx) { | ||||||
|  |         Id = Idx; | ||||||
|  |         Info = ScriptData.GetMonster(Idx); | ||||||
|  | 
 | ||||||
|  |         base.Init(Info); | ||||||
|  | 
 | ||||||
|  |         //构造属性对象 | ||||||
|  |         Attribute = AttributeClass(); | ||||||
|  |         //加载脚本属性 | ||||||
|  |         Attribute.Init(Info.Attributes, this); | ||||||
|  | 
 | ||||||
|  |         //如果存在Atk 初始化所有Atk | ||||||
|  |         if ("attackinfo" in Info) { | ||||||
|  |             Attackinfo = []; | ||||||
|  |             foreach(_index, path in Info.attackinfo) { | ||||||
|  |                 // local AniBuf = Animation(path); | ||||||
|  |                 // AniBuf.ShowBorder(true); | ||||||
|  |                 Attackinfo.append(path); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnAddchild(Parent) { | ||||||
|  |         getroottable().MonsterObjectFunction["MonsterObject_Create_" + Id](this, Parent); | ||||||
|  |         base.OnAddchild(Parent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnRemove(Parent) { | ||||||
|  |         getroottable().MonsterObjectFunction["MonsterObject_Destroy_" + Id](this, Parent); | ||||||
|  |         base.OnRemove(Parent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //被调用 | ||||||
|  |     function OnUpdate(dt) { | ||||||
|  |         //调用怪物Proc状态 | ||||||
|  |         getroottable().MonsterObjectFunction["MonsterObject_Proc_" + Id](this, dt); | ||||||
|  |         //属性更新 | ||||||
|  |         if (Attribute) Attribute.Proc(this, dt); | ||||||
|  |         //原始逻辑 | ||||||
|  |         base.OnUpdate(dt); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,56 @@ | ||||||
|  | /* | ||||||
|  | 文件名:PassiveObjectClass.nut | ||||||
|  | 路径:User/GameClass/ObjectClass/PassiveObjectClass.nut | ||||||
|  | 创建日期:2024-05-11	09:14 | ||||||
|  | 文件用途:被动对象 | ||||||
|  | */ | ||||||
|  | class PassiveObject extends ActiveObject { | ||||||
|  | 
 | ||||||
|  |     OnCreateFunction = null; | ||||||
|  |     OnProcFunction = null; | ||||||
|  |     OnDestroyFunction = null; | ||||||
|  |     OnAttackFunction = null; | ||||||
|  | 
 | ||||||
|  |     function Init(Idx) { | ||||||
|  |         Info = ScriptData.GetPassiveObject(Idx); | ||||||
|  | 
 | ||||||
|  |         base.Init(Info); | ||||||
|  | 
 | ||||||
|  |         //储存图层信息 | ||||||
|  |         if ("layer" in Info) | ||||||
|  |             Layer = Info.layer.slice(1, -1); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         //初始化回调函数 | ||||||
|  |         InitCallBackFunc(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function InitCallBackFunc() { | ||||||
|  |         if ("create function" in Info) OnCreateFunction = Info["create function"].bindenv(this); | ||||||
|  |         if ("destroy function" in Info) OnDestroyFunction = Info["destroy function"].bindenv(this); | ||||||
|  |         if ("proc function" in Info) OnProcFunction = Info["proc function"].bindenv(this); | ||||||
|  |         if ("attack function" in Info) OnAttackFunction = Info["attack function"].bindenv(this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnAddchild(Parent) { | ||||||
|  |         if (OnCreateFunction) OnCreateFunction(Parent); | ||||||
|  |         base.OnAddchild(Parent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function OnRemove(Parent) { | ||||||
|  |         if (OnDestroyFunction) OnDestroyFunction(Parent); | ||||||
|  |         base.OnRemove(Parent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //攻击到其他对象时 | ||||||
|  |     function OnAttack(Damager) { | ||||||
|  |         if (OnAttackFunction) OnAttackFunction(Damager); | ||||||
|  |         base.OnAttack(Damager); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //被调用 | ||||||
|  |     function OnUpdate(dt) { | ||||||
|  |         if (OnProcFunction) OnProcFunction(dt); | ||||||
|  |         base.OnUpdate(dt); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,15 @@ | ||||||
|  | /* | ||||||
|  | 文件名:StaticObjectClass.nut | ||||||
|  | 路径:GameClass/ObjectClass/StaticObjectClass.nut | ||||||
|  | 创建日期:2024-05-09	22:28 | ||||||
|  | 文件用途:静态Obj对象 | ||||||
|  | */ | ||||||
|  | class StaticObject extends BaseObject { | ||||||
|  | 
 | ||||||
|  |     AniObject = null; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function Init() { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,246 @@ | ||||||
|  | /* | ||||||
|  | 文件名:MapObject.nut | ||||||
|  | 路径:User/Object/Map/MapObject.nut | ||||||
|  | 创建日期:2024-11-22	19:40 | ||||||
|  | 文件用途:地图对象 | ||||||
|  | */ | ||||||
|  | class Map extends Actor { | ||||||
|  |     //图层对象Map | ||||||
|  |     LayerObject = null; | ||||||
|  | 
 | ||||||
|  |     //地图编号 | ||||||
|  |     m_mapId = 0; | ||||||
|  |     //数据 | ||||||
|  |     m_data = null; | ||||||
|  | 
 | ||||||
|  |     //地图长度 | ||||||
|  |     m_length = 0; | ||||||
|  | 
 | ||||||
|  |     //初始化图层对象 | ||||||
|  |     function InitLayer() { | ||||||
|  |         //图层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.closeback.SetZOrder(FristOrder); | ||||||
|  |         FristOrder += 50000; | ||||||
|  |         LayerObject.close.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); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     //初始化数据 | ||||||
|  |     function InitData(path) { | ||||||
|  |         m_data = ScriptData.GetFileData(path, function(DataTable, Data) { | ||||||
|  |             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 == "[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 <- []; | ||||||
|  |                     while (true) { | ||||||
|  |                         local areadata = Data.Get(); | ||||||
|  |                         if (areadata == "[/town movable area]") break; | ||||||
|  |                         local info = []; | ||||||
|  |                         info.push(areadata); | ||||||
|  |                         for (local i = 0; i< 5; i++) { | ||||||
|  |                             info.push(Data.Get()) | ||||||
|  |                         } | ||||||
|  |                         DataTable.town_movable_area.push(info); | ||||||
|  |                     } | ||||||
|  |                 } else if (str == "[virtual movable area]") { | ||||||
|  |                     DataTable.virtual_movable_area <- []; | ||||||
|  |                     while (true) { | ||||||
|  |                         local areadata = Data.Get(); | ||||||
|  |                         if (areadata == "[/virtual movable area]") break; | ||||||
|  |                         local info = []; | ||||||
|  |                         info.push(areadata); | ||||||
|  |                         for (local i = 0; i< 3; i++) { | ||||||
|  |                             info.push(Data.Get()) | ||||||
|  |                         } | ||||||
|  |                         DataTable.virtual_movable_area.push(info); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         m_data.path <- path; | ||||||
|  |         m_data.dirpath <- path.slice(0, path.lastfind("/") + 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //初始化地板 | ||||||
|  |     function InitTile() { | ||||||
|  |         //普通地板 | ||||||
|  |         if ("tile" in m_data) { | ||||||
|  |             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, 0); | ||||||
|  |                 LayerObject.bottom.Addchild(TileObj); | ||||||
|  |                 //计算地图长度 | ||||||
|  |                 m_length += 224; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         //补充地板 | ||||||
|  |         if ("extended_tile" in m_data) { | ||||||
|  |             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 * 224, 560); | ||||||
|  |                 LayerObject.bottom.Addchild(TileObj); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //初始化背景动画 | ||||||
|  |     function InitBackgroundAnimation() { | ||||||
|  |         //背景动画 | ||||||
|  |         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< width; 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, m_data.background_pos); | ||||||
|  |                     LayerObject[Info.layer].Addchild(ani); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //初始化场景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); | ||||||
|  |             //注意这里默认要增加120的Y轴偏移 | ||||||
|  |             if (info.layer != "normal") AniObj.SetPositionNoLayer(info.xpos, info.ypos + m_data.background_pos + 120, info.zpos); | ||||||
|  |             else AniObj.SetPosition(info.xpos, info.ypos + m_data.background_pos + 120, info.zpos); | ||||||
|  |             LayerObject[info.layer].Addchild(AniObj); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     constructor(arg) { | ||||||
|  |         base.constructor(); | ||||||
|  | 
 | ||||||
|  |         if (typeof arg == "integer") { | ||||||
|  | 
 | ||||||
|  |         } else if (typeof arg == "string") { | ||||||
|  |             InitData(arg); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //初始化图层 | ||||||
|  |         InitLayer(); | ||||||
|  | 
 | ||||||
|  |         //初始化地板 | ||||||
|  |         InitTile(); | ||||||
|  |         //初始化背景动画 | ||||||
|  |         InitBackgroundAnimation(); | ||||||
|  |         //初始化场景Ani | ||||||
|  |         InitAnimation(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,45 @@ | ||||||
|  | /* | ||||||
|  | 文件名:TileObject.nut | ||||||
|  | 路径:User/Object/Map/TileObject.nut | ||||||
|  | 创建日期:2024-11-28	23:17 | ||||||
|  | 文件用途:地板类 | ||||||
|  | */ | ||||||
|  | class Tile extends CL_SpriteObject { | ||||||
|  | 
 | ||||||
|  |     m_data = null; | ||||||
|  | 
 | ||||||
|  |     function InitData(path) { | ||||||
|  |         m_data = ScriptData.GetFileData(path, function(DataTable, Data) { | ||||||
|  |             while (!Data.Eof()) { | ||||||
|  |                 local Pack = Data.Get(); | ||||||
|  |                 if (Pack == "[IMAGE]") { | ||||||
|  |                     local PathBuf = Data.Get().tolower(); | ||||||
|  |                     if (PathBuf.len() > 0) { | ||||||
|  |                         DataTable.path <- "sprite/" + PathBuf; | ||||||
|  |                         DataTable.idx <- Data.Get(); | ||||||
|  |                     } | ||||||
|  |                 } else if (Pack == "[img pos]") { | ||||||
|  |                     DataTable.pos <- Data.Get(); | ||||||
|  |                 } else if (Pack == "[pass type]") { | ||||||
|  |                     DataTable.pass_type <- []; | ||||||
|  |                     while (!Data.Eof()) { | ||||||
|  |                         DataTable.pass_type.push(Data.Get()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     constructor(arg) { | ||||||
|  |         if (typeof arg == "integer") { | ||||||
|  | 
 | ||||||
|  |         } else if (typeof arg == "string") { | ||||||
|  |             InitData(arg); | ||||||
|  |             if ("path" in m_data) | ||||||
|  |                 base.constructor(m_data.path, m_data.idx); | ||||||
|  |             else { | ||||||
|  |                 base.constructor("sprite/character/common/circlecooltime.img", 27); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | /* | ||||||
|  | 文件名:AnimationObject.nut | ||||||
|  | 路径:User/Object/Object/AnimationObject.nut | ||||||
|  | 创建日期:2024-11-29	10:36 | ||||||
|  | 文件用途:动画对象 | ||||||
|  | */ | ||||||
|  | class AnimationObject extends BaseObject { | ||||||
|  | 
 | ||||||
|  |     //动画对象 | ||||||
|  |     m_Animation = null; | ||||||
|  | 
 | ||||||
|  |     constructor(args) { | ||||||
|  |         base.constructor(); | ||||||
|  | 
 | ||||||
|  |         if (typeof args == "string") { | ||||||
|  |             m_Animation = Animation(args); | ||||||
|  |             m_Animation.SetAnchor(0.0, 0.0); | ||||||
|  |             Addchild(m_Animation); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,110 @@ | ||||||
|  | /* | ||||||
|  | 文件名:BaseObject.nut | ||||||
|  | 路径:User/Object/Object/BaseObject.nut | ||||||
|  | 创建日期:2024-11-29	10:32 | ||||||
|  | 文件用途: | ||||||
|  | */ | ||||||
|  | class BaseObject extends Actor { | ||||||
|  | 
 | ||||||
|  |     //方向 | ||||||
|  |     Direction = 1; | ||||||
|  | 
 | ||||||
|  |     //坐标 | ||||||
|  |     X = 0; | ||||||
|  |     Y = 0; | ||||||
|  |     Z = 0; | ||||||
|  | 
 | ||||||
|  |     constructor(...) { | ||||||
|  |         local C_Object; | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             C_Object = BaseObject_Create(); | ||||||
|  |         } else { | ||||||
|  |             C_Object = vargv[0]; | ||||||
|  |         } | ||||||
|  |         base.constructor(C_Object); | ||||||
|  |         //锚点居中 | ||||||
|  |         SetAnchor(0.5, 0.5); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function SetPositionNoLayer(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             X = Value.x; | ||||||
|  |             Y = Value.y; | ||||||
|  |             Z = Value.z; | ||||||
|  |             Value.y = Value.y - Value.z; | ||||||
|  |             base.SetPosition(Value); | ||||||
|  |         } else if (vargv.len() == 2) { | ||||||
|  |             X = Value; | ||||||
|  |             Y = vargv[0]; | ||||||
|  |             Z = vargv[1]; | ||||||
|  |             base.SetPosition(Value, vargv[0] - vargv[1]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //override | ||||||
|  |     function SetPosition(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             X = Value.x; | ||||||
|  |             Y = Value.y; | ||||||
|  |             Z = Value.z; | ||||||
|  |             Value.y = Value.y - Value.z; | ||||||
|  |             base.SetPosition(Value); | ||||||
|  |         } else if (vargv.len() == 2) { | ||||||
|  |             X = Value; | ||||||
|  |             Y = vargv[0]; | ||||||
|  |             Z = vargv[1]; | ||||||
|  |             base.SetPosition(Value, vargv[0] - vargv[1]); | ||||||
|  |         } | ||||||
|  |         SetZOrder(Y); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //传入坐标 xyz 的table  或者 单独传 xyz | ||||||
|  |     function MoveTo(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             X = Value.x; | ||||||
|  |             Y = Value.y; | ||||||
|  |             Z = Value.z; | ||||||
|  |             Value.y = Value.y - Value.z; | ||||||
|  |             base.MoveTo(Value); | ||||||
|  |         } else if (vargv.len() == 2) { | ||||||
|  |             X = Value; | ||||||
|  |             Y = vargv[0]; | ||||||
|  |             Z = vargv[1]; | ||||||
|  |             base.MoveTo(Value, vargv[0] - vargv[1]); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //传入坐标 xyz 的table  或者 单独传 xyz | ||||||
|  |     function MoveBy(Value, ...) { | ||||||
|  |         if (vargv.len() == 0) { | ||||||
|  |             X += Value.x; | ||||||
|  |             Y += Value.y; | ||||||
|  |             Z += Value.z; | ||||||
|  |             Value.y = Value.y - Value.z; | ||||||
|  |             base.MoveBy(Value); | ||||||
|  |         } else if (vargv.len() == 2) { | ||||||
|  |             X += Value; | ||||||
|  |             Y += vargv[0]; | ||||||
|  |             Z += vargv[1]; | ||||||
|  |             base.MoveBy(Value, vargv[0] - vargv[1]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //设置方向 | ||||||
|  |     function SetDirection(D) { | ||||||
|  |         if (D == DIRECTION.RIGHT) { | ||||||
|  |             SetScale(fabs(GetScale().x), GetScale().y); | ||||||
|  |         } else if (D == DIRECTION.LEFT) { | ||||||
|  |             SetScale(-fabs(GetScale().x), GetScale().y); | ||||||
|  |         } | ||||||
|  |         Direction = D; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //销毁自身 | ||||||
|  |     function DestroySelf() { | ||||||
|  |         RemoveSelf(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,126 @@ | ||||||
|  | /* | ||||||
|  | 文件名:StateMachineClass.nut | ||||||
|  | 路径:User/Object/StateMachine/StateMachineClass.nut | ||||||
|  | 创建日期:2024-11-29	23:14 | ||||||
|  | 文件用途:状态机 | ||||||
|  | */ | ||||||
|  | class FiniteStateMachineClass { | ||||||
|  | 
 | ||||||
|  |     //状态 | ||||||
|  |     State = -1; | ||||||
|  |     //状态时间 | ||||||
|  |     StateTime = 0; | ||||||
|  | 
 | ||||||
|  |     //状态注册组 | ||||||
|  |     StateFuncArr = null; | ||||||
|  |     //条件注册组 | ||||||
|  |     ConditionStateArr = null; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         //初始化 | ||||||
|  |         StateFuncArr = {}; | ||||||
|  |         //初始化 | ||||||
|  |         ConditionStateArr = {}; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //状态检查 | ||||||
|  |     function OnCheck(gState) { | ||||||
|  |         if ("OnCheck" in StateFuncArr[gState]) { | ||||||
|  |             local Flag = StateFuncArr[gState].OnCheck(); | ||||||
|  |             if (Flag) return Flag; | ||||||
|  |             else return false; | ||||||
|  |         } else return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //状态进入 | ||||||
|  |     function OnStart() { | ||||||
|  |         if ("OnStart" in StateFuncArr[State]) StateFuncArr[State].OnStart(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //状态退出 | ||||||
|  |     function OnEnd() { | ||||||
|  |         if ("OnEnd" in StateFuncArr[State]) StateFuncArr[State].OnEnd(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //状态中全帧 | ||||||
|  |     function OnProc(dt) { | ||||||
|  |         if ("OnProc" in StateFuncArr[State]) StateFuncArr[State].OnProc(dt, StateTime); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //状态中144 | ||||||
|  |     function OnProcFrom144(MillisecondsDuration) { | ||||||
|  |         if ("OnProcCon" in StateFuncArr[State]) StateFuncArr[State].OnProcCon(MillisecondsDuration); | ||||||
|  |         foreach(Key, Func in ConditionStateArr) { | ||||||
|  |             if (Func()) ChangeState(Key); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //注册普通状态 | ||||||
|  |     function RegisterStaticState(StateIndex, T) { | ||||||
|  |         StateFuncArr.rawset(StateIndex, T); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //注册条件状态 | ||||||
|  |     function RegisterConditionState(StateIndex, Func) { | ||||||
|  |         ConditionStateArr.rawset(StateIndex, Func); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //更改状态 | ||||||
|  |     function ChangeState(StateIndex) { | ||||||
|  |         //判断有这个状态才执行 | ||||||
|  |         if (StateIndex in StateFuncArr) { | ||||||
|  |             //如果有检查 先调用检查 | ||||||
|  |             local Flag = OnCheck(StateIndex); | ||||||
|  |             //如果Flag成立 | ||||||
|  |             if (Flag) { | ||||||
|  |                 //如果自身状态不等于-1 | ||||||
|  |                 if (State != -1) { | ||||||
|  |                     //调用状态退出 | ||||||
|  |                     OnEnd(); | ||||||
|  |                 } | ||||||
|  |                 //更新状态 | ||||||
|  |                 State = StateIndex; | ||||||
|  |                 //重置状态时间 | ||||||
|  |                 StateTime = 0; | ||||||
|  | 
 | ||||||
|  |                 //调用状态进入 | ||||||
|  |                 OnStart(); | ||||||
|  |                 return true; | ||||||
|  |             } else return false; | ||||||
|  |         } else return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //Ani播放KeyFlag | ||||||
|  |     function ChangeAniKeyFlag(Index) { | ||||||
|  |         if ("OnAniKeyFlag" in StateFuncArr[State]) StateFuncArr[State].OnAniKeyFlag(Index); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //Ani播放完成回调 | ||||||
|  |     function ChangeAniEndFlag() { | ||||||
|  |         if ("OnAniEndFlag" in StateFuncArr[State]) StateFuncArr[State].OnAniEndFlag(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //攻击到目标的回调 | ||||||
|  |     function ChangeOnAttack(Damager) { | ||||||
|  |         if ("OnAttack" in StateFuncArr[State]) StateFuncArr[State].OnAttack(Damager); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //状态机持续执行函数 144帧 | ||||||
|  |     function OnUpdateFrom144(MillisecondsDuration) { | ||||||
|  |         //如果自身状态不等于-1 | ||||||
|  |         if (State != -1) { | ||||||
|  |             //状态中144 | ||||||
|  |             OnProcFrom144(MillisecondsDuration); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //状态机持续执行函数 | ||||||
|  |     function OnUpdate(dt) { | ||||||
|  |         StateTime += dt; | ||||||
|  |         //如果自身状态不等于-1 | ||||||
|  |         if (State != -1) { | ||||||
|  |             //状态中 | ||||||
|  |             OnProc(dt); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | /* | ||||||
|  | 文件名:Socket.nut | ||||||
|  | 路径:User/Socket/Socket.nut | ||||||
|  | 创建日期:2024-12-01	14:47 | ||||||
|  | 文件用途:网络通信 | ||||||
|  | */ | ||||||
|  | class MySocket extends Socket { | ||||||
|  | 
 | ||||||
|  |     //字符串包处理逻辑 | ||||||
|  |     PackHandler = null; | ||||||
|  |     //数据流包处理逻辑 | ||||||
|  |     PackBinaryHandler = null; | ||||||
|  | 
 | ||||||
|  |     State = 0; | ||||||
|  | 
 | ||||||
|  |     constructor(Ip, Port) { | ||||||
|  |         //初始化处理逻辑Map | ||||||
|  |         PackHandler = {}; | ||||||
|  |         PackBinaryHandler = {}; | ||||||
|  | 
 | ||||||
|  |         //先执行父类的构造函数 | ||||||
|  |         base.constructor(); | ||||||
|  | 
 | ||||||
|  |         //绑定回调函数 | ||||||
|  |         BindFunc(SOCKET_CALLBACK_TYPE.onConnect, function() { | ||||||
|  |             State = 1; | ||||||
|  |         }.bindenv(this)); | ||||||
|  |         BindFunc(SOCKET_CALLBACK_TYPE.onReceive, function(PacketId, Str) { | ||||||
|  |             //如果存在对应处理逻辑 | ||||||
|  |             if (PackHandler.rawin(PacketId)) { | ||||||
|  |                 //将字符画序列化json | ||||||
|  |                 local Jso = Json.Decode(Str); | ||||||
|  |                 PackHandler[PacketId](Jso); | ||||||
|  |             } | ||||||
|  |         }.bindenv(this)); | ||||||
|  |         BindFunc(SOCKET_CALLBACK_TYPE.onReceiveBinary, function(PacketId, Blob_Obj) { | ||||||
|  |             //如果存在对应处理逻辑 | ||||||
|  |             if (PackBinaryHandler.rawin(PacketId)) { | ||||||
|  |                 PackBinaryHandler[PacketId](Blob_Obj); | ||||||
|  |             } | ||||||
|  |         }.bindenv(this)); | ||||||
|  | 
 | ||||||
|  |         Connect(Ip, Port, false); | ||||||
|  |         //注册自己到全局 | ||||||
|  |         getroottable()._MySocket_ <- this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //注册字符串包处理逻辑 | ||||||
|  |     function RegisterHandler(PacketId, Func) { | ||||||
|  |         getroottable()._MySocket_.PackHandler.rawset(PacketId, Func); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //注册数据流包处理逻辑 | ||||||
|  |     function RegisterBinaryHandler(PacketId, Func) { | ||||||
|  |         getroottable()._MySocket_.PackBinaryHandler.rawset(PacketId, Func); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //发包 | ||||||
|  |     function Send(PacketId, Jso) { | ||||||
|  |         //将json序列化字符串 | ||||||
|  |         local Str = Json.Encode(Jso); | ||||||
|  |         Socket_SendPacket(getroottable()._MySocket_.Client, PacketId, Str); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,66 @@ | ||||||
|  | /* | ||||||
|  | 文件名:LodingStage.nut | ||||||
|  | 路径:User/Stage/LodingStage.nut | ||||||
|  | 创建日期:2024-12-10	12:11 | ||||||
|  | 文件用途: 加载界面 | ||||||
|  | */ | ||||||
|  | function InitGame() { | ||||||
|  |     //初始化Socekt连接 | ||||||
|  |     // MySocket("192.168.200.24", 19666); | ||||||
|  |     MySocket("127.0.0.1", 19666); | ||||||
|  | 
 | ||||||
|  |     //设定全局默认音量 | ||||||
|  |     _Globa_Audio_Volume_ = 0.1; | ||||||
|  | 
 | ||||||
|  |     Script(); | ||||||
|  | 
 | ||||||
|  |     //初始化资产管理器 | ||||||
|  |     _AssetManager_(); | ||||||
|  |     //初始化字体 | ||||||
|  |     _FontAssetManager_(); | ||||||
|  | 
 | ||||||
|  |     //进入下一个场景 | ||||||
|  |     TestStage(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function LoginStage() { | ||||||
|  |     local T = CL_StageObject(); | ||||||
|  |     T.SetName("加载界面舞台"); | ||||||
|  | 
 | ||||||
|  |     local AniTime = 100; | ||||||
|  | 
 | ||||||
|  |     //大背景 | ||||||
|  |     local BackGround = CL_SpriteObject("sprite/loding.img", 0); | ||||||
|  |     T.Addchild(BackGround); | ||||||
|  | 
 | ||||||
|  |     //Kiwano图标 | ||||||
|  |     local Kiwano = CL_SpriteObject("sprite/loding.img", 1); | ||||||
|  |     Kiwano.SetAnchor(0.5, 0.5); | ||||||
|  |     Kiwano.SetScale(0.35, 0.35); | ||||||
|  |     Kiwano.SetPosition(1066 / 2, 800); | ||||||
|  |     Kiwano.SetUpdateFunc(function(sp, dt) { | ||||||
|  |         if (!("time" in sp.Var)) sp.Var.time <- 0; | ||||||
|  |         sp.Var.time += dt; | ||||||
|  |         local rate = Math.sq_GetAccel(100, 0, sp.Var.time, AniTime, true); | ||||||
|  |         sp.SetOpacity(rate / 100.0); | ||||||
|  |     }); | ||||||
|  |     T.Addchild(Kiwano); | ||||||
|  | 
 | ||||||
|  |     //Yosin图标 | ||||||
|  |     local Yosin = CL_SpriteObject("sprite/loding.img", 2); | ||||||
|  |     Yosin.SetAnchor(0.5, 0.5); | ||||||
|  |     Yosin.SetPosition(1066 / 2, 300); | ||||||
|  |     Yosin.SetOpacity(0.0); | ||||||
|  |     Yosin.SetUpdateFunc(function(sp, dt) { | ||||||
|  |         if (!("time" in sp.Var)) sp.Var.time <- 0; | ||||||
|  |         sp.Var.time += dt; | ||||||
|  |         local rate = Math.getUniformVelocity(0, 100, sp.Var.time - AniTime, AniTime); | ||||||
|  |         sp.SetOpacity(rate / 100.0); | ||||||
|  |         if (rate == 100) { | ||||||
|  |             InitGame(); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |     T.Addchild(Yosin); | ||||||
|  | 
 | ||||||
|  |     T.Enter(); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | /* | ||||||
|  | 文件名:TestStage.nut | ||||||
|  | 路径:User/Stage/TestStage.nut | ||||||
|  | 创建日期:2024-11-24	08:37 | ||||||
|  | 文件用途:测试场景 | ||||||
|  | */ | ||||||
|  | function TestStage() { | ||||||
|  |     local T = CL_StageObject(); | ||||||
|  |     T.SetName("测试舞台"); | ||||||
|  |     T.Enter(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     // local Window = Sq_CreateWindow(_Login_Window, "启动界面窗口", 0, 0, 288, 512, 0); | ||||||
|  |     // Window.ResetFocus(); | ||||||
|  | 
 | ||||||
|  |     // local Fontobj = Font(); | ||||||
|  | 
 | ||||||
|  |     local MapObj = Map("map/cataclysm/town/elvengard/new_elvengard.map"); | ||||||
|  |     // local MapObj = Map("map/cataclysm/town/seria_room/elvengard.map"); | ||||||
|  |     // local MapObj = Map("map/cataclysm/town/sainthorn_heaven/sainthorn_heaven_ship_rear_down.map"); | ||||||
|  |     T.Addchild(MapObj); | ||||||
|  | 
 | ||||||
|  |     local Charc = Character(); | ||||||
|  |     Charc.Init(0); | ||||||
|  |     Charc.SetPosition(356, 430, 0); | ||||||
|  |     Charc.SetAnimation(Charc.RestAni); | ||||||
|  |     Charc.SetZOrder(99999999); | ||||||
|  |     MapObj.Addchild(Charc); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,109 @@ | ||||||
|  | /* | ||||||
|  | 文件名:InputBox.nut | ||||||
|  | 路径:User/UI/Widget/InputBox.nut | ||||||
|  | 创建日期:2024-12-02	09:55 | ||||||
|  | 文件用途:输入框 | ||||||
|  | */ | ||||||
|  | //基础按钮 | ||||||
|  | class Yosin_InputBox extends Yosin_CommonUi { | ||||||
|  |     //状态 | ||||||
|  |     State = 0; | ||||||
|  |     //是否焦点 | ||||||
|  |     IsFocus = false; | ||||||
|  |     //内容 | ||||||
|  |     str = ""; | ||||||
|  |     sliceCode = "|"; | ||||||
|  | 
 | ||||||
|  |     InputController = null; | ||||||
|  | 
 | ||||||
|  |     //宽度 | ||||||
|  |     DWidth = 0; | ||||||
|  | 
 | ||||||
|  |     //文本对象 | ||||||
|  |     Text_Obj = null; | ||||||
|  |     //Path | ||||||
|  |     Path = "sprite/interface/lenheartwindowcommon.img"; | ||||||
|  | 
 | ||||||
|  |     constructor(X, Y, W) { | ||||||
|  |         this.DWidth = W; | ||||||
|  | 
 | ||||||
|  |         base.constructor(X, Y, W, 20); | ||||||
|  |         local FillCount = DWidth; | ||||||
|  | 
 | ||||||
|  |         local HeaderSp = CL_SpriteObject(Path, 63); | ||||||
|  |         Addchild(HeaderSp); | ||||||
|  |         for (local i = 0; i< FillCount; i++) { | ||||||
|  |             local MiddleSp = CL_SpriteObject(Path, 64); | ||||||
|  |             MiddleSp.SetPosition(i + 3, 0); | ||||||
|  |             Addchild(MiddleSp); | ||||||
|  |         } | ||||||
|  |         local TailSp = CL_SpriteObject(Path, 65); | ||||||
|  |         TailSp.SetPosition(FillCount + 3, 0); | ||||||
|  |         Addchild(TailSp); | ||||||
|  | 
 | ||||||
|  |         Text_Obj = TextActor(0, { | ||||||
|  |             color = 0xFFFFFFFF | ||||||
|  |         }); | ||||||
|  |         Text_Obj.SetPosition(4, 3); | ||||||
|  |         Addchild(Text_Obj); | ||||||
|  | 
 | ||||||
|  |         _Imm_Input_Func_.rawset(C_Object, Imm_Input.bindenv(this)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //闪烁时间 | ||||||
|  |     FlushTime = 0; | ||||||
|  | 
 | ||||||
|  |     function SliceCodeFlicker(Dt) { | ||||||
|  |         FlushTime += Dt; | ||||||
|  |         if (FlushTime >= 500) { | ||||||
|  |             FlushTime = 0; | ||||||
|  |             if (sliceCode.len() > 0) sliceCode = ""; | ||||||
|  |             else if (sliceCode.len() == 0) sliceCode = "|"; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //判断是否中文字符 | ||||||
|  |     function IsChineseChar(code) { | ||||||
|  |         return (code & 0x80) != 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //接收文本数据 | ||||||
|  |     function Imm_Input(str) { | ||||||
|  |         if (!IsFocus) return; | ||||||
|  |         //退格键 | ||||||
|  |         if (str == "\b") { | ||||||
|  |             if (this.str.len() > 0) { | ||||||
|  |                 this.str = Sq_RemoveStringLast(this.str); | ||||||
|  |             } | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         this.str += str; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //同步文本对象数据 | ||||||
|  |     function SyncText() { | ||||||
|  |         Text_Obj.SetText(str + sliceCode); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function Proc(Dt) { | ||||||
|  |         if (IsFocus) SliceCodeFlicker(Dt); | ||||||
|  |         else sliceCode = ""; | ||||||
|  | 
 | ||||||
|  |         SyncText(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //鼠标左键单击回调 | ||||||
|  |     function OnMouseLbClick(MousePos_X, MousePos_Y) { | ||||||
|  |         local Pos = GetWorldPosition(); | ||||||
|  |         if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, Pos.x, Pos.y, Width, Height)) { | ||||||
|  |             if (OnClick) OnClick(this); | ||||||
|  |             IsFocus = true; | ||||||
|  |             sliceCode = "|"; | ||||||
|  |             Sq_SetImmEnabled(true); | ||||||
|  |         } else { | ||||||
|  |             IsFocus = false; | ||||||
|  |             sliceCode = ""; | ||||||
|  |             Sq_SetImmEnabled(false); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,129 @@ | ||||||
|  | /* | ||||||
|  | 文件名:0_Login.nut | ||||||
|  | 路径:User/UI/0_Login.nut | ||||||
|  | 创建日期:2024-12-01	15:13 | ||||||
|  | 文件用途:登录界面窗口 | ||||||
|  | */ | ||||||
|  | class _Login_Window extends Yosin_Window { | ||||||
|  |     //调试模式 | ||||||
|  |     // DeBugMode = true; | ||||||
|  | 
 | ||||||
|  |     //不是窗口 | ||||||
|  |     // NoWindow = true; | ||||||
|  | 
 | ||||||
|  |     //是否可见 | ||||||
|  |     // Visible = false; | ||||||
|  | 
 | ||||||
|  |     AccountInputBox = null; | ||||||
|  |     PasswordInputBox = null; | ||||||
|  | 
 | ||||||
|  |     BackGroundMusic = null; | ||||||
|  | 
 | ||||||
|  |     constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) { | ||||||
|  |         base.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH); | ||||||
|  | 
 | ||||||
|  |         //注册绘制 | ||||||
|  |         RegisterDraw(); | ||||||
|  |         //注册控件 | ||||||
|  |         RegisterWidget(); | ||||||
|  |         // OpenDeBug(); | ||||||
|  | 
 | ||||||
|  |         //播放音乐 | ||||||
|  |         PlayBackgroundMusic(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function PlayBackgroundMusic() { | ||||||
|  |         // BackGroundMusic = Sound("SoundPacks/Loop.ogg"); | ||||||
|  |         // BackGroundMusic.Play(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function MusicLogic() { | ||||||
|  |         if (BackGroundMusic == null) return; | ||||||
|  |         if (!BackGroundMusic.IsPlaying()) BackGroundMusic.Play(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function RegisterWidget() { | ||||||
|  |         //账号输入框 | ||||||
|  |         local AccountInputBox = Yosin_InputBox(752, 240, 200); | ||||||
|  |         AddUIChild(AccountInputBox); | ||||||
|  | 
 | ||||||
|  |         //密码输入框 | ||||||
|  |         local PasswordInputBox = Yosin_InputBox(752, 280, 200); | ||||||
|  |         AddUIChild(PasswordInputBox); | ||||||
|  | 
 | ||||||
|  |         //登录按钮 | ||||||
|  |         local LoginButton = Yosin_BaseButton(770, 410, 77, 24 "sprite/interface/lenheartwindowcommon.img", 90); | ||||||
|  |         //点击事件回调 | ||||||
|  |         LoginButton.OnClick = function(Button) { | ||||||
|  |             MySocket.Send(1, { | ||||||
|  |                 account = AccountInputBox.str, | ||||||
|  |                 password = PasswordInputBox.str | ||||||
|  |             }) | ||||||
|  |         }.bindenv(this); | ||||||
|  | 
 | ||||||
|  |         //登录按钮文本 | ||||||
|  |         local LoginTextActor = FontAssetManager.GenerateNormal("登录", sq_RGBA(200, 195, 169, 255), true); | ||||||
|  |         LoginTextActor.SetPosition(26, 4); | ||||||
|  |         LoginButton.Addchild(LoginTextActor); | ||||||
|  |         AddUIChild(LoginButton); | ||||||
|  | 
 | ||||||
|  |         //注册按钮 | ||||||
|  |         local RegisterButton = Yosin_BaseButton(865, 410, 77, 24 "sprite/interface/lenheartwindowcommon.img", 90); | ||||||
|  |         //点击事件回调 | ||||||
|  |         RegisterButton.OnClick = function(Button) { | ||||||
|  |             MySocket.Send(3, { | ||||||
|  |                 account = AccountInputBox.str, | ||||||
|  |                 password = PasswordInputBox.str | ||||||
|  |             }) | ||||||
|  |         }.bindenv(this); | ||||||
|  |         //注册按钮文本 | ||||||
|  |         local RegisterTextActor = FontAssetManager.GenerateNormal("注册", sq_RGBA(200, 195, 169, 255), true); | ||||||
|  |         RegisterTextActor.SetPosition(26, 4); | ||||||
|  |         RegisterButton.Addchild(RegisterTextActor); | ||||||
|  |         AddUIChild(RegisterButton); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function RegisterDraw() { | ||||||
|  |         //大背景 | ||||||
|  |         local BackGround = CL_SpriteObject("sprite/interface2/charactercreatever2/characterbackground.img", 14); | ||||||
|  |         Addchild(BackGround); | ||||||
|  |         //左上角的背景 | ||||||
|  |         local Cover = CL_SpriteObject("sprite/interface2/channel/channelselect/channelbackground/channelbackground.img", 20); | ||||||
|  |         Addchild(Cover); | ||||||
|  |         //登录框的背景 | ||||||
|  |         local LoginBoxBg = CL_SpriteObject("sprite/login_ui.img", 3); | ||||||
|  |         LoginBoxBg.SetPosition(634, 0); | ||||||
|  |         Addchild(LoginBoxBg); | ||||||
|  |         local AniObj = Animation("ui/selectcharacter/animation/selectcharactereffect.ani"); | ||||||
|  |         AniObj.SetPosition(770, 0); | ||||||
|  |         Addchild(AniObj); | ||||||
|  |         //登录游戏字体 | ||||||
|  |         local LoginText = CL_SpriteObject("sprite/login_ui.img", 0); | ||||||
|  |         LoginText.SetPosition(796, 65); | ||||||
|  |         Addchild(LoginText); | ||||||
|  |         //登录游戏说明 | ||||||
|  |         local LoginTexttip = CL_SpriteObject("sprite/login_ui.img", 1); | ||||||
|  |         LoginTexttip.SetPosition(-33, 40); | ||||||
|  |         LoginText.Addchild(LoginTexttip); | ||||||
|  | 
 | ||||||
|  |         //账号 | ||||||
|  |         local AccountTextActor = FontAssetManager.GenerateNormal("账号:", sq_RGBA(200, 195, 169, 255), false); | ||||||
|  |         AccountTextActor.SetPosition(720, 241); | ||||||
|  |         Addchild(AccountTextActor); | ||||||
|  |         //密码 | ||||||
|  |         local PasswordTextActor = FontAssetManager.GenerateNormal("密码:", sq_RGBA(200, 195, 169, 255), false); | ||||||
|  |         PasswordTextActor.SetPosition(720, 281); | ||||||
|  |         Addchild(PasswordTextActor); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //逻辑入口 | ||||||
|  |     function Proc(Dt) { | ||||||
|  |         MusicLogic(); | ||||||
|  | 
 | ||||||
|  |         SyncPos(X, Y); | ||||||
|  |         base.Proc(Dt); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,86 @@ | ||||||
|  | /* | ||||||
|  | 文件名:enum_game.nut | ||||||
|  | 路径:User/_ENUM/enum_game.nut | ||||||
|  | 创建日期:2024-11-29	23:20 | ||||||
|  | 文件用途: | ||||||
|  | 	游戏中用到的枚举表 | ||||||
|  | */ | ||||||
|  | //职业枚举表 | ||||||
|  | enum CHARACTERJOB { | ||||||
|  |     SWORDMAN | ||||||
|  |     FIGHTER | ||||||
|  |     GUNNER | ||||||
|  |     MAGE | ||||||
|  |     PRIEST | ||||||
|  |     AT_GUNNER | ||||||
|  |     THIEF | ||||||
|  |     AT_FIGHTER | ||||||
|  |     AT_MAGE | ||||||
|  |     DEMONIC_SWORDMAN | ||||||
|  |     CREATOR_MAGE | ||||||
|  |     AT_SWORDMAN | ||||||
|  |     KNIGHT | ||||||
|  |     DEMONIC_LANCER | ||||||
|  |     AT_PRIEST | ||||||
|  |     GUN_BLADER | ||||||
|  |     ARCHER | ||||||
|  |     MAX | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //时装枚举类 | ||||||
|  | enum AvatarType { | ||||||
|  |     hair = "hair" //头部 | ||||||
|  |     cap = "cap" //帽子 | ||||||
|  |     face = "face" //脸部 | ||||||
|  |     neck = "neck" //胸部 | ||||||
|  |     coat = "coat" //上衣 | ||||||
|  |     skin = "skin" //皮肤 | ||||||
|  |     belt = "belt" //腰部 | ||||||
|  |     pants = "pants" //下装 | ||||||
|  |     shoes = "shoes" //鞋子 | ||||||
|  |     weapon = "weapon" //武器 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //方向枚举表 | ||||||
|  | enum DIRECTION { | ||||||
|  |     //左 | ||||||
|  |     LEFT = 0 | ||||||
|  |     //右 | ||||||
|  |     RIGHT = 1 | ||||||
|  |     //上 | ||||||
|  |     UP = 2 | ||||||
|  |     //下 | ||||||
|  |     DOWN = 3 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //基础状态枚举表 | ||||||
|  | enum BASE_STATE { | ||||||
|  |     //站立 | ||||||
|  |     REST = 0 | ||||||
|  |     //移动 | ||||||
|  |     MOVE = 1 | ||||||
|  |     //奔跑 | ||||||
|  |     DASH = 2 | ||||||
|  |     //跳跃 | ||||||
|  |     JUMP = 3 | ||||||
|  |     //普通攻击 | ||||||
|  |     BASE_ATTACK = 4 | ||||||
|  |     //跳跃攻击 | ||||||
|  |     JUMP_ATTACK = 5 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     //受击 | ||||||
|  |     DAMAGE = 99 | ||||||
|  |     //倒地 | ||||||
|  |     DOWN = 100 | ||||||
|  |     //蹲下 | ||||||
|  |     SIT = 101 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     //引导1状态 | ||||||
|  |     THROW_1 = 601 | ||||||
|  |     //引导2状态 | ||||||
|  |     THROW_2 = 602 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,20 @@ | ||||||
|  | /* | ||||||
|  | 文件名:main.nut | ||||||
|  | 路径:User/main.nut | ||||||
|  | 创建日期:2024-11-17	08:26 | ||||||
|  | 文件用途: | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | function main(args) { | ||||||
|  |     local Game = GameWindow(); | ||||||
|  |     Game.title = "Yosin & Kiwano"; | ||||||
|  |     Game.bg_color = [255.0, 255.0, 255.0, 255.0]; | ||||||
|  |     Game.size = [1066, 600]; | ||||||
|  |     Game.v_sync = false; | ||||||
|  |     Game.frame_interval = 10000; | ||||||
|  |     Game.debug_mode = true; | ||||||
|  |     Game.Run(LoginStage); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,146 @@ | ||||||
|  | { | ||||||
|  |     "Core/BaseTool": { | ||||||
|  |         "description": "基础工具" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass": { | ||||||
|  |         "description": "基础类" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/Game_Window_Class.nut": { | ||||||
|  |         "description": "游戏窗口类" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/BaseObject.nut": { | ||||||
|  |         "description": "基础对象类" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/ActorObject.nut": { | ||||||
|  |         "description": "演员类 - Actor" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/SpriteObject": { | ||||||
|  |         "description": "精灵类 & 精灵帧类" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/StageClass.nut": { | ||||||
|  |         "description": "场景类 - Stage" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/SpriteObject/SpriteClass.nut": { | ||||||
|  |         "description": "精灵类 - Sprite" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/SpriteObject/SpriteFrameClass.nut": { | ||||||
|  |         "description": "精灵帧类 - SpriteFrame" | ||||||
|  |     }, | ||||||
|  |     "Core/UI_Class": { | ||||||
|  |         "description": "UI类" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseTool/Math.nut": { | ||||||
|  |         "description": "数学库" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/ScriptManager": { | ||||||
|  |         "description": "pvf管理" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseTool/BlobExClass.nut": { | ||||||
|  |         "description": "高级流" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/AnimationClass": { | ||||||
|  |         "description": "动画类" | ||||||
|  |     }, | ||||||
|  |     "User/Object": { | ||||||
|  |         "description": "对象类" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Bird.nut": { | ||||||
|  |         "description": "小鸟 对象" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Map.nut": { | ||||||
|  |         "description": "地图 对象" | ||||||
|  |     }, | ||||||
|  |     "Core/ENUM": { | ||||||
|  |         "description": "枚举类" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Pipes.nut": { | ||||||
|  |         "description": "管道对象" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Pipe.nut": { | ||||||
|  |         "description": "管道对象" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Score.nut": { | ||||||
|  |         "description": "分数对象" | ||||||
|  |     }, | ||||||
|  |     "User/Stage": { | ||||||
|  |         "description": "场景" | ||||||
|  |     }, | ||||||
|  |     "User/Stage/Start_Stage.nut": { | ||||||
|  |         "description": "开始场景" | ||||||
|  |     }, | ||||||
|  |     "User/Stage/Game_Stage.nut": { | ||||||
|  |         "description": "游戏场景" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Map": { | ||||||
|  |         "description": "地图类" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Map/MapObject.nut": { | ||||||
|  |         "description": "地图对象" | ||||||
|  |     }, | ||||||
|  |     "User/Asset": { | ||||||
|  |         "description": "资产" | ||||||
|  |     }, | ||||||
|  |     "User/Asset/AssetManager.nut": { | ||||||
|  |         "description": "资产管理器" | ||||||
|  |     }, | ||||||
|  |     "User/_ENUM": { | ||||||
|  |         "description": "枚举" | ||||||
|  |     }, | ||||||
|  |     "Core/ENUM/enum_system.nut": { | ||||||
|  |         "description": "系统枚举" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseTool/String.nut": { | ||||||
|  |         "description": "字符串库" | ||||||
|  |     }, | ||||||
|  |     "User/Object/Object/BaseObject.nut": { | ||||||
|  |         "description": "基础对象" | ||||||
|  |     }, | ||||||
|  |     "User/Object/ActiveObject": { | ||||||
|  |         "description": "动态对象" | ||||||
|  |     }, | ||||||
|  |     "User/Object/StateMachine": { | ||||||
|  |         "description": "状态机" | ||||||
|  |     }, | ||||||
|  |     "User/_ENUM/enum_game.nut": { | ||||||
|  |         "description": "游戏枚举" | ||||||
|  |     }, | ||||||
|  |     "Core/ExtraCalss": { | ||||||
|  |         "description": "附加类" | ||||||
|  |     }, | ||||||
|  |     "Core/ExtraCalss/Socket": { | ||||||
|  |         "description": "Socket类" | ||||||
|  |     }, | ||||||
|  |     "Core/Game_Proc": { | ||||||
|  |         "description": "底层核心处理逻辑" | ||||||
|  |     }, | ||||||
|  |     "User/Socket": { | ||||||
|  |         "description": "网络" | ||||||
|  |     }, | ||||||
|  |     "User/UI": { | ||||||
|  |         "description": "界面窗口" | ||||||
|  |     }, | ||||||
|  |     "User/UI/Window/0_Login.nut": { | ||||||
|  |         "description": "登录界面" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/TextObject": { | ||||||
|  |         "description": "文本类" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/TextObject/Font.nut": { | ||||||
|  |         "description": "字体类" | ||||||
|  |     }, | ||||||
|  |     "Core/BaseClass/TextObject/TextStyle.nut": { | ||||||
|  |         "description": "字体风格类" | ||||||
|  |     }, | ||||||
|  |     "Core/ENUM/ENUM_SYSTEM.nut": { | ||||||
|  |         "description": "系统枚举" | ||||||
|  |     }, | ||||||
|  |     "User/UI/Window": { | ||||||
|  |         "description": "窗口" | ||||||
|  |     }, | ||||||
|  |     "User/UI/Widget": { | ||||||
|  |         "description": "控件" | ||||||
|  |     }, | ||||||
|  |     "User/Asset/FontAsset.nut": { | ||||||
|  |         "description": "游戏文本资产" | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue