cocos龙骨案例分析:机器人如何完成瞄准点击位置的动作

我们要分析的就是cocos create 官方给出的那个机器人,如何完成瞄准触摸点并不断随着触摸点进行动作更新动作。
在这里插入图片描述
实际上机器人关于转向的只有向上和向下瞄准这两个动作。

在这里插入图片描述
完成丰富的转向动作考靠的是动画的weight属性,这个变量时控制本龙骨某个动画动作幅度的一个属性,我们可以通过改变它来改变动作的幅度,取值是[0,1]。
具体的操作如下面的代码(ps:这段代码加载龙骨节点下面):

        // 获取龙骨的属性
        this._armatureDisplay = this.getComponent(dragonBones.ArmatureDisplay);
        this._armature = this._armatureDisplay.armature();
        // 播放要播放的动画,并声明变量记录播放动画函数的返回值
        this._aimState = this._armature.animation.fadeIn(
            "aimUp", 0, 1,
            0, "aim", 2
        );
        //|||||||||||||||||||||||||||||||||||
        //下面是关键!!!
        //这里既是改变动作幅度的方法,通过给weight赋值
        //来改变举枪的动作!!!
        this._aimState.weight=0.2;

执行代码的效果如下:
在这里插入图片描述
我们发现这个机器值进行的原来动作幅度的0.2,只是上举了一小点儿。这既是完成这些动作的核心

完整的不断对触摸点瞄准的动作就是基于这个原理来完成。首先通过Math.atan2()函数,以机器人为原点,触摸点为坐标的夹角的值R(这个是我自己设的变量),并把值R按比例转换为0到1之间。最后在update()函数中不断调用,把值R赋给weight,就完成了机器的武器的转向了。

完整的跟随触摸点变化的代码如下(要加在机器人的节点下面):

cc.Class({
    extends: cc.Component,

    properties: {
       touchHandler:{
           default:null,
           type:cc.Node,
       },
       _aimDir:0,
       _aimRadian:0,
       _aimState : null,
       _target : cc.v2(0, 0),
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.touchHandler.on(cc.Node.EventType.TOUCH_START, event => {
            var touches = event.getTouches();
            var touchLoc = touches[0].getLocation();
            this.aim(touchLoc.x, touchLoc.y);
            //this.attack(true);
        }, this);
        this.touchHandler.on(cc.Node.EventType.TOUCH_END, event => {
            //this.attack(false);
        }, this);
        this.touchHandler.on(cc.Node.EventType.TOUCH_MOVE, event => {
            var touches = event.getTouches();
            var touchLoc = touches[0].getLocation();
            this.aim(touchLoc.x, touchLoc.y);
        }, this);
    },

    start() {
     this._armatureDisplay = this.getComponent(dragonBones.ArmatureDisplay);
        this._armature = this._armatureDisplay.armature();
    },

    /**
     * 获取瞄准目标
     */
    aim(x,y){
        if (this._aimDir === 0) {
            this._aimDir = 10;
        }

        this._target = this.node.parent.convertToNodeSpaceAR(cc.v2(x, y));
    },
    
    update (dt) {
        this._updateAim();
    },
    
    _updateAim () {
        if (this._aimDir === 0) {
            return;
        }

        //决定机器人开火的Y轴方向
        this._faceDir = this._target.x > this.node.x ? 1 : -1;
        //通过改变机器人的scaleX的数值来对机器人的转身进行改变
        if (this.node.scaleX * this._faceDir < 0) {
            this.node.scaleX *= -1;
            if (this._moveDir) {
                this._updateAnimation();
            }
        }

        //获取胸部骨骼的世界坐标
        //var global = this._armature.getBone("chest").global;
        var aimOffsetY = this._armature.getBone("chest").global.y ;//* this.node.scaleY;
        //var bonePos = this.node.parent.convertToNodeSpaceAR(cc.v2(global.x, global.y));
        //cc.log(this._target.y-bonePos.y,this._target.x-bonePos.x);

        //获取夹角的值
        if (this._faceDir > 0) {
            this._aimRadian = Math.atan2((this._target.y - this.node.y + aimOffsetY), this._target.x - this.node.x);
        } else {
            this._aimRadian = Math.PI - Math.atan2((this._target.y - this.node.y + aimOffsetY), this._target.x - this.node.x);
            if (this._aimRadian > Math.PI) {
                this._aimRadian -= Math.PI * 2;
            }
        }

        let aimDir = 0;
        if (this._aimRadian < 0) {
            aimDir = -1;
        } else {
            aimDir = 1;
        }

        if (this._aimDir != aimDir) {
            this._aimDir = aimDir;

            // Animation mixing.
            if (this._aimDir >= 0) {
                this._aimState = this._armature.animation.fadeIn(
                    "aimUp", 0, 1,
                    0, "normal", 2
                );
            } else {
                this._aimState = this._armature.animation.fadeIn(
                    "aimDown", 0, 1,
                    0, "normal", 2
                );
            }
            // Add bone mask.
            //_aimState.addBoneMask("pelvis");
        }

        this._aimState.weight = Math.abs(this._aimRadian / Math.PI * 2);
        //_armature.invalidUpdate("pelvis"); // Only update bone mask.
        this._armature.invalidUpdate();
    },
});
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值