zoukankan      html  css  js  c++  java
  • cocos creator基础-(二十九)动画编辑器编辑地图路径

    思路

    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);
            }
        },
    });
  • 相关阅读:
    AOP
    资料
    有用快捷键
    Java中getResourceAsStream的用法
    【转载】URL编码与两次encodeURI
    maven 如何使用
    MyEclipse运行Java出错:could not find the main class:test.program will exit(导入项目)
    java集合的操作(set,Iterator)
    java类集框架(ArrayList,LinkedList,Vector区别)
    java线程控制安全
  • 原文地址:https://www.cnblogs.com/orxx/p/10560390.html
Copyright © 2011-2022 走看看