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