Files

238 lines
6.2 KiB
JavaScript
Raw Permalink Normal View History

2026-05-23 22:10:14 +08:00
/******************************************************************
* Copyright(C) 2019 - 2020 Nx Studio
*
* Spine强化
*
* 2023.11.01
******************************************************************/
cc.Class( {
extends: cc.Component,
properties: {
spNode: { default: null, type: sp.Skeleton },
spAction: { default: "", displayName: "动作名" },
spRK: { default: "", displayName: "资源键值" },
spLoop: { default: true, displayName: "循环" },
isAntialias: { default: true, displayName: "抗锯齿" },
},
// 编辑器特性
editor: {
// 允许当前组件在编辑器模式下运行
executeInEditMode: false,
// 当本组件添加到节点上后,禁止同类型(含子类)的组件再添加到同一个节点,防止逻辑发生冲突
disallowMultiple: true,
// menu 用来将当前组件添加到组件菜单中,方便用户查找
menu: "Nx/本地化|骨骼动画",
},
// 加载
onLoad: function() {
// SP事件绑定
this.spEvent();
// 语言改变
this.onLanguageChanged();
},
// 销毁
onDestroy: function() {
// 资源释放
if( this.spSkeleton && window.nx ) {
nx.assets.uncacheAsset( this.spSkeleton );
this.spSkeleton = null;
}
},
// 播放
play: function( _rkey, _action, _cb, _loop ) {
// 直接播放
if( this.key == _rkey && this.spNode.skeletonData ) {
this.action( _action, _loop, _cb );
return;
}
// 先停止
this.stop();
// 再加载
let self = this;
this.load( _rkey, ( _e, _p ) => {
// 失败处理
if( _e ) {
nx.dt.fnInvoke( _cb, _e );
return;
}
// 最后播放
self.action( _action, _loop, _cb );
} );
},
// 停止
stop: function( _release = true ) {
this.spCB = null;
if( !this.spNode ) {
return;
}
// 动画停止
this.spNode.node.opacity = 0;
this.spNode.animation = "";
if( _release && this.spNode.skeletonData ) {
this.spNode.skeletonData.reset();
this.spNode.skeletonData = null;
nx.assets.uncacheAsset( this.spSkeleton );
this.spSkeleton = null;
}
},
// 加载SPINE文件
load: function( _rkey, _cb ) {
// 完成处理
// 记录当前文件信息
let self = this;
let done = function() {
self.key = _rkey;
self.spRK = _rkey;
};
// 統一返回
let notify = function( _p1, _p2 ) {
if( !self || !self.spNode ) {
nx.warn( `NxSpine:节点已经不存在,回调忽略!` );
return;
}
nx.dt.fnInvoke( _cb, _p1, _p2 );
};
// 读取
let path = nx.res.fmtPath( _rkey );
nx.res.loadSpine( path, function( _e, _p ) {
if( _e ) {
notify( _e );
return;
}
// 抗锯齿
if( nx.dt.arrNEmpty( _p.textures ) ) {
let minF = self.isAntialias ? cc.Texture2D.Filter.LINEAR : cc.Texture2D.Filter.NEAREST;
let magF = self.isAntialias ? cc.Texture2D.Filter.LINEAR : cc.Texture2D.Filter.NEAREST;
for( let i in _p.textures ) {
let tex = _p.textures[ i ];
if( tex ) {
tex.setFilters( minF, magF );
}
}
}
// 资源绑定
if( self.spNode ) {
nx.assets.cacheAsset( _p, path );
self.spNode.skeletonData = _p;
nx.assets.uncacheAsset( self.spSkeleton );
self.spSkeleton = _p;
self.spNode.node.opacity = 255;
}
done();
notify();
} );
},
// 直接播放动作
action: function( _action, _loop, _cb, _scale = 1.0 ) {
if( !this.spNode ) {
nx.warn( "节点丢失,播放动作失败!" + _action );
return;
}
// 如果已经丢失数据,则重载播放
if( !this.spNode.skeletonData ) {
this.play( this.spRK, _action, _loop, _cb );
return;
}
this.spCB = _cb;
this.spAction = _action;
this.spLoop = !!_loop;
// 播放
this.spNode.loop = !!_loop;
this.spNode.animation = _action;
this.spNode.node.opacity = 255;
this.spNode.timeScale = _scale;
},
// 修改播放速度
setTimeScale: function( _scale = 1.0 ) {
if( this.spNode ) {
this.spNode.timeScale = _scale;
}
},
// SP事件绑定
spEvent: function() {
if( !this.spNode ) {
return;
}
let self = this;
let tracker = function( _key, _tracker, _custom = false ) {
let name = _tracker.animation ? _tracker.animation.name : "";
self._notify( _key, name, _custom );
};
// 监听
this.spNode.setStartListener( _tk => { tracker( "start", _tk ); } );
this.spNode.setInterruptListener( _tk => { tracker( "interrupt", _tk ); } );
this.spNode.setEndListener( _tk => { tracker( "end", _tk ); } );
this.spNode.setDisposeListener( _tk => { tracker( "disposed", _tk ); } );
this.spNode.setCompleteListener( _tk => { tracker( "complete", _tk ); } );
this.spNode.setEventListener( ( _tk, _event ) => { tracker( _event.data.name, _tk, true ); } );
},
// 当前语种改变
onLanguageChanged: function( _lang ) {
if( nx.dt.strEmpty( this.spRK ) ||
nx.dt.strEmpty( this.spAction ) ) {
return;
}
// 播放
this.play( this.spRK, this.spAction, this.spCB, this.spLoop );
},
// 通告
_notify: function( event, anim, custom ) {
// nx.debug( "[SPINE]Event:%s %s", event, anim );
nx.dt.fnInvoke( this.spCB, event, anim, custom );
},
} );