【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 mapPanel extends cc.Component {@property(cc.Node)player: cc.Node = null;@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], [5, 1], [5, 3], [2, 5]],startPosId: 2,road: [2, 5, 1, 4]}data.mapData.forEach(element => {this.creatOneBuild(element, data.startPosId)});this.player.position = data.mapData[data.startPosId - 1].posdata.linkData.forEach(element => {this.setPoint(cc.v2(data.mapData[element[0] - 1].pos), cc.v2(data.mapData[element[1] - 1].pos))});let roadArray = []data.road.forEach((element) => {roadArray.push(data.mapData[element - 1].pos);})this.playTween(roadArray);}playTween(roadArray, moveSpeed = 0.003, time = 1.5, delayTime = 0.3, cb?) {let tween = cc.tween(this.player)let nowPos = roadArray[0]for (let i = 1; i < roadArray.length; i++) {let nextPos = roadArray[i]let pointArr = this.getOneroad(nowPos, nextPos, 1)let speed = moveSpeedif (pointArr.length * moveSpeed > time) speed = (time / pointArr.length)// if (speed > moveSpeed) speed = moveSpeedpointArr.forEach(element => {tween.to(speed, { position: element })});tween.delay(delayTime)nowPos = nextPos;}tween.call(() => {cb && cb()}).start();}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 pointArr = this.getOneroad(startPoint, endPoint, pointDistance, angel)pointArr.forEach(element => {this.creatOnePoint(element)console.log(element);//每个小圆点点坐标,这里进行处理});}/*** 获取n点之间路径* @param startPoint 起点* @param endPoint 终点* @param pointDistance 小点间距* @param angel 弧度*/getTotalRoad(arrList, pointDistance = 30, angel = 60) {let pointArrTotal = []let nowPos = pointArrTotal.shift()let list = arrList;while (1) {let nextPos = list.shift()if (nextPos) {let pointArr = this.getOneroad(nowPos, nextPos, pointDistance, angel)pointArrTotal = pointArrTotal.concat(pointArr)nowPos = nextPos;}else {break;}}return pointArrTotal}/*** 获取两点之间路径* @param startPoint 起点* @param endPoint 终点* @param pointDistance 小点间距* @param angel 弧度*/getOneroad(startPoint, endPoint, pointDistance = 30, angel = 60) {startPoint = cc.v2(startPoint);endPoint = cc.v2(endPoint);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)return pointArr;}/*** 获取两点之间垂直平分线线上的点* @param startPoint * @param endPoint * @param bcLength * @returns */findPointCInRightTriangle(startPoint: cc.Vec2, endPoint: cc.Vec2, bcLength: number, isUP = true): 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 * (isUP ? -1 : 1);const cy = ay + acLength * acUnitY * (isUP ? -1 : 1);return cc.v2(cx, cy);}/*** 获取贝塞尔曲线上的点* @param {返回的点的数组长度} num * @param {起点} startPoint * @param {控制点} middlePoint * @param {终点} endPoint */getBezierPoints(num, startPoint, middlePoint, endPoint) {let pointList = [];let x1 = startPoint.x, y1 = startPoint.y;let x2 = endPoint.x, y2 = endPoint.y;let cx = middlePoint.x, cy = middlePoint.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) {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/810181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024 年 3 月 Web3 游戏报告:市场趋势与投资动态

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;Footprint Analytics GameFi Research 2024 年 3 月&#xff0c;比特币不断刷新纪录&#xff0c;成功跨越了月中的低谷。受益于宏观经济的积极态势&#xff0c;整个加密货币市场表现突出。与此同时&#xff0c…

宠物医院电子处方软件操作教程,兽医处方笺范例经验分享

宠物医院电子处方软件操作教程&#xff0c;兽医处方笺范例经验分享 一、前言 以下软件操作教程以&#xff0c;佳易王宠物店兽医电子处方管理系统软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 软件基本功能&#xff1a;权限管理&#xff…

Vscode设置滚轮进行字体大小的调节

Vscode设置滚轮进行字体大小的调节 正常的话按 ctrl 或者 ctrl - 进行字体的大小调节 1.打开Vscode&#xff0c;找打设置的图标&#xff0c;在点击设置&#xff0c;或者直接使用快捷键&#xff0c;【ctrl ,】 2. 在搜索框搜索Font Ligatures 3.双击进入settings.json ,找到如…

手持气象站功能介绍

TH-SQ5手持气象站是一种便携式设备&#xff0c;用于手动测量和记录气象参数&#xff0c;如温度、湿度、风速和气压。这些设备通常用于户外活动、教育和业余气象观测。以下是对机械式手持气象站的一些续写内容&#xff1a; 数据记录功能&#xff1a;虽然基本型号的机械式手持气象…

本地开发nginx代理服务器(2024-04-10)

1、nginx 解释 nginx 是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/POP3/SMTP 代理服务器。 在性能上&#xff0c;Nginx占用很少的系统资源&#xff0c;能支持更多的并发连接&#xff0c;达到更高的访问效率&#xff1b; 在功能上&#xff0c;Nginx是优…

密码学 | 椭圆曲线 ECC 密码学入门(二)

目录 4 椭圆曲线&#xff1a;更好的陷门函数 5 奇异的对称性 6 让我们变得奇特 ⚠️ 原文地址&#xff1a;A (Relatively Easy To Understand) Primer on Elliptic Curve Cryptography ⚠️ 写在前面&#xff1a;本文属搬运博客&#xff0c;自己留着学习。如果你和我一样…

2024妈妈杯mathorcup B题详细思路代码:甲骨文智能识别中原始拓片单字自动分割与识别研究

甲骨文智能识别中原始拓片单字自动分割与识别研究&#xff1a; 问题一&#xff1a; 图像预处理&#xff1a;这通常包括将图像转换为灰度图&#xff0c;剔除噪声&#xff0c;调整对比度&#xff0c;以及可能的二值化处理&#xff0c;使得甲骨文的特征更加突出。此外&#xff0c…

2024年第十四届 Mathorcup (B题)| 甲骨文智能识别 | 深度学习 计算机视觉 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看Mathorcup (B题&#xff09;&#xff01; CS团队…

【随笔】Git 高级篇 -- 整理提交记录(下)rebase -i(十六)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

如何在Windows通过固定tcp公网地址ssh远程访问本地Kali Linux

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 本文主要介绍如何在Kali系统编辑SSH配置文件并结合cpolar内网穿透软件&#xff0c;实现公网环境ssh远程连接本地kali系统。 1. 启…

操作系统③ —— 文件管理

前言 操作系统对文件管理中需要对磁盘块进行管理。这其中包含对空闲磁盘块和非空闲磁盘块的管理 对空闲磁盘块的管理涉及文件存储空间的管理。对非空闲磁盘块的管理涉及文件的物理结构/文件的分配方式。 1. 文件存储空间管理 1.1 存储空间的划分与初始化 存储空间的划分&a…

【Linux学习】初识Linux指令(一)

文章目录 1.指令操作与图形化界面操作1.什么是指令操作&#xff0c;什么是图形化界面操作&#xff1f; 2.Linux下基本指令1.Linux下的复制粘贴2.Linux两个who命令3.补充知识4.pwd指令5. ls 指令6.cd 指令1.目录树2.相对路径与绝对路劲3.常用cd指令 7.tree指令8. touch指令9.sta…

需求调研和程序员有关系吗?

很多程序员可能都觉得&#xff0c;需求调研是产品经理或者需求分析师的事情&#xff0c;我只需要负责拿到写到的需求规格说明书来开发就好了&#xff0c;为什么要参与需求调研。但结合笔者从业经历来说&#xff0c;程序员其实应该在一定程度上参与到需求调研中&#xff0c;无论…

CST软件中变更求解器和宏的使用技巧【操作教程】

变更求解器 变更CST MWS中的Solver&#xff01; Home > Simulation > Setup Solver CST Microwave Studio (CST MWS)总共有六个Solver。用户根据仿真目的和应用方向选择合适的Solver&#xff0c;才可以快速获得准确的结果。变更或选择Solver时&#xff0c;在Setup Sol…

SpringBoot项目整合ACTable实现实体类快速生产数据库表

1.安装 ACTable依赖 <dependency> <groupId>com.gitee.sunchenbin.mybatis.actable</groupId> <artifactId>mybatis-enhance-actable</artifactId> <version>1.5.0.RELEASE</version> </dependency> 使用mybatis…

【LAMMPS学习】八、基础知识(1.4)多副本模拟

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

Redis 高可用

redis高可用介绍 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;除了保证提…

android平台下opencv的编译--包含扩展模块

由于项目需要使用安卓平台下opencv的扩展库&#xff0c;对于通用的opencv库&#xff0c; opencv官网提供了android的SDK 但未能提供扩展库&#xff0c;因此需要自己进行源码编译。本文记录android平台下opencv及其扩展库的交叉编译。 前提&#xff1a;主机已安装android-ndk交…

玩美移动珠宝虚拟试戴解决方案引入glTF 2.0格式支持

领先的AIAR美妆和时尚科技解决方案提供商&#xff0c;以及"美丽AI"解决方案开发商 — 玩美移动于今日宣布&#xff0c;其AI珠宝虚拟试戴解决方案升级版本&#xff0c;性能得以显著提升。通过此次更新&#xff0c;玩美移动系统现可支持glTF 2.0&#xff08;图形库传输…

启明智显技术分享|ESP32-C3助力Model 3C芯片86盒彩屏开发板实现3MB波特率OTA程序升级和单独图片升级

在物联网快速发展的今天&#xff0c;彩屏显示作为人机交互的重要一环&#xff0c;其显示效果和升级便利性成为了衡量产品竞争力的关键指标。而Model 3C(以下简称M3C芯片&#xff09;与ESP32-C3的结合&#xff0c;无疑为物联网彩屏领域应用奠定了坚实的基石。 M3C芯片 是启明智…