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

发布时间:2025-05-19 08:45

思路

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.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 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({

// foo: {

// },

// ...

map: {

type: gen_map_path,

default: null,

},

speed: 100,

},

},

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++;

}

},

update: function(dt) {

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

this.walk_update(dt);

}

},

});

网址:cocos creator动画编辑器编辑地图路径 http://www.mxgxt.com/news/view/1279513

相关内容

明星博主都在用的图片编辑神器
《影视制作》编辑部
明星博主都在用的图片编辑软件推荐
明星时尚编辑
编程逻辑关系是什么意思
时尚编辑CHEN
为古书画延续生机(编辑手记)
在《VOGUE》做时尚编辑.doc
时尚新媒体IVYPLUME招募新媒体编辑、美术编辑、造型协助
时尚编辑岗位职责

随便看看