279 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
/*
 | 
						|
文件名:AnimationClass.nut
 | 
						|
路径:Core/BaseClass/AnimationClass/AnimationClass.nut
 | 
						|
创建日期:2024-05-07	23:25
 | 
						|
文件用途:动画类
 | 
						|
*/
 | 
						|
class Animation extends CL_SpriteObject {
 | 
						|
 | 
						|
    //Ani是否可用
 | 
						|
    IsUsability = true;
 | 
						|
 | 
						|
    //当前帧数
 | 
						|
    CurrentFrameIndex = 0;
 | 
						|
    //总帧数
 | 
						|
    TotalFrameIndex = 0;
 | 
						|
    //当前帧时间
 | 
						|
    CurrentIndexT = 0;
 | 
						|
    //当前帧
 | 
						|
    CurrentFrame = null;
 | 
						|
    //下帧延迟
 | 
						|
    NextFrameDelay = 9999999;
 | 
						|
    //状态机对象(只有存在时才有KeyFlag)
 | 
						|
    StateMachine = null;
 | 
						|
 | 
						|
    //Ani的标签
 | 
						|
    AnimationFlag = null;
 | 
						|
    //帧对象数组
 | 
						|
    FrameArr = null;
 | 
						|
    //图片精灵帧对象
 | 
						|
    SpriteArr = null;
 | 
						|
 | 
						|
    //Ani类型
 | 
						|
    Type = "normal";
 | 
						|
    //Ani路径
 | 
						|
    AniPath = null;
 | 
						|
 | 
						|
    //是否描边
 | 
						|
    IsOutline = false;
 | 
						|
    //描边颜色
 | 
						|
    OutlineColor = null;
 | 
						|
    //描边对象List
 | 
						|
    OutlineList = null;
 | 
						|
    //当前描边对象
 | 
						|
    CurrentOutline = null;
 | 
						|
 | 
						|
    //附加选项
 | 
						|
    AdditionalOptions = null;
 | 
						|
 | 
						|
    function _typeof() {
 | 
						|
        return "animation";
 | 
						|
    }
 | 
						|
 | 
						|
    constructor(...) {
 | 
						|
        base.constructor();
 | 
						|
 | 
						|
        //精灵帧数组
 | 
						|
        SpriteArr = [];
 | 
						|
        //帧数组
 | 
						|
        FrameArr = [];
 | 
						|
        //描边对象List
 | 
						|
        OutlineList = [];
 | 
						|
 | 
						|
        //判断是否有特殊处理
 | 
						|
        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) {
 | 
						|
            AniPath = Buf.filepath;
 | 
						|
            AnimationFlag = Buf.Flag;
 | 
						|
            FrameArr = Buf.Frame;
 | 
						|
            foreach(FrameObj in FrameArr) {
 | 
						|
                local SpriteFramebuf;
 | 
						|
                //img路径判空
 | 
						|
                if (FrameObj.Img_Path) {
 | 
						|
                    //如果有附加处理 格式化
 | 
						|
                    if (AdditionalOptions && AdditionalOptions.rawin("ImgFormat")) FrameObj.Img_Path = AdditionalOptions["ImgFormat"](FrameObj.Img_Path);
 | 
						|
 | 
						|
                    SpriteFramebuf = CL_SpriteFrameObject("sprite/" + FrameObj.Img_Path, FrameObj.Img_Index);
 | 
						|
 | 
						|
                    //坐标
 | 
						|
                    SpriteFramebuf.SetPosition(FrameObj.Pos);
 | 
						|
                } else {
 | 
						|
                    SpriteFramebuf = CL_SpriteFrameObject("sprite/interface/base.img", 0);
 | 
						|
                }
 | 
						|
 | 
						|
 | 
						|
                SpriteArr.append(SpriteFramebuf);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            error("创建Ani失败,找不到Ani数据");
 | 
						|
        }
 | 
						|
 | 
						|
        //初始化完毕 如果是第一次初始化 而非重新构造 设置大小为第0帧大小否则天空 地板等依靠大小的初始化会有问题
 | 
						|
        if (CurrentIndexT == 0) SetSize(SpriteArr[0].GetSize());
 | 
						|
        //记录总帧数
 | 
						|
        TotalFrameIndex = FrameArr.len();
 | 
						|
    }
 | 
						|
 | 
						|
    //被添加时  要刷新一下当前帧
 | 
						|
    function OnAddchild(Parent) {
 | 
						|
        base.OnAddchild(Parent);
 | 
						|
        FlushFrame(0);
 | 
						|
    }
 | 
						|
 | 
						|
    //重置Ani
 | 
						|
    function Reset() {
 | 
						|
        IsUsability = true;
 | 
						|
        FlushFrame(0);
 | 
						|
    }
 | 
						|
 | 
						|
    //赋予状态机
 | 
						|
    function BindenvStateMachine(gM) {
 | 
						|
        StateMachine = gM;
 | 
						|
    }
 | 
						|
 | 
						|
    //获取当前帧信息
 | 
						|
    function GetCurrentFrameInfo() {
 | 
						|
        return FrameArr[CurrentFrameIndex];
 | 
						|
    }
 | 
						|
 | 
						|
    //设置描边
 | 
						|
    function SetOutline(Flag, Color = 0xffffffff) {
 | 
						|
        IsOutline = Flag;
 | 
						|
        //如果是开启
 | 
						|
        if (Flag) {
 | 
						|
            //如果没有创建过描边对象就创建
 | 
						|
            if (OutlineList.len() == 0) {
 | 
						|
                foreach(FrameSf in SpriteArr) {
 | 
						|
                    local OutlineCanvasObj = FrameSf.CreateOutLine(Color);
 | 
						|
                    // OutlineCanvasObj.SetZOrder(-1);
 | 
						|
                    // OutlineCanvasObj.SetPosition(-1, -1);
 | 
						|
                    // OutlineCanvasObj.SetPosition(-FrameSf.GetSize().w / 2, -FrameSf.GetSize().h);
 | 
						|
                    OutlineList.push(OutlineCanvasObj);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            //先把当前帧的描边对象设置上
 | 
						|
            AddOutlineChild();
 | 
						|
        } else {
 | 
						|
            //移除当前描边对象
 | 
						|
            if (CurrentOutline) {
 | 
						|
                Removechild(CurrentOutline);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    //添加描边子对象
 | 
						|
    function AddOutlineChild() {
 | 
						|
        //如果有上一个描边对象先移除
 | 
						|
        if (CurrentOutline) {
 | 
						|
            Removechild(CurrentOutline);
 | 
						|
        }
 | 
						|
        //如果没有添加为子对象则添加
 | 
						|
        local OutlineCanvasObj = OutlineList[CurrentFrameIndex];
 | 
						|
        if (OutlineCanvasObj.Parent == null) {
 | 
						|
            CurrentOutline = OutlineCanvasObj;
 | 
						|
            Addchild(CurrentOutline);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    function FlushFrame(Index) {
 | 
						|
        //同步当前帧
 | 
						|
        CurrentFrameIndex = Index;
 | 
						|
 | 
						|
        //当前帧更换为本帧
 | 
						|
        CurrentFrame = SpriteArr[CurrentFrameIndex];
 | 
						|
        SetFrame(CurrentFrame);
 | 
						|
 | 
						|
        local FrameInfo = FrameArr[CurrentFrameIndex];
 | 
						|
        local FlagBuf = FrameInfo.Flag;
 | 
						|
        NextFrameDelay = FrameInfo.Delay;
 | 
						|
        //关键帧
 | 
						|
        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);
 | 
						|
        }
 | 
						|
        //线性减淡
 | 
						|
        if ("GRAPHIC_EFFECT_LINEARDODGE" in FrameInfo.Flag) {
 | 
						|
            SetMode(0);
 | 
						|
        }
 | 
						|
        //如果有描边
 | 
						|
        if (IsOutline) AddOutlineChild();
 | 
						|
 | 
						|
        //Ani对象的大小同步为精灵帧对象的大小
 | 
						|
        if (CurrentFrame) SetSize(CurrentFrame.GetSize());
 | 
						|
    }
 | 
						|
 | 
						|
    //override
 | 
						|
    function OnUpdate(dt) {
 | 
						|
        //可用性检查
 | 
						|
        if (IsUsability) {
 | 
						|
            //累加当前帧时间
 | 
						|
            CurrentIndexT += dt;
 | 
						|
 | 
						|
            //当前帧时间 超过 当前帧延迟就需要切换帧了
 | 
						|
            if (CurrentIndexT >= NextFrameDelay) {
 | 
						|
                CurrentIndexT = 0;
 | 
						|
                //如果当前帧小于总帧数就切换
 | 
						|
                if (CurrentFrameIndex<(TotalFrameIndex - 1)) {
 | 
						|
                    FlushFrame(CurrentFrameIndex + 1);
 | 
						|
                }
 | 
						|
                //说明播放完毕了
 | 
						|
                else {
 | 
						|
                    //如果有循环
 | 
						|
                    if ("LOOP" in AnimationFlag) {
 | 
						|
                        FlushFrame(0);
 | 
						|
                    }
 | 
						|
                    //没有循环触发状态机回调
 | 
						|
                    else {
 | 
						|
                        //将不再可用
 | 
						|
                        IsUsability = false;
 | 
						|
                        if (StateMachine && StateMachine.State != -1) StateMachine.ChangeAniEndFlag();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        //Animation类下只会有精灵 因此不需要对子对象进行更新  还有可能有als  还得想办法优化
 | 
						|
        base.OnUpdate(dt);
 | 
						|
    }
 | 
						|
} |