[LayaAir 2.0]Laya 绑定显示内容到骨骼动画

 记录自己添加的内容:
 
1. 可绑定内容的骨骼动画
 
export default class BindSkeleton extends Laya.Skeleton
{
private __bindList:BindSource[];
constructor(){
super();
this.__bindList=[];

/**
* 绑定
* @param source
*/
bind(source:BindSource):void{
let index:number=this.__bindList.indexOf(source);
if(index<0){
this.__bindList.push(source);
}
this.addChild(source);
this.timer.frameLoop(1,this,this.__updateBinds);

unbind(source:BindSource):void{
let index:number=this.__bindList.indexOf(source);
if(index<0){
throw new Error("找不到要删除的绑定内容");
}
this.removeChild(source);
this.__bindList.splice(index,1);

private __updateBinds():void{
let source:BindSource;
let position:Laya.Point=Laya.Point.create();
for(let index:number=0;index<this.__bindList.length;index++){
source=this.__bindList[index];
SkeletonUtils.getBoneLocalPoint(this,source.boneName,position);
source.x=source.offestX+position.x;
source.y=source.offestX+position.y;
}

destroy(destroyChild?:boolean):void{
this.timer.clear(this,this.__updateBinds);
this.__bindList.length=0;
this.__bindList=null;
super.destroy(destroyChild);
}
}
 
2. 可绑定到骨骼的内容
/**
* 可绑定到骨骼的内容(实现者必须是Laya.Sprite的子类)
*/
export interface IBindSource{
boneName:string;
offestX:number;
offestY:number;
}
 
3.一个具体的可绑定内容实现
/**
* 可绑定到骨骼槽的内容
*/
export default class BindSource extends Laya.Sprite implements IBindSource
{
public boneName:string;
public offestX:number;
public offestY:number;
constructor(boneName:string,offestX:number=0,offestY=0){
super();
this.boneName=boneName;
this.offestX=offestX;
this.offestY=offestY;

destroy(destroyChild?:boolean):void{
this.boneName=null;
this.offestX=this.offestY=undefined;
super.destroy(destroyChild);
}
}
 
4. 骨骼工具类提供一个静态方法
 
export default class SkeletonUtils
{
/**
* 获取骨骼在局部空间的坐标点
* @param skeleton
* @param BoneName
*/
static getBoneLocalPoint(skeleton:Laya.Skeleton,BoneName:string,result:Laya.Point=null):Laya.Point{
if(result==null){
result=new Laya.Point();
}
result.x=result.y=0;
let bone:laya.ani.bone.Bone=skeleton.templet.mRootBone.findBone(BoneName);
let matrix:laya.maths.Matrix=bone.getResultMatrixByFrame(skeleton.index);
result=matrix.transformPoint(result);
return result;
}
}
 
 
以上是自定义代码部分,下面是laya源码的修改:
 
1. laya.ani.js 文件中 Bone 类中添加通过帧数来获取矩阵的方法
//返回变化矩阵
    __proto.getResultMatrixByFrame=function(index){
        var matrix=this._resultMatrixCache[index];
        if(matrix){
            return matrix;
        }
        return this.resultMatrix;
    }
 
2. Bone 的构造函数中添加矩阵缓存列表
function Bone(){
        this.name=null;
        this.root=null;
        this.parentBone=null;
        this.length=10;
        this.transform=null;
        this.inheritScale=true;
        this.inheritRotation=true;
        this.rotation=NaN;
        this.resultRotation=NaN;
        this.d=-1;
        this._tempMatrix=null;
        this._sprite=null;
        this.resultTransform=new Transform();
        this.resultMatrix=new Matrix();
        this._children=[];
        //帧变换缓存
        this._resultMatrixCache=[];
    }

3.在Bone 的 update 函数添加参数 clipIndex 并在函数的最后修改成
       
var i=0,n=0;
var tBone;
for (i=0,n=this._children.length;i < n;i++){
       tBone=this._children[i];
            //递归调用必须传入帧索引让子骨骼也能缓存变换矩阵
            tBone.update(clipIndex);
}
//缓存起来
this._resultMatrixCache[clipIndex]=this.resultMatrix.clone(); 
4. 好了  收尾阶段在 laya.ani.js  中 Skeleton 类的 _createGraphics方法 有个调用骨骼更新的方法
this._rootBone.update(this._clipIndex,this._yReverseMatrix || Matrix.TEMP.identity());

 使用方式:
   this.__bind=new BindSkeleton();
        Laya.stage.addChild(this.__bind);
        this.__bind.x=Laya.stage.width*0.5;
        this.__bind.y=Laya.stage.height*0.5; 
        this.__bind.load(GamePath.single.getSpinePath("tank_blue.sk"),Laya.Handler.create(this,this.testLoadComplete));
  } 
    private __bind:BindSkeleton;
    private testLoadComplete():void{ 
        let source:BindSource=new BindSource("gongji");
        source.graphics.drawRect(0,0,20,20,"#FFFF00"); 
        this.__bind.bind(source);    } 
已邀请:

蝈蝈

赞同来自:

更新  骨骼中的缓存内容换为二维数组来支持 多动画
 

要回复问题请先

商务合作
商务合作