【cocos creator】【TS】贝塞尔曲线,地图之间显示曲线
参考:
https://blog.csdn.net/Ctrls_/article/details/108731313
https://blog.csdn.net/qq_28299311/article/details/104009804
const { ccclass, property } = cc._decorator;@ccclass
export default class creatPoint extends cc.Component {@property(cc.Node)build: cc.Node = null;@property(cc.Node)point: cc.Node = null;@property(cc.Node)root: cc.Node = null;start() {this.init();}init(data?) {data = {mapData: [{ id: 1, name: "1", pos: { x: 0, y: 100 } },{ id: 2, name: "2", pos: { x: -100, y: -100 } },{ id: 3, name: "3", pos: { x: 200, y: -80 } },{ id: 4, name: "4", pos: { x: 180, y: 300 } },{ id: 5, name: "5", pos: { x: 150, y: 50 } }],linkData: [[2, 1], [1, 4], [1, 5], [5, 3], [2, 5]],startPosId: 2,}data.mapData.forEach(element => {this.creatOneBuild(element, data.startPosId)});data.linkData.forEach(element => {this.setPoint(cc.v2(data.mapData[element[0] - 1].pos), cc.v2(data.mapData[element[1] - 1].pos))});}creatOneBuild(data, nowId) {let build = cc.instantiate(this.build);build.parent = this.root;build.position = cc.v3(data.pos);build.getChildByName("name").getComponent(cc.Label).string = data.name;build.active = true;build.getChildByName("light").active = nowId == data.id;}creatOnePoint(pos: cc.Vec3) {let build = cc.instantiate(this.point);build.parent = this.root;build.position = pos;build.active = true;}/*** * @param startPoint 起点* @param endPoint 终点* @param pointDistance 小点间距* @param angel 弧度*/setPoint(startPoint, endPoint, pointDistance = 30, angel = 60) {let distance = startPoint.sub(endPoint).mag();let middlePoint = cc.v2((startPoint.x + endPoint.x) / 2, (startPoint.y + endPoint.y) / 2)let height = Math.sin(angel * (180 / Math.PI)) * (distance / 2) * 1.5;cc.log(height)let middlePoint2 = this.findPointCInRightTriangle(startPoint, middlePoint, height);let number = Number((distance / pointDistance).toFixed(0));let pointArr = this.getBezierPoints(number, startPoint, height ? middlePoint2 : middlePoint, endPoint)pointArr.forEach(element => {this.creatOnePoint(element)console.log(element);//每个小圆点点坐标,这里进行处理});}getAngle(y1, x1, y2, x2) {const radians = Math.atan2(y2 - y1, x2 - x1);const degrees = radians * (180 / Math.PI);return degrees;}findPointCInRightTriangle(startPoint: cc.Vec2, endPoint: cc.Vec2, bcLength: number): cc.Vec2 | null {let ax = endPoint.x;let ay = endPoint.y;let bx = startPoint.x;let by = startPoint.y;// 计算向量AB const dx = bx - ax;const dy = by - ay;// 计算AB的长度 const abLength = Math.sqrt(dx * dx + dy * dy);// 检查AB长度是否为零,以避免除以零的错误 if (abLength === 0) {return null; // 无法确定C点位置,因为AB长度为0 }// 计算AC的长度(利用勾股定理) const acLength = Math.sqrt(bcLength * bcLength - abLength * abLength);// 计算向量AB的单位向量 const abUnitX = dx / abLength;const abUnitY = dy / abLength;// 计算向量AC,它垂直于向量AB(因为ABC是直角三角形) const acUnitX = -abUnitY; // 垂直向量的x分量是原向量y分量的相反数 const acUnitY = abUnitX; // 垂直向量的y分量是原向量x分量 // 计算点C的坐标 const cx = ax - acLength * acUnitX;const cy = ay - acLength * acUnitY;return cc.v2(cx, cy);}/*** * @param {返回的点的数组长度} num * @param {起点} point1 * @param {控制点} point2 * @param {终点} point3 */getBezierPoints(num, point1, point2, point3) {let pointList = [];let x1 = point1.x, y1 = point1.y;let x2 = point3.x, y2 = point3.y;let cx = point2.x, cy = point2.y;let t = 0;for (let i = 1; i < (num + 1); i++) {//用i当作t,算出点坐标,放入数组t = i / num;let x = Math.pow(1 - t, 2) * x1 + 2 * t * (1 - t) * cx + Math.pow(t, 2) * x2;let y = Math.pow(1 - t, 2) * y1 + 2 * t * (1 - t) * cy + Math.pow(t, 2) * y2;pointList.push(cc.v2(x, y))}return pointList;}// update (dt) {}
}