西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → Dragon Bones插件创建并控制多个动作的骨骼动画

Dragon Bones插件创建并控制多个动作的骨骼动画

相关软件相关文章发表评论 来源:西西整理时间:2013/9/3 15:18:09字体大小:A-A+

作者:西西点击:132次评论:0次标签: DragonBones

Dragon Bones插件v2.3 官方最新版
  • 类型:编程控件大小:17.0M语言:中文 评分:5.0
  • 标签:
立即下载

接下来你将了解到运用DragonBones创建包含多个动作的骨骼动画,并在程序中通过键盘交互控制动作。

打开文件DragonBones_Tutorial_MultiBehavior.fla,双击库里的动画元件Dragon,你可以看到此动画中有四个动作:stand,walk,jump和fail。每个动作的起始帧上添加了对应的帧标签,这也是DragonBones识别不同动作的标识。

打开骨骼动画编辑面板,你会看到在Behavior List里面会有多个动作,选择某个动作就可以为对应动作设置动画帧数、缓动,设置此动作的某个骨骼的细节参数等。

请留意Behavior编辑里的Blending Times选项。

这个选项是表明的其他动作切换到当前动作需要的过渡时间。例如这里设置的跳跃动作的Blending Times为0.13,那么其他动作切换到跳跃需要0.13秒,DragonBones框架会自动为你添加其中的过渡帧,让各种动作之间切换变得自然。当然,你可以在动画预览窗口中看到各种动画的切换效果。

Dragon Bones插件 v2.3 官方最新版:http://www.cr173.com/soft/68403.html

调整完毕各个动作的细节后,点击“Export”按钮导出骨骼动画数据。

打开DBStarlingMultiBehavior.as文件,代码如下。此示例是在Starling框架中通过键盘控制骨骼动画运动。

PSE: collapse; FONT-FAMILY: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; MAX-WIDTH: 100%; FLOAT: none !important; HEIGHT: auto !important; FONT-SIZE: 1em !important; VERTICAL-ALIGN: baseline !important; OVERFLOW: hidden !important; BORDER-TOP: 0px; TOP: auto !important; RIGHT: auto !important; FONT-WEIGHT: normal !important; BORDER-RIGHT: 0px; PADDING-TOP: 0px !important; LEFT: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px" border="0" cellspacing="0" cellpadding="0">
package
{
    import dragonBones.Armature;
    import dragonBones.animation.WorldClock;
    import dragonBones.factorys.StarlingFactory;
    import flash.ui.Keyboard;
    import starling.display.Sprite;
    import starling.events.EnterFrameEvent;
    import starling.events.KeyboardEvent;
    import starling.text.TextField;
    import flash.events.Event;
    public class DBStarlingMultiBehavior extends Sprite
    {
        [Embed(source = "../assets/Dragon2.png", mimeType = "application/octet-stream")]
        public static const ResourcesData:Class;
        private var factory:StarlingFactory;
        private var armature:Armature;
        private var armatureClip:Sprite;
        private var isLeft:Boolean;
        private var isRight:Boolean;
        private var isJumping:Boolean;
        private var moveDir:int=0;
        private var speedX:Number = 0;
        private var speedY:Number = 0;
        private var textField:TextField
        public function DBStarlingMultiBehavior()
        {
            factory = new StarlingFactory();
            factory.addEventListener(Event.COMPLETE, textureCompleteHandler);
            factory.parseData(new ResourcesData());
        }
        private function textureCompleteHandler(e:Event):void
        {
            armature = factory.buildArmature("Dragon");
            armatureClip = armature.display as Sprite;
            armatureClip.x = 400;
            armatureClip.y = 550;
            addChild(armatureClip);
            WorldClock.clock.add(armature);
            updateBehavior()
            addEventListener(EnterFrameEvent.ENTER_FRAME, onEnterFrameHandler);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyEventHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyEventHandler);
            textField=new TextField(400,30,"A-move left,D-move right,W-jump","Verdana",16,0,true)
            textField.x=60;
            textField.y=2;
            addChild(textField);
        }
        private function onKeyEventHandler(e:KeyboardEvent):void
        {
            switch (e.keyCode)
            {
                case Keyboard.A :
                case Keyboard.LEFT :
                    isLeft=e.type == KeyboardEvent.KEY_DOWN;
                    break;
                case Keyboard.D :
                case Keyboard.RIGHT :
                    isRight=e.type == KeyboardEvent.KEY_DOWN;
                    break;
                case Keyboard.W :
                case Keyboard.UP :
                    jump();
                    break;
            }
            var dir:int;
            if (isLeft && isRight)
            {
                dir=moveDir;
                return;
            }
            else if (isLeft)
            {
                dir=-1;
            }
            else if (isRight)
            {
                dir=1;
            }
            else
            {
                dir=0;
            }
            if(dir==moveDir)
            {
                return;
            }
            else
            {
                moveDir=dir;
            }
            updateBehavior()
        }
        private function onEnterFrameHandler(_e:EnterFrameEvent):void
        {
            updateMove();
            WorldClock.clock.advanceTime(-1);
        }
        private function updateBehavior():void
        {
            if (isJumping)
            {
                return;
            }
            if (moveDir == 0)
            {
                speedX = 0;
                armature.animation.gotoAndPlay("stand");
            }
            else
            {
                speedX=6*moveDir;
                armatureClip.scaleX = -moveDir;
                armature.animation.gotoAndPlay("walk");
            }
        }
        private function updateMove():void
        {
            if (speedX != 0)
            {
                armatureClip.x += speedX;
                if (armatureClip.x < 0)
                {
                    armatureClip.x = 0;
                }
                else if (armatureClip.x > 800)
                {
                    armatureClip.x = 800;
                }
            }
            if (isJumping)
            {
                if (speedY <= 0 && speedY + 1 > 0 )
                {
                    armature.animation.gotoAndPlay("fall");
                }
                speedY += 1;
            }
            if (speedY != 0)
            {
                armatureClip.y += speedY;
                if (armatureClip.y > 540)
                {
                    armatureClip.y = 550;
                    isJumping = false;
                    speedY = 0;
                    updateBehavior();
                }
            }
        }
        private function jump():void
        {
            if (isJumping)
            {
                return;
            }
            speedY = -25;
            isJumping = true;
            armature.animation.gotoAndPlay("jump");
        }
    }
}

