美文网首页
cocos creator动画编辑器编辑地图路径

cocos creator动画编辑器编辑地图路径

作者: 游戏开发大表哥 | 来源:发表于2019-07-10 15:20 被阅读0次

    思路

    1、利用动画编辑器,设置一个路径,多个路径就编辑多个动画

    2、用特定的代码对动画进行处理,获取到路径坐标,大佬已经写好代码, 不用自己重复造轮子了(微元法求曲线长度)

      获得动画路径的贝塞尔曲线方程

      求得每一段贝塞尔曲线的长度

      每隔一小段打一个点

      最终生成一个路径

    3、编写寻路脚本,挂载到物体上,让沿着路径移动

    动画编辑

    脚本挂载

    // gen_map_path.js 动画路径转换坐标的代码 已经升级到2.x

    cc.Class({

        extends: cc.Component,

        properties: {

            // foo: {

            //    default: null,      // The default value will be used only when the component attaching

            //                           to a node for the first time

            //    url: cc.Texture2D,  // optional, default is typeof default

            //    serializable: true, // optional, default is true

            //    visible: true,      // optional, default is true

            //    displayName: 'Foo', // optional

            //    readonly: false,    // optional, default is false

            // },

            // ...

            is_debug: false,

        },

        // use this for initialization

        onLoad: function() {

            this.anim_com = this.node.getComponent(cc.Animation);

            var clips = this.anim_com.getClips();

            var clip = clips[0];

            var newNode = new cc.Node();

            this.new_draw_node = newNode.getComponent(cc.Graphics);

            if (!this.new_draw_node) {

                this.new_draw_node = this.node.addComponent(cc.Graphics);

            }

            this.node.addChild(newNode);

            // this.draw_node = new cc.DrawNode();

            // this.node._sgNode.addChild(this.draw_node);

            var paths = clip.curveData.paths;

            // console.log(paths);

            this.road_data_set = [];

            var k;

            for (k in paths) {

                var road_data = paths[k].props.position;

                this.gen_path_data(road_data);

            }

        },

        start: function() {

            /*

            // test()

            var actor = cc.find("UI_ROOT/map_root/ememy_gorilla").getComponent("actor");

            // actor.gen_at_road(this.road_data_set[0]);

            actor = cc.find("UI_ROOT/map_root/ememy_small2").getComponent("actor");

            // actor.gen_at_road(this.road_data_set[1]);

            actor = cc.find("UI_ROOT/map_root/ememy_small3").getComponent("actor");

            actor.gen_at_road(this.road_data_set[2]);

            */

            // end 

        },

        get_road_set: function() {

            return this.road_data_set;

        },

        gen_path_data: function(road_data) {

            var ctrl1 = null;

            var start_point = null;

            var end_point = null;

            var ctrl2 = null;

            var road_curve_path = []; // [start_point, ctrl1, ctrl2, end_point],

            for (var i = 0; i < road_data.length; i++) {

                var key_frame = road_data[i];

                if (ctrl1 !== null) {

                    road_curve_path.push([start_point, ctrl1, ctrl1, cc.p(key_frame.value[0], key_frame.value[1])]);

                }

                start_point = cc.p(key_frame.value[0], key_frame.value[1]);

                for (var j = 0; j < key_frame.motionPath.length; j++) {

                    var end_point = cc.p(key_frame.motionPath[j][0], key_frame.motionPath[j][1]);

                    ctrl2 = cc.p(key_frame.motionPath[j][2], key_frame.motionPath[j][3]);

                    if (ctrl1 === null) {

                        ctrl1 = ctrl2;

                    }

                    // 贝塞尔曲线 start_point, ctrl1, ctrl2, end_point,

                    road_curve_path.push([start_point, ctrl1, ctrl2, end_point]);

                    ctrl1 = cc.p(key_frame.motionPath[j][4], key_frame.motionPath[j][5]);

                    start_point = end_point;

                }

            }

            console.log(road_curve_path);

            var one_road = [road_curve_path[0][0]];

            for (var index = 0; index < road_curve_path.length; index++) {

                start_point = road_curve_path[index][0];

                ctrl1 = road_curve_path[index][1];

                ctrl2 = road_curve_path[index][2];

                end_point = road_curve_path[index][3];

                var len = this.bezier_length(start_point, ctrl1, ctrl2, end_point);

                var OFFSET = 16;

                var count = len / OFFSET;

                count = Math.floor(count);

                var t_delta = 1 / count;

                var t = t_delta;

                for (var i = 0; i < count; i++) {

                    var x = start_point.x * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.x * t * (1 - t) * (1 - t) + 3 * ctrl2.x * t * t * (1 - t) + end_point.x * t * t * t;

                    var y = start_point.y * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.y * t * (1 - t) * (1 - t) + 3 * ctrl2.y * t * t * (1 - t) + end_point.y * t * t * t;

                    one_road.push(cc.p(x, y));

                    t += t_delta;

                }

            }

            console.log(one_road);

            if (this.is_debug) {

                this.new_draw_node.clear(); // 清除以前的

                for (var i = 0; i < one_road.length; i++) {

                    this.new_draw_node.moveTo(one_road[i].x, one_road[i].y);

                    this.new_draw_node.lineTo(one_road[i].x + 1, one_road[i].y + 1);

                    this.new_draw_node.stroke();

                    // this.draw_node.drawSegment(one_road[i],

                    //     cc.p(one_road[i].x + 1, one_road[i].y + 1),

                    //     1, cc.color(255, 0, 0, 255));

                }

            }

            this.road_data_set.push(one_road);

        },

        bezier_length: function(start_point, ctrl1, ctrl2, end_point) {

                // t [0, 1] t 分成20等分 1 / 20 = 0.05

                var prev_point = start_point;

                var length = 0;

                var t = 0.05;

                for (var i = 0; i < 20; i++) {

                    var x = start_point.x * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.x * t * (1 - t) * (1 - t) + 3 * ctrl2.x * t * t * (1 - t) + end_point.x * t * t * t;

                    var y = start_point.y * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.y * t * (1 - t) * (1 - t) + 3 * ctrl2.y * t * t * (1 - t) + end_point.y * t * t * t;

                    var now_point = cc.p(x, y);

                    var dir = now_point.sub(prev_point);

                    prev_point = now_point;

                    length += dir.mag();

                    t += 0.05;

                }

                return length;

            }

            // called every frame, uncomment this function to activate update callback

            // update: function (dt) {

        // },

    });

    // actor.js 角色沿路径行走代码

    var gen_map_path = require("gen_map_path");

    var State = {

        Idle: 0,

        Walk: 1,

        Attack: 2,

        Dead: 3,

    };

    cc.Class({

        extends: cc.Component,

        properties: {

            // foo: {

            //    default: null,      // The default value will be used only when the component attaching

            //                           to a node for the first time

            //    url: cc.Texture2D,  // optional, default is typeof default

            //    serializable: true, // optional, default is true

            //    visible: true,      // optional, default is true

            //    displayName: 'Foo', // optional

            //    readonly: false,    // optional, default is false

            // },

            // ...

            map: {

                type: gen_map_path,

                default: null,

            },

            speed: 100,

        },

        // use this for initialization

        onLoad: function() {

        },

        start: function() {

            var road_set = this.map.get_road_set();

            this.cur_road = road_set[0];

            if (this.cur_road < 2) {

                return;

            }

            this.state = State.Idle;

            var pos = this.cur_road[0];

            this.node.setPosition(pos);

            this.walk_to_next = 1;

            this.start_walk();

        },

        start_walk: function() {

            if (this.walk_to_next >= this.cur_road.length) {

                // 攻击逻辑

                this.state = State.Attack;

                // 

                return;

            }

            var src = this.node.getPosition();

            var dst = this.cur_road[this.walk_to_next];

            var dir = dst.sub(src);

            var len = dir.mag();

            this.vx = this.speed * dir.x / len;

            this.vy = this.speed * dir.y / len;

            this.walk_total_time = len / this.speed;

            this.walked_time = 0;

            this.state = State.Walk;

        },

        walk_update: function(dt) {

            if (this.state != State.Walk) {

                return;

            }

            this.walked_time += dt;

            if (this.walked_time > this.walk_total_time) {

                dt -= (this.walked_time - this.walk_total_time);

            }

            var sx = this.vx * dt;

            var sy = this.vy * dt;

            this.node.x += sx;

            this.node.y += sy;

            if (this.walked_time >= this.walk_total_time) {

                this.walk_to_next++;

                this.start_walk();

            }

        },

        // called every frame, uncomment this function to activate update callback

        update: function(dt) {

            if (this.state == State.Walk) {

                this.walk_update(dt);

            }

        },

    });点击链接加入群聊【cocos/unity交流群】

    相关文章

      网友评论

          本文标题:cocos creator动画编辑器编辑地图路径

          本文链接:https://www.haomeiwen.com/subject/oyehkctx.html