微信小游戏:Cocos Creator抛物线掉落路径

抛物线掉落路径在我们制作游戏的过程当中是经常用到的,下面介绍一下我的抛物线路径思路和代码直线

思路

  • 在我们游戏中用到抛物线一般是有一个起始点,一个结束点,从起始点到结束点形成一个抛物线的路径。
  • 抛物线是怎么形成的呢,以二维平面为例,在x/y轴方向进行匀加速运动,在y/x轴进行匀速运动就会形成抛物线,如此一来,我们在制作抛物线的时候就容易了,只需要设定一个方向的速度,设定另一个方向的初始速度和加速度就可以形成抛物线了,然后每帧更新即可。
  • 聪明如你,一定想到了在三围空间也是相同的道理,只要把单独的一个轴改为二维单位向量就和二维平面一样了。

实现

cc.Class({
    extends: cc.Component,

    properties: {
    },

    onLoad : function() {
        this.start_position = null;
        this.Y_ACCELERATE_THRESHOLD = 30;  //Y轴是否是匀速运动的阈值
        this.y_speed = 0;  //Y轴的初始速度
        this.y_acceleration = 0; //Y轴的加速度
        this.x_speed = 0;  //X轴的初始速度
        this.x_acceleration = 0;  //Y轴的加速度

        this.start_Y_pos = 0;
        this.start_X_pos = 0;
        this.move_total_time = 0; //计算出的总的移动时间
        this.node.on(cc.Node.EventType.TOUCH_START, this.on_touch_begin, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.on_touch_end, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.on_touch_cancel, this);
    },  
    
    update : function(dt) 
    {
        if(this.is_moving_for_touch && this.move_total_time > 0)
        {
            this.move_total_time -= dt; //每帧更新移动时间
            this.start_X_pos -= this.x_speed * dt; //更新X轴坐标
            this.start_Y_pos -= this.y_speed * dt; //更新Y轴坐标
            this.node.setPosition(this.start_X_pos, this.start_Y_pos); //更新节点的位置
            this.x_speed -= this.x_acceleration * dt; //更新X轴速度
            this.y_speed -= this.y_acceleration * dt; //更新Y轴速度
        }
    },
    
    on_touch_begin : function(event)
    {
        this.start_position = event.getLocation();
    },

    on_touch_end : function(event)
    {
        var position = event.getLocation();
        if(Math.abs(position.x - this.start_position.x) > this.MOVE_THRESHOLD)
        {
            this.is_moving_for_touch = true;
            if(position.x - this.start_position.x > 0)
            {
                this.calc_parabola_efficient(this.node.position, this.controller.right_target_node.position);
            }
            else
            {
                this.calc_parabola_efficient(this.node.position, this.controller.left_target_node.position);
            }
            this.node.off(cc.Node.EventType.TOUCH_START, this.on_touch_begin, this);
            this.node.off(cc.Node.EventType.TOUCH_END, this.on_touch_end, this);
            this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.on_touch_cancel, this);
        }
    },
    
    on_touch_cancel : function(event)
    {
        var position = event.getLocation();
        if(Math.abs(position.x - this.start_position.x) > this.MOVE_THRESHOLD)
        {
            this.is_moving_for_touch = true;
            if(position.x - this.start_position.x > 0)
            {
                this.calc_parabola_efficient(this.node.position, this.controller.right_target_node.position);
            }
            else
            {
                this.calc_parabola_efficient(this.node.position, this.controller.left_target_node.position);
            }
            this.node.off(cc.Node.EventType.TOUCH_START, this.on_touch_begin, this);
            this.node.off(cc.Node.EventType.TOUCH_END, this.on_touch_end, this);
            this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.on_touch_cancel, this);
        }
    },

    calc_parabola_efficient : function(start_pos, end_pos)
    {
        this.start_X_pos = start_pos.x;
        this.start_Y_pos = start_pos.y;

        var speed = 300;

		//起始点与结束点高度差大于阈值,半条抛物线也就是只有加速过程, Y轴匀速运动,X轴加速运动
        if(start_pos.y - end_pos.y > this.Y_ACCELERATE_THRESHOLD) 
        {
            var x_distance = Math.abs(start_pos.x - end_pos.x);
            var y_distance = Math.abs(start_pos.y - end_pos.y);
            this.move_total_time = Math.sqrt(x_distance * x_distance + y_distance * y_distance) / speed;   //计算总的移动时间
            var x_speed = x_distance / this.move_total_time; //计算X轴的平均速度
            this.y_speed = y_distance / this.move_total_time; //计算Y轴的速度
            this.y_acceleration = 0; //Y轴匀速运动,不需要加速度,设为0
            if(end_pos.x > start_pos.x) //根据起始点的坐标判断移动速度的方向
            {
                this.x_speed = -x_speed * 1.5;  //计算初始速度,调整参数1.5可以改变抛物线形状
                this.x_acceleration = -x_speed / this.move_total_time; //计算X轴加速度
            }
            else
            {
                this.x_speed = x_speed * 1.5; //计算初始速度,调整参数1.5可以改变抛物线形状
                this.x_acceleration = x_speed / this.move_total_time; //计算X轴加速度
            }

        }
        //需要Y轴做加速运动形成抛物线,因为小于阈值,所以需要先到达最高点
        else
        {
            var x_distance = start_pos.x - end_pos.x;
            var y_distance = Math.abs(start_pos.y - end_pos.y);
            this.move_total_time = Math.sqrt(x_distance * x_distance + y_distance * y_distance) / speed;
            this.x_speed = x_distance / this.move_total_time; //X轴匀速运动,X轴的速度
            this.x_acceleration = 0;  //匀速运动不需要加速度,设为0 

            var highest_y = Math.max(start_pos.y, end_pos.y) + y_distance;  //计算最高点的位置,距离设为2倍高度差,可以调整参数y_distance的系数来改变抛物线最高点,来调整抛物线形状

			//抛物线移动氛围两段,一段是移动到最高点,另一段是从最高点移动到目标点,因为x轴匀速运动,所以我们只需要关心Y轴就可以了
            var d1 = highest_y - start_pos.y;
            var d2 = highest_y - end_pos.y;

            var t1 = this.move_total_time / (1 + Math.sqrt(d1 / d2)); //上升段的时间
            var t2 = this.move_total_time - t1; //下降段的时间

            this.y_acceleration = -(2 * d1) / (t1 * t1); //因为是匀加速运动,所以用任何一段计算加速度都可以
            this.y_speed = this.y_acceleration * t1; //计算Y轴的初始速度,因为是匀减速,且到达最高点时速度一定为零,所以可以直接计算得出Y轴初始速度
        }
    },

以上就是简单又漂亮的抛物线制作思路和实现。

推广一下自己做的简单的小游戏
微信小游戏:Cocos Creator抛物线掉落路径_第1张图片
微信小游戏:Cocos Creator抛物线掉落路径_第2张图片
创建了一个小游戏交流群,如果过期或者满了或者有问题交流 可以加我微信 备注“微信小游戏”
微信小游戏:Cocos Creator抛物线掉落路径_第3张图片
微信小游戏:Cocos Creator抛物线掉落路径_第4张图片

你可能感兴趣的:(微信小游戏:Cocos Creator抛物线掉落路径)