238 lines
6.2 KiB
JavaScript
238 lines
6.2 KiB
JavaScript
/******************************************************************
|
|
* 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 );
|
|
},
|
|
|
|
} );
|