通过上面的代码我们可以发现,我们只需要在程序中需要播放相关骨骼动画的时候调用函数armature.animation.gotoAndPlay()即可。

除了指定需要播放的动作名称,你还可以通过此函数来动态指定动作的总帧数、是否循环等。

对于每个动画,除了指定其播放之外,DragonBones框架提供了动画播放相关的各种事件。

动作切换事件:

armature.addEventListener(dragonbones.events.Event.MOVEMENT_CHANGE, aramtureEventHandler);

动作开始事件:

armature.addEventListener(dragonbones.events.Event.START, aramtureEventHandler);

动作结束事件

armature.addEventListener(dragonbones.events.Event.COMPLETE, aramtureEventHandler);

动作循环完毕事件:

armature.addEventListener(dragonbones.events.Event.LOOP_COMPLETE, aramtureEventHandler);

通过各种事件与动作的配合,你可以轻松创建具有复杂运动角色的游戏。 

控制骨骼框架中的每根骨头

对于一个有趣的游戏,仅仅播放预先设置的骨骼动画或许不够,我们需要角色具有动态可控的各自动作。令人高兴的是DragonBones提供了访问并控制骨骼框架里每根骨头的方法,让你的角色在游戏中随意运动。

此示例通过鼠标在场景中的移动来控制骨骼。我们创建了一个跟随鼠标运动的小鸟,小龙人会与小鸟保持一定距离,同时小龙人的头和胳膊会跟随小鸟运动而做出不同姿势,非常有趣。

打开DBStarlingControlBone.as,代码如下。

