在实际项目制作过程中,***有时候仅仅播放预先设置的骨骼动画是不够的,还需要角色具有动态可控的动作。DragonBones提供了访问并控制骨骼框架里的每一根骨头的方法,可以让角色能够有丰富多样的交互效果。***
在示例中,通过鼠标拖拽方块,小龙人根据与方块的距离去播放stand或者walk的动画,根据与方块的角度问题,小龙人的头部与手部会有一个角度的变化。
本需求的重点就是:获取头部与手部的骨骼,然后设置骨骼的旋转角度。
本示例的关键代码如下:
private head: dragonBones.Bone;
private armL: dragonBones.Bone;
private armR: dragonBones.Bone;
//获取骨骼
this.head = this.armature.getBone("head");
this.armL = this.armature.getBone("armUpperL");
this.armR = this.armature.getBone("armUpperR");
通过dragoneBones.Armature.getBone("骨骼名字")来获取某个骨骼,骨骼对象中的offset属性是一个DBTranform对象,是专门用于给开发者设置叠加的变换信息的,包括平移,旋转,缩放等。
this.head.offset.rotation = _r *0.3
this.armR.offset.rotation = _r *0.8;
this.armL.offset.rotation = _r * 1.5;
ps:这里的offset的值是叠加到骨骼现有的变化上,并不是取代骨骼的现有变换。
下面是整个示例的完整代码:
/**
* 该类主要是用来学习 如何控制骨骼动画中骨骼的运动
*/
class DBTestScene2 extends egret.Sprite{
// private factory:dragonBones.EgretFactory;
// private armature:dragonBones.Armature;//骨架
// private armatureDisplay:dragonBones.EgretArmatureDisplay;//骨架显示对象
// private head:dragonBones.Bone;//头骨骼
// private armL:dragonBones.Bone;//左臂骨骼
// private armR:dragonBones.Bone;//右臂骨骼
// private bird:egret.Shape;
public constructor() {
super();
this.addEventListener(egret.Event.ADDED_TO_STAGE,this.onStage,this);
}
private onStage(){
this.graphics.beginFill(0xff0000,0.3);
this.graphics.drawRect(0,0,this.stage.stageWidth,this.stage.stageHeight);
this.graphics.endFill();
this.initGame();
}
private factory:dragonBones.EgretFactory = new dragonBones.EgretFactory();
private armature: dragonBones.Armature;
private armatureClip:egret.DisplayObject;
private head: dragonBones.Bone;
private armL: dragonBones.Bone;
private armR: dragonBones.Bone;
private lark: egret.Bitmap;
private initGame(): void
{
// 获取骨骼数据
var skeletonData = RES.getRes("Dragon_ske_json");
// 获取纹理数据
var textureData = RES.getRes("Dragon_tex_json");
var texture = RES.getRes("Dragon_tex_png");
// 解析骨骼数据与纹理数据
this.factory.parseDragonBonesData(skeletonData);
this.factory.parseTextureAtlasData(textureData,texture);
// 获取骨架
this.armature = this.factory.buildArmature("Dragon");
// 注意!!!!!这里要获取骨架上的display 才可以在骨架移动的时候贴图一起移动
this.armatureClip = this.armature.getDisplay();
// 如果这样子获取armatureDisplay 骨骼移动之后 贴图并不会动
// this.armatureClip = this.factory.buildArmatureDisplay("Dragon");
this.armatureClip.x = 200;
this.armatureClip.y = 450;
this.addChild(this.armatureClip);
dragonBones.WorldClock.clock.add(this.armature);
this.armature.animation.play("stand");
this.head = this.armature.getBone("head");
this.armL = this.armature.getBone("armUpperL");
this.armR = this.armature.getBone("armUpperR");
egret.startTick(this.onTicker, this);
this.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.onTouchMove,this);
this.lark = new egret.Bitmap(RES.getRes("button_down_png"));
this.addChild(this.lark);
}
private _time:number;
private onTicker(timeStamp:number) {
if(!this._time) {
this._time = timeStamp;
}
var now = timeStamp;
var pass = now - this._time;
this._time = now;
this.checkDist();
this.updateMove();
this.updateBones();
dragonBones.WorldClock.clock.advanceTime(pass / 1000);
return false;
}
private mouseX: number = 0;
private mouseY: number = 0;
private dist: number = 0;
private moveDir: number = 0;
private speedX: number = 0;
private onTouchMove(evt: egret.TouchEvent): void
{
this.mouseX = evt.stageX;
this.mouseY = evt.stageY;
this.lark.x=this.mouseX - 39;
this.lark.y=this.mouseY - 34;
}
private checkDist():void
{
this.dist = this.armatureClip.x-this.mouseX;
if(this.dist<150)
{
this.updateBehavior(1);
}
else if(this.dist>190)
{
this.updateBehavior(-1)
}
else
{
this.updateBehavior(0)
}
}
private updateBehavior(dir:number):void
{
if(this.moveDir == dir) {
return;
}
this.moveDir=dir;
if (this.moveDir == 0)
{
this.speedX = 0;
this.armature.animation.gotoAndPlay("stand");
}
else
{
this.speedX=6*this.moveDir;
this.armature.animation.gotoAndPlay("walk");
}
}
private updateMove():void
{
if (this.speedX != 0)
{
this.armatureClip.x += this.speedX;
if (this.armatureClip.x < 0)
{
this.armatureClip.x = 0;
}
else if (this.armatureClip.x > 800)
{
this.armatureClip.x = 800;
}
}
}
private updateBones():void
{
//update the bones' pos or rotation
var _r = Math.PI + Math.atan2(this.mouseY - this.armatureClip.y+this.armatureClip.height/2, this.mouseX - this.armatureClip.x);
if (_r > Math.PI)
{
_r -= Math.PI * 2;
}
this.head.offset.rotation = _r *0.3
this.armR.offset.rotation = _r *0.8;
this.armL.offset.rotation = _r * 1.5;
this.lark.rotation=_r*0.2;
}
}