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

413 lines
14 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
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;
//名字
Name = null;
ENUM_RINDRO_JOB_TITLE_HEIGHT = [
//男鬼剑士
{
x = -18,
y = -154
},
//女格斗
{
x = -18,
y = -140
},
//男神枪手
{
x = -20,
y = -168
},
//女魔法师
{
x = -22,
y = -126
},
//男圣职者
{
x = -22,
y = -166
},
//女神枪手
{
x = -18,
y = -156
},
//女暗夜使者
{
x = -20,
y = -154
},
//男格斗家
{
x = -21,
y = -160
},
//男魔法师
{
x = -21,
y = -140
},
//黑暗武士
{
x = -18,
y = -154
},
//缔造者
{
x = -22,
y = -126
},
];
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
InitAni(SlotType);
//初始化名字
InitName();
}
function InitAni(SlotType) {
//读取并设置 等待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);
}
}
}
//初始化名字
function InitName() {
//创建名字对象
Name = FontAssetManager.GenerateNormal("", false, {
color = sq_RGBA(209, 185, 148, 255),
alignment = TextAlign.Center
});
Name.SetPosition(ENUM_RINDRO_JOB_TITLE_HEIGHT[Parent.Job]);
Name.SetZOrder(80000);
Addchild(Name);
}
//设置名字
function SetName(Name) {
this.Name.SetText(Name);
}
//设置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);
}
}
}
}