package
{
    import dragonBones.Armature;
    import dragonBones.Bone;
    import dragonBones.animation.WorldClock;
    import dragonBones.factorys.StarlingFactory;
    import flash.geom.Point;
    import flash.ui.Mouse;
    import starling.display.Image;
    import starling.display.Sprite;
    import starling.events.EnterFrameEvent;
    import starling.events.TouchEvent;
    import starling.textures.Texture;
    import flash.events.Event;
    public class DBStarlingControlBone extends Sprite
    {
        [Embed(source = "../assets/Dragon2.png", mimeType = "application/octet-stream")]
        public static const ResourcesData:Class;
        [Embed(source = "../assets/starling.png")]
        private static const starlingImg:Class;
        private var factory:StarlingFactory;
        private var armature:Armature;
        private var armatureClip:Sprite;
        private var mouseX:Number = 0;
        private var mouseY:Number = 0;
        private var moveDir:int=0;
        private var dist:Number;
        private var speedX:Number = 0;
        private var starlingBird:Image;
        private var _r:Number;
        private var _head:Bone;
        private var _armR:Bone;
        private var _armL:Bone;
        public function DBStarlingControlBone()
        {
            factory = new StarlingFactory();
            factory.addEventListener(Event.COMPLETE, textureCompleteHandler);
            factory.parseData(new ResourcesData());
        }
        private function textureCompleteHandler(e:Event):void
        {
            armature = factory.buildArmature("Dragon");
            armatureClip = armature.display as Sprite;
            armatureClip.x = 400;
            armatureClip.y = 550;
            addChild(armatureClip);
            WorldClock.clock.add(armature);
            updateBehavior(0)
            addEventListener(EnterFrameEvent.ENTER_FRAME, onEnterFrameHandler);
            stage.addEventListener(TouchEvent.TOUCH, onMouseMoveHandler);
            starlingBird=new Image(Texture.fromBitmap(new starlingImg()))
            addChild(starlingBird);
            Mouse.hide();
            //get the bones which you want to control
            _head = armature.getBone("head");
            _armR = armature.getBone("armUpperR");
            _armL = armature.getBone("armUpperL");
        }
        private function onEnterFrameHandler(_e:EnterFrameEvent):void
        {
            checkDist();
            updateMove();
            updateBones();
            WorldClock.clock.advanceTime(-1);
        }
        private function checkDist():void
        {
            dist = armatureClip.x-mouseX;
            if(dist<150)
            {
                updateBehavior(1)
            }
            else if(dist>190)
            {
                updateBehavior(-1)
            }
            else
            {
                updateBehavior(0)
            }
        }
        private function onMouseMoveHandler(_e:TouchEvent):void
        {
            var _p:Point = _e.getTouch(stage).getLocation(stage);
            mouseX = _p.x;
            mouseY = _p.y;
            starlingBird.x=mouseX-73;
            starlingBird.y=mouseY-73;
        }
        private function updateBehavior(dir:int):void
        {
            if(moveDir==dir)return;
            moveDir=dir;
            if (moveDir == 0)
            {
                speedX = 0;
                armature.animation.gotoAndPlay("stand");
            }
            else
            {
                speedX=6*moveDir;
                armature.animation.gotoAndPlay("walk");
            }
        }
        private function updateMove():void
        {
            if (speedX != 0)
            {
                armatureClip.x += speedX;
                if (armatureClip.x < 0)
                {
                    armatureClip.x = 0;
                }
                else if (armatureClip.x > 800)
                {
                    armatureClip.x = 800;
                }
            }
        }
        private function updateBones():void
        {
            //update the bones' pos or rotation
            _r = Math.PI + Math.atan2(mouseY - armatureClip.y+armatureClip.height/2, mouseX - armatureClip.x);
            if (_r > Math.PI)
            {
                _r -= Math.PI * 2;
            }
            _head.node.rotation = _r*0.3       
            _armR.node.rotation = _r *0.8;
            _armL.node.rotation = _r * 1.5;
            starlingBird.rotation=_r*0.2;
        }
    }
}

从上面代码我们可以看到,通过方法dragonBones.Armature.getBone(_name:String):Bone来获取某个骨骼。骨骼中的node对象包含了此骨骼的位置坐标,旋转弧度,拉伸比例,倾斜数据等等。我们根据游戏逻辑的需要对骨骼的这些参数赋数,即可实现动态控制此骨骼的效果。

在上面示例中,请留意updateBones()函数里,我们先获取到当前鼠标位置与骨骼框架中心点的夹角,然后根据这个角度,来改变小龙人的头部和胳膊的旋转弧度,从而实现了这个有趣的效果。

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)