/* 文件名:Animation.nut 路径:User/Asset/Character/Animation.nut 创建日期:2024-12-12 16:43 文件用途: */ class Character_Animation extends Actor { //角色对象 Parent = 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; //光环 AuroraAni = null; constructor() { base.constructor(); } //同步单部位动画 function SyncAnimationBySlot(Type, AniObj, Src) { this[AniObj][Type] <- []; //如果有时装就初始化Ani //除了皮肤 在没有的情况下初始化0 if (Type == "skin") { local variation = [0, 0]; //如果存在皮肤就读取variation if (Parent[Type] != null) { local AvaInfo = Parent[Type]; local JobInfo = AvaInfo["Animation_Job"]["Ani_" + Parent.Info["job"]]; variation = JobInfo["variation"]; } local BufInfo = sq_DeepCopy(ScriptData.GetAni(Src)); local Ao = { ImgVariation = 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]); } } } local SkinAni = Animation(BufInfo, Ao); //如果是皮肤Ani 绑定状态机 确保唯一性 SkinAni.BindenvStateMachine(Parent.StateMachine); //将Ani类型设置为皮肤 SkinAni.Type = "skin"; //加入组 this[AniObj][Type].append(SkinAni); } else { //先判断类型 if (Parent[Type] != null) { local AvaInfo = Parent[Type]; if (AvaInfo) { local JobInfo = AvaInfo["Animation_Job"]["Ani_" + Parent.Info["job"]]; foreach(_index, value in JobInfo["layer_variation"]) { local BufInfo = sq_DeepCopy(ScriptData.GetAni(AvaInfo["DirPath"] + value["Path"] + Src.slice(Src.lastfind("/")))); 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][Type].append(AniBuf); } } } } } //读取并设置Ani function ReadAndSetAni(AniObj, Src, SlotType) { //从父对象 也就是角色对象取得Info local Info = Parent.Info; //如果有这个标签Ani则初始化 获取ani路径 if (Info.rawin(Src)) Src = Info[Src]; else return; //如果不存在则构造 if (this[AniObj] == null) this[AniObj] = {}; //如果没有传递装备类型就初始化所有 if (!SlotType) { foreach(Type in getconsttable().AvatarType) { SyncAnimationBySlot(Type, AniObj, Src); } } //否则只初始化这一件装备的 else { //记录当前皮肤Ani的时间 确保唯一性 local AniTime = 0; if (this.CurrentAni) AniTime = this.CurrentAni["skin"][0].CurrentIndexT; //记录当前皮肤Ani的帧 确保唯一性 local AniFrameIndex = 0; if (this.CurrentAni) AniFrameIndex = this.CurrentAni["skin"][0].CurrentFrameIndex; //如果当前播放Ani是 构造的Ani 则移除 并清空 if (this.CurrentAni == this[AniObj]) { foreach(AniBuf in this.CurrentAni[SlotType]) { AniBuf.RemoveSelf(); } } SyncAnimationBySlot(SlotType, AniObj, Src); //如果当前播放Ani是 构造的Ani if (this.CurrentAni == this[AniObj]) { //添加Ani 并设置为当前皮肤Ani的时间 foreach(AniBuf in this.CurrentAni[SlotType]) { //一定要先添加 否则会导致动画时间混乱因为被添加时会刷新到0帧 Addchild(AniBuf); AniBuf.CurrentIndexT = AniTime; AniBuf.FlushFrame(AniFrameIndex); } } } } 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 = AssetManager.GetEquipment(this[Type]); local JobInfo = AvaInfo["Ani"]["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 = AssetManager.GetEquipment(this[Type]); local JobInfo = AvaInfo["Ani"]["Ani_" + Info["job"]]; foreach(_index, value in JobInfo["layer_variation"]) { local BufInfo = sq_DeepCopy(ScriptData.GetAni(AvaInfo["DirPath"] + value["Path"] + Src.slice(Src.lastfind("/")))); 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 Init(SlotType = false) { //读取并设置 等待Ani ReadAndSetAni("WaitingAni", "waiting motion", SlotType); //读取并设置 移动Ani ReadAndSetAni("MoveAni", "move motion", SlotType); //读取并设置 蹲下Ani ReadAndSetAni("SitAni", "sit motion", SlotType); //读取并设置 受伤Ani ReadAndSetAni("DamageAni1", "damage motion 1", SlotType); //读取并设置 受伤Ani ReadAndSetAni("DamageAni2", "damage motion 2", SlotType); //读取并设置 倒地Ani ReadAndSetAni("DownAni", "down motion", SlotType); //读取并设置 被击后退Ani ReadAndSetAni("OverturnAni", "overturn motion", SlotType); //读取并设置 跳跃Ani ReadAndSetAni("JumoAni", "jump motion", SlotType); //读取并设置 跳跃攻击Ani ReadAndSetAni("JumpAttackAni", "jumpattack motion", SlotType); //读取并设置 站立Ani ReadAndSetAni("RestAni", "rest motion", SlotType); //读取并设置 引导Ani ReadAndSetAni("ThrowAni1_1", "throw motion 1-1", SlotType); ReadAndSetAni("ThrowAni1_2", "throw motion 1-2", SlotType); ReadAndSetAni("ThrowAni2_1", "throw motion 2-1", SlotType); ReadAndSetAni("ThrowAni2_2", "throw motion 2-2", SlotType); ReadAndSetAni("ThrowAni3_1", "throw motion 3-1", SlotType); ReadAndSetAni("ThrowAni3_2", "throw motion 3-2", SlotType); ReadAndSetAni("ThrowAni4_1", "throw motion 4-1", SlotType); ReadAndSetAni("ThrowAni4_2", "throw motion 4-2", SlotType); //读取并设置 奔跑Ani ReadAndSetAni("DashAni", "dash motion", SlotType); //读取并设置 奔跑攻击Ani ReadAndSetAni("DashAttackAni", "dashattack motion", SlotType); //读取并设置 拾取Ani ReadAndSetAni("GetItemAni", "getitem motion", SlotType); //读取并设置 释放BUFFAni ReadAndSetAni("BuffAni", "buff motion", SlotType); //读取并设置 AttackAni // ReadAndSetAttackAni(); } function InitAuroa() { //光环 local Info = Parent.aurora; //如果有光环 if (AuroraAni) { foreach(Ani in AuroraAni) { Removechild(Ani); } } AuroraAni = []; foreach(Effect in Info.Aurora_effects) { local AniBuf = Animation(Effect.path); AuroraAni.append(AniBuf); Addchild(AniBuf); //front if (Effect.type == 1) { AniBuf.SetZOrder(100000); } else { AniBuf.SetZOrder(-100000); } } } //设置Ani function SetAnimation(Ani) { //因为是Ani组所以要foreach调用 //如果已经有Ani了 if (CurrentAni) { //动作Ani组 foreach(AniGroup in CurrentAni) { //槽类型动画 foreach(AniObj in AniGroup) { Removechild(AniObj); } } } if (type(Ani) == "integer") { //TODO 进阶ANI } else { CurrentAni = this[Ani]; } //重置Ani 并添加子对象 foreach(Key, AniGroup in CurrentAni) { foreach(AniObj in AniGroup) { AniObj.Reset(); Addchild(AniObj); } } } }