DOF/sqr/User/Asset/Character/Animation.nut

335 lines
12 KiB
Plaintext

/*
文件名: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
JumpAni = 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;
SMap = {
WaitingAni = "waiting motion",
MoveAni = "move motion",
SitAni = "sit motion",
DamageAni1 = "damage motion 1",
DamageAni2 = "damage motion 2",
DownAni = "down motion",
OverturnAni = "overturn motion",
JumpAni = "jump motion",
JumpAttackAni = "jumpattack motion",
RestAni = "rest motion",
ThrowAni1_1 = "throw motion 1-1",
ThrowAni1_2 = "throw motion 1-2",
ThrowAni2_1 = "throw motion 2-1",
ThrowAni2_2 = "throw motion 2-2",
ThrowAni3_1 = "throw motion 3-1",
ThrowAni3_2 = "throw motion 3-2",
ThrowAni4_1 = "throw motion 4-1",
ThrowAni4_2 = "throw motion 4-2",
DashAni = "dash motion",
DashAttackAni = "dashattack motion",
GetItemAni = "getitem motion",
BuffAni = "buff motion",
}
//默认的Ani
Default_Avatar = null;
//隐藏图层
HideLayer = null;
//使用武器装扮
UseWeaponAvatar = false;
constructor() {
base.constructor();
}
//根据Ani路径和格式化数组来创建Ani ImgVariation Ani对应的格式化的数组 | Src Ani路径
function CreateAni(ImgVariation, Src) {
//拷贝Ani的信息
local AniInfo = sq_DeepCopy(ScriptData.GetAni(Src));
//构造Ani的处理函数
local Ao = {
//传递Img的格式化方法
ImgFormat = function(ImgPath) {
//如果是皮肤这里会是"%04d" 这里要格式化成"%02d%02d"
if (ImgPath.find("%04d")) {
local Pos = ImgPath.find("%04d");
ImgPath = ImgPath.slice(0, Pos) + "%02d%02d" + ImgPath.slice(Pos + 4);
}
//替换掉Img的索引编号
return format(ImgPath, ImgVariation[0], ImgVariation[1]);
}
}
//构造Ani
local Ani = Animation(AniInfo, Ao);
return Ani;
}
//同步单部位动画 Type 时装的类型名字 "hair" | Src Ani的路径
function SyncAnimationBySlot(Type, Src) {
//单部位的动画组
local AniList = [];
//如果有时装就初始化Ani
//除了皮肤 在没有的情况下初始化0
if (Type == "skin_avatar") {
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 SkinAni = CreateAni(variation, Src);
//如果是皮肤Ani 绑定状态机 确保唯一性
SkinAni.BindenvStateMachine(Parent.StateMachine);
//将Ani类型设置为皮肤
SkinAni.Type = "skin";
//加入组
AniList.append(SkinAni);
} else {
//先判断 时装类型 角色有没有穿戴这个类型的时装
if (Parent[Type] != null) {
//获取对应装备或时装的信息
local AvaInfo = Parent[Type];
if (AvaInfo) {
//获取对应职业对应的格式化信息
local JobInfo = AvaInfo["Animation_Job"]["Ani_" + Parent.Info["job"]];
local variation = JobInfo["variation"];
//非皮肤的时装 会有多个层
foreach(_index, value in JobInfo["layer_variation"]) {
local RealAniPath;
//如果有指定Ani Path 就使用指定的Ani Path
if (AvaInfo["ExpandPath"]) RealAniPath = AvaInfo["ExpandPath"] + value["Path"] + Src.slice(Src.lastfind("/"));
//否则 拼接真实的Ani路径
else RealAniPath = AvaInfo["DirPath"] + value["Path"] + Src.slice(Src.lastfind("/"));
local AniBuf = CreateAni(variation, RealAniPath);
//设置Ani类型
AniBuf.Type = Type;
//设置Ani的ZOrder
AniBuf.SetZOrder(value["Zorder"]);
//加入组
AniList.append(AniBuf);
}
}
}
}
return AniList;
}
//根据动画组名称构造AniMap AniObj 角色类的动画组名称 Src Ani代表的标签 “sit motion” SlotType 装备类型
function StructureAniMap(Src) {
//初始化所有时装部位
local AniObjectMap = {};
foreach(Type, NString in getconsttable().AvatarType) {
local AniList = SyncAnimationBySlot(Type, Src);
AniObjectMap[Type] <- AniList;
}
return AniObjectMap;
}
//切换装备的刷新Ani
function RefreshAni(AniObj, Src, SlotType) {
//记录当前皮肤Ani的时间 确保唯一性
local AniTime = 0;
if (this.CurrentAni) AniTime = this.CurrentAni["skin_avatar"][0].CurrentIndexT;
//记录当前皮肤Ani的帧 确保唯一性
local AniFrameIndex = 0;
if (this.CurrentAni) AniFrameIndex = this.CurrentAni["skin_avatar"][0].CurrentFrameIndex;
//如果当前播放Ani是 构造的Ani 则移除 并清空
if (this.CurrentAni == this[AniObj]) {
foreach(AniBuf in this.CurrentAni[SlotType]) {
AniBuf.RemoveSelf();
}
}
local AniList = SyncAnimationBySlot(SlotType, Src);
this[AniObj][SlotType] <- AniList;
//如果当前播放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 Init(SlotType = false) {
//遍历所有Ani类型并构造
foreach(ChrAniObj, InfoSrc in SMap) {
//从父对象 角色对象取得Info 判断其中有没有这个Ani标签 如果有 取得路径
if (Parent.Info.rawin(InfoSrc)) InfoSrc = Parent.Info[InfoSrc];
else continue;
if (!SlotType) {
this[ChrAniObj] = StructureAniMap(InfoSrc);
} else {
RefreshAni(ChrAniObj, InfoSrc, SlotType);
}
}
//将默认时装类型存储起来 因为脱下时装的时候要恢复默认时装的设定
if (!Default_Avatar) {
Default_Avatar = {};
foreach(EquiId in Parent.Info.default_avatar) {
local EquBuffer = GameItem.Equipment(EquiId);
Default_Avatar[EquBuffer.SlotType] <- EquBuffer;
}
}
}
//构造临时Ani
function CreateTempAni(AniName) {
local InfoSrc = SMap[AniName];
//从父对象 角色对象取得Info 判断其中有没有这个Ani标签 如果有 取得路径
if (Parent.Info.rawin(InfoSrc)) InfoSrc = Parent.Info[InfoSrc];
else return;
local Ani = Actor();
foreach(Key, AniGroup in StructureAniMap(InfoSrc)) {
//如果是皮肤Ani 则设置Ani的大小
if (Key == "skin_avatar") Ani.SetSize(AniGroup[0].GetSize());
//如果使用了武器装扮 不加入武器的Ani
if (Key == "weapon" && UseWeaponAvatar) continue;
foreach(AniObj in AniGroup) {
//如果AniObj的ZOrder在隐藏图层中 则隐藏
if (HideLayer.rawin(AniObj.GetZOrder())) {
} else {
Ani.Addchild(AniObj);
}
}
}
return Ani;
}
//处理隐藏图层
function HandlingHideLayers() {
//遍历全部时装计算隐藏图层
HideLayer = {};
UseWeaponAvatar = false;
foreach(Type, NString in getconsttable().AvatarType) {
local Equip = Parent[Type];
if (Equip) {
//如果装备有隐藏图层 则加入隐藏图层
if (Equip.HideLayer) {
foreach(layer in Equip.HideLayer) {
HideLayer[layer] <- true;
}
}
//如果有佩戴武器装扮
if (Type == "weapon_avatar") {
UseWeaponAvatar = true;
}
}
}
//遍历全部Ani
foreach(ChrAniObj, InfoSrc in SMap) {
//取得Ani组
if (this[ChrAniObj]) {
foreach(Key, AniGroup in this[ChrAniObj]) {
//如果使用了武器装扮 则隐藏武器Ani
if (Key == "weapon" && UseWeaponAvatar) {
foreach(AniObj in AniGroup) {
AniObj.SetVisible(false);
}
} else {
//遍历Ani组
foreach(AniObj in AniGroup) {
//如果AniObj的ZOrder在隐藏图层中 则隐藏
if (HideLayer.rawin(AniObj.GetZOrder())) {
AniObj.SetVisible(false);
} else {
AniObj.SetVisible(true);
}
}
}
}
}
}
}
//设置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);
}
}
}
//设置方向
function SetDirection(D) {
if (D == DIRECTION.RIGHT) {
SetScale(fabs(GetScale().x), GetScale().y);
} else if (D == DIRECTION.LEFT) {
SetScale(-fabs(GetScale().x), GetScale().y);
}
}
}