commit c9dcc5ffd99e0b7f5a9363f96c4af2d0cab96e13 Author: WONIU Date: Wed Dec 11 15:08:57 2024 +0800 初版 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af0be6f --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +ImagePacks2/ +SoundPacks/ +Yosin_Game_Reloading.Sign +Script.pvf +Yosin_Engine.pdb diff --git a/DevMode.ini b/DevMode.ini new file mode 100644 index 0000000..e69de29 diff --git a/Fonts/Gasinamu.ttf b/Fonts/Gasinamu.ttf new file mode 100644 index 0000000..d4f17e4 Binary files /dev/null and b/Fonts/Gasinamu.ttf differ diff --git a/Fonts/GasinamuNew.ttf b/Fonts/GasinamuNew.ttf new file mode 100644 index 0000000..7927db2 Binary files /dev/null and b/Fonts/GasinamuNew.ttf differ diff --git a/Fonts/Gothica-Book.ttf b/Fonts/Gothica-Book.ttf new file mode 100644 index 0000000..8b78034 Binary files /dev/null and b/Fonts/Gothica-Book.ttf differ diff --git a/Fonts/msjh.ttf b/Fonts/msjh.ttf new file mode 100644 index 0000000..8997148 Binary files /dev/null and b/Fonts/msjh.ttf differ diff --git a/Save/Data.sav b/Save/Data.sav new file mode 100644 index 0000000..9c845ab --- /dev/null +++ b/Save/Data.sav @@ -0,0 +1 @@ +{"HistoryBestScore":5} \ No newline at end of file diff --git a/Yosin_Engine.exe b/Yosin_Engine.exe new file mode 100644 index 0000000..b0dacbc Binary files /dev/null and b/Yosin_Engine.exe differ diff --git a/ffi-8.dll b/ffi-8.dll new file mode 100644 index 0000000..fc63a1e Binary files /dev/null and b/ffi-8.dll differ diff --git a/folder-alias.json b/folder-alias.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/folder-alias.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/sqr/Core/BaseClass/ActorObject.nut b/sqr/Core/BaseClass/ActorObject.nut new file mode 100644 index 0000000..30ed968 --- /dev/null +++ b/sqr/Core/BaseClass/ActorObject.nut @@ -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); + } + } +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/AnimationClass/AnimationClass.nut b/sqr/Core/BaseClass/AnimationClass/AnimationClass.nut new file mode 100644 index 0000000..3ec71b2 --- /dev/null +++ b/sqr/Core/BaseClass/AnimationClass/AnimationClass.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/AudioClass.nut b/sqr/Core/BaseClass/AudioClass.nut new file mode 100644 index 0000000..2bfb17e --- /dev/null +++ b/sqr/Core/BaseClass/AudioClass.nut @@ -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); +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/BaseObject.nut b/sqr/Core/BaseClass/BaseObject.nut new file mode 100644 index 0000000..d29b5e3 --- /dev/null +++ b/sqr/Core/BaseClass/BaseObject.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/Game_Window_Class.nut b/sqr/Core/BaseClass/Game_Window_Class.nut new file mode 100644 index 0000000..0f69289 --- /dev/null +++ b/sqr/Core/BaseClass/Game_Window_Class.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/ScriptManager/InitAni.nut b/sqr/Core/BaseClass/ScriptManager/InitAni.nut new file mode 100644 index 0000000..501f8ac --- /dev/null +++ b/sqr/Core/BaseClass/ScriptManager/InitAni.nut @@ -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; +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/ScriptManager/ScriptManager.nut b/sqr/Core/BaseClass/ScriptManager/ScriptManager.nut new file mode 100644 index 0000000..b75472e --- /dev/null +++ b/sqr/Core/BaseClass/ScriptManager/ScriptManager.nut @@ -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(); \ No newline at end of file diff --git a/sqr/Core/BaseClass/SpriteObject/SpriteClass.nut b/sqr/Core/BaseClass/SpriteObject/SpriteClass.nut new file mode 100644 index 0000000..86385dc --- /dev/null +++ b/sqr/Core/BaseClass/SpriteObject/SpriteClass.nut @@ -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); + } + } +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/SpriteObject/SpriteFrameClass.nut b/sqr/Core/BaseClass/SpriteObject/SpriteFrameClass.nut new file mode 100644 index 0000000..ebbd90d --- /dev/null +++ b/sqr/Core/BaseClass/SpriteObject/SpriteFrameClass.nut @@ -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); + } + +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/StageClass.nut b/sqr/Core/BaseClass/StageClass.nut new file mode 100644 index 0000000..9db1653 --- /dev/null +++ b/sqr/Core/BaseClass/StageClass.nut @@ -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); + } + +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/TextObject/Font.nut b/sqr/Core/BaseClass/TextObject/Font.nut new file mode 100644 index 0000000..abd72b0 --- /dev/null +++ b/sqr/Core/BaseClass/TextObject/Font.nut @@ -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; + } + +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/TextObject/TextActor.nut b/sqr/Core/BaseClass/TextObject/TextActor.nut new file mode 100644 index 0000000..ac6fb35 --- /dev/null +++ b/sqr/Core/BaseClass/TextObject/TextActor.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/BaseClass/UserStorage.nut b/sqr/Core/BaseClass/UserStorage.nut new file mode 100644 index 0000000..28b2c94 --- /dev/null +++ b/sqr/Core/BaseClass/UserStorage.nut @@ -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(); + } +} \ No newline at end of file diff --git a/sqr/Core/BaseTool/BaseTool.nut b/sqr/Core/BaseTool/BaseTool.nut new file mode 100644 index 0000000..a848cb5 --- /dev/null +++ b/sqr/Core/BaseTool/BaseTool.nut @@ -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; +} \ No newline at end of file diff --git a/sqr/Core/BaseTool/BlobExClass.nut b/sqr/Core/BaseTool/BlobExClass.nut new file mode 100644 index 0000000..77b583f --- /dev/null +++ b/sqr/Core/BaseTool/BlobExClass.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/BaseTool/JsonClass/Json.nut b/sqr/Core/BaseTool/JsonClass/Json.nut new file mode 100644 index 0000000..242d5e9 --- /dev/null +++ b/sqr/Core/BaseTool/JsonClass/Json.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/BaseTool/JsonClass/JsonClass.nut b/sqr/Core/BaseTool/JsonClass/JsonClass.nut new file mode 100644 index 0000000..e91ba72 --- /dev/null +++ b/sqr/Core/BaseTool/JsonClass/JsonClass.nut @@ -0,0 +1,702 @@ +/** + * JSON Parser + * + * @author Mikhail Yurasov + * @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; + } +} \ No newline at end of file diff --git a/sqr/Core/BaseTool/Math.nut b/sqr/Core/BaseTool/Math.nut new file mode 100644 index 0000000..3a4ae83 --- /dev/null +++ b/sqr/Core/BaseTool/Math.nut @@ -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); \ No newline at end of file diff --git a/sqr/Core/BaseTool/String.nut b/sqr/Core/BaseTool/String.nut new file mode 100644 index 0000000..f77d2e6 --- /dev/null +++ b/sqr/Core/BaseTool/String.nut @@ -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; + } +} \ No newline at end of file diff --git a/sqr/Core/ENUM/ENUM_KEY.nut b/sqr/Core/ENUM/ENUM_KEY.nut new file mode 100644 index 0000000..9667bb3 --- /dev/null +++ b/sqr/Core/ENUM/ENUM_KEY.nut @@ -0,0 +1,14 @@ +/* +文件名:ENUM_KEY.nut +路径:Core/ENUM/ENUM_KEY.nut +创建日期:2024-11-13 16:31 +文件用途:按键枚举 +*/ + +enum MOUSE_KEY { + LEFT, ///< 鼠标左键 + RIGHT, ///< 鼠标右键 + MIDDLE, ///< 鼠标中键 + + LAST +}; \ No newline at end of file diff --git a/sqr/Core/ENUM/ENUM_SYSTEM.nut b/sqr/Core/ENUM/ENUM_SYSTEM.nut new file mode 100644 index 0000000..226b3a5 --- /dev/null +++ b/sqr/Core/ENUM/ENUM_SYSTEM.nut @@ -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 ///< 圆角样式 +}; \ No newline at end of file diff --git a/sqr/Core/ExtraCalss/Socket/Socket.nut b/sqr/Core/ExtraCalss/Socket/Socket.nut new file mode 100644 index 0000000..4b801cc --- /dev/null +++ b/sqr/Core/ExtraCalss/Socket/Socket.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/Game_Proc/Game_Proc.nut b/sqr/Core/Game_Proc/Game_Proc.nut new file mode 100644 index 0000000..eee479a --- /dev/null +++ b/sqr/Core/Game_Proc/Game_Proc.nut @@ -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(); + } +} \ No newline at end of file diff --git a/sqr/Core/UI_Class/UI_Core.nut b/sqr/Core/UI_Class/UI_Core.nut new file mode 100644 index 0000000..16a75e8 --- /dev/null +++ b/sqr/Core/UI_Class/UI_Core.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/Core/UI_Class/UI_Widget.nut b/sqr/Core/UI_Class/UI_Widget.nut new file mode 100644 index 0000000..8541502 --- /dev/null +++ b/sqr/Core/UI_Class/UI_Widget.nut @@ -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(); + } +} \ No newline at end of file diff --git a/sqr/SquirrelFileConfig.cfg b/sqr/SquirrelFileConfig.cfg new file mode 100644 index 0000000..029caed --- /dev/null +++ b/sqr/SquirrelFileConfig.cfg @@ -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 \ No newline at end of file diff --git a/sqr/User/Asset/AssetManager.nut b/sqr/User/Asset/AssetManager.nut new file mode 100644 index 0000000..77781f4 --- /dev/null +++ b/sqr/User/Asset/AssetManager.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; + } +} \ No newline at end of file diff --git a/sqr/User/Asset/FontAsset.nut b/sqr/User/Asset/FontAsset.nut new file mode 100644 index 0000000..e91929b --- /dev/null +++ b/sqr/User/Asset/FontAsset.nut @@ -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; + } +} \ No newline at end of file diff --git a/sqr/User/Object/ActiveObject/ActiveObjectClass.nut b/sqr/User/Object/ActiveObject/ActiveObjectClass.nut new file mode 100644 index 0000000..fa525ef --- /dev/null +++ b/sqr/User/Object/ActiveObject/ActiveObjectClass.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/User/Object/ActiveObject/CharacterObjectClass.nut b/sqr/User/Object/ActiveObject/CharacterObjectClass.nut new file mode 100644 index 0000000..ac53755 --- /dev/null +++ b/sqr/User/Object/ActiveObject/CharacterObjectClass.nut @@ -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); + + // Util.PrintTable(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(); + + } +} \ No newline at end of file diff --git a/sqr/User/Object/ActiveObject/CharacterObjectClass_AI.nut b/sqr/User/Object/ActiveObject/CharacterObjectClass_AI.nut new file mode 100644 index 0000000..bd89076 --- /dev/null +++ b/sqr/User/Object/ActiveObject/CharacterObjectClass_AI.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/User/Object/ActiveObject/MonsterObjectClass.nut b/sqr/User/Object/ActiveObject/MonsterObjectClass.nut new file mode 100644 index 0000000..b6de9a6 --- /dev/null +++ b/sqr/User/Object/ActiveObject/MonsterObjectClass.nut @@ -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); + } + + +} \ No newline at end of file diff --git a/sqr/User/Object/ActiveObject/PassiveObjectClass.nut b/sqr/User/Object/ActiveObject/PassiveObjectClass.nut new file mode 100644 index 0000000..e343d18 --- /dev/null +++ b/sqr/User/Object/ActiveObject/PassiveObjectClass.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/User/Object/ActiveObject/StaticObjectClass.nut b/sqr/User/Object/ActiveObject/StaticObjectClass.nut new file mode 100644 index 0000000..4b0e606 --- /dev/null +++ b/sqr/User/Object/ActiveObject/StaticObjectClass.nut @@ -0,0 +1,15 @@ +/* +文件名:StaticObjectClass.nut +路径:GameClass/ObjectClass/StaticObjectClass.nut +创建日期:2024-05-09 22:28 +文件用途:静态Obj对象 +*/ +class StaticObject extends BaseObject { + + AniObject = null; + + + function Init() { + + } +} \ No newline at end of file diff --git a/sqr/User/Object/Map/MapObject.nut b/sqr/User/Object/Map/MapObject.nut new file mode 100644 index 0000000..fcfdbba --- /dev/null +++ b/sqr/User/Object/Map/MapObject.nut @@ -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(); + } +} \ No newline at end of file diff --git a/sqr/User/Object/Map/TileObject.nut b/sqr/User/Object/Map/TileObject.nut new file mode 100644 index 0000000..b99045a --- /dev/null +++ b/sqr/User/Object/Map/TileObject.nut @@ -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); + } + } + } +} \ No newline at end of file diff --git a/sqr/User/Object/Object/AnimationObject.nut b/sqr/User/Object/Object/AnimationObject.nut new file mode 100644 index 0000000..c1d6ff9 --- /dev/null +++ b/sqr/User/Object/Object/AnimationObject.nut @@ -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); + } + + } +} \ No newline at end of file diff --git a/sqr/User/Object/Object/BaseObject.nut b/sqr/User/Object/Object/BaseObject.nut new file mode 100644 index 0000000..5c7e53c --- /dev/null +++ b/sqr/User/Object/Object/BaseObject.nut @@ -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(); + } +} \ No newline at end of file diff --git a/sqr/User/Object/StateMachine/StateMachineClass.nut b/sqr/User/Object/StateMachine/StateMachineClass.nut new file mode 100644 index 0000000..ae376f4 --- /dev/null +++ b/sqr/User/Object/StateMachine/StateMachineClass.nut @@ -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); + } + } +} \ No newline at end of file diff --git a/sqr/User/Socket/Socket.nut b/sqr/User/Socket/Socket.nut new file mode 100644 index 0000000..d4b65dc --- /dev/null +++ b/sqr/User/Socket/Socket.nut @@ -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); + } +} \ No newline at end of file diff --git a/sqr/User/Stage/LodingStage.nut b/sqr/User/Stage/LodingStage.nut new file mode 100644 index 0000000..3d8ebf6 --- /dev/null +++ b/sqr/User/Stage/LodingStage.nut @@ -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(); +} \ No newline at end of file diff --git a/sqr/User/Stage/TestStage.nut b/sqr/User/Stage/TestStage.nut new file mode 100644 index 0000000..8a56474 --- /dev/null +++ b/sqr/User/Stage/TestStage.nut @@ -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); +} \ No newline at end of file diff --git a/sqr/User/UI/Widget/InputBox.nut b/sqr/User/UI/Widget/InputBox.nut new file mode 100644 index 0000000..6bb9009 --- /dev/null +++ b/sqr/User/UI/Widget/InputBox.nut @@ -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); + } + } +} \ No newline at end of file diff --git a/sqr/User/UI/Window/0_Login.nut b/sqr/User/UI/Window/0_Login.nut new file mode 100644 index 0000000..eaf7ec8 --- /dev/null +++ b/sqr/User/UI/Window/0_Login.nut @@ -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); + } + +} \ No newline at end of file diff --git a/sqr/User/_ENUM/enum_game.nut b/sqr/User/_ENUM/enum_game.nut new file mode 100644 index 0000000..9ea29aa --- /dev/null +++ b/sqr/User/_ENUM/enum_game.nut @@ -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 +} \ No newline at end of file diff --git a/sqr/User/main.nut b/sqr/User/main.nut new file mode 100644 index 0000000..39661f2 --- /dev/null +++ b/sqr/User/main.nut @@ -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); +} \ No newline at end of file diff --git a/sqr/folder-alias.json b/sqr/folder-alias.json new file mode 100644 index 0000000..91e4a0f --- /dev/null +++ b/sqr/folder-alias.json @@ -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": "游戏文本资产" + } +} \ No newline at end of file