在實(shí)際項(xiàng)目制作過(guò)程中基协,***有時(shí)候僅僅播放預(yù)先設(shè)置的骨骼動(dòng)畫是不夠的,還需要角色具有動(dòng)態(tài)可控的動(dòng)作。DragonBones提供了訪問(wèn)并控制骨骼框架里的每一根骨頭的方法十拣,可以讓角色能夠有豐富多樣的交互效果叙身。***
在示例中渔扎,通過(guò)鼠標(biāo)拖拽方塊,小龍人根據(jù)與方塊的距離去播放stand或者walk的動(dòng)畫信轿,根據(jù)與方塊的角度問(wèn)題晃痴,小龍人的頭部與手部會(huì)有一個(gè)角度的變化。
本需求的重點(diǎn)就是:獲取頭部與手部的骨骼财忽,然后設(shè)置骨骼的旋轉(zhuǎn)角度倘核。
本示例的關(guān)鍵代碼如下:
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");
通過(guò)dragoneBones.Armature.getBone("骨骼名字")來(lái)獲取某個(gè)骨骼,骨骼對(duì)象中的offset屬性是一個(gè)DBTranform對(duì)象即彪,是專門用于給開發(fā)者設(shè)置疊加的變換信息的紧唱,包括平移,旋轉(zhuǎn)隶校,縮放等漏益。
this.head.offset.rotation = _r *0.3
this.armR.offset.rotation = _r *0.8;
this.armL.offset.rotation = _r * 1.5;
ps:這里的offset的值是疊加到骨骼現(xiàn)有的變化上,并不是取代骨骼的現(xiàn)有變換深胳。
下面是整個(gè)示例的完整代碼:
/**
* 該類主要是用來(lái)學(xué)習(xí) 如何控制骨骼動(dòng)畫中骨骼的運(yùn)動(dòng)
*/
class DBTestScene2 extends egret.Sprite{
// private factory:dragonBones.EgretFactory;
// private armature:dragonBones.Armature;//骨架
// private armatureDisplay:dragonBones.EgretArmatureDisplay;//骨架顯示對(duì)象
// 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
{
// 獲取骨骼數(shù)據(jù)
var skeletonData = RES.getRes("Dragon_ske_json");
// 獲取紋理數(shù)據(jù)
var textureData = RES.getRes("Dragon_tex_json");
var texture = RES.getRes("Dragon_tex_png");
// 解析骨骼數(shù)據(jù)與紋理數(shù)據(jù)
this.factory.parseDragonBonesData(skeletonData);
this.factory.parseTextureAtlasData(textureData,texture);
// 獲取骨架
this.armature = this.factory.buildArmature("Dragon");
// 注意4掳獭!3硗馈B退!這里要獲取骨架上的display 才可以在骨架移動(dòng)的時(shí)候貼圖一起移動(dòng)
this.armatureClip = this.armature.getDisplay();
// 如果這樣子獲取armatureDisplay 骨骼移動(dòng)之后 貼圖并不會(huì)動(dòng)
// 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;
}
}