Box2d 物理画线,Cocos Creator 3.8

一个简易的画线刚体Demo

效果

8f47de634e1b0ed99c34556f5d6d6bce.gif

抱歉,放错图了,以上是 孙二喵 iwae https://forum.cocos.org/t/topic/142673[1] 的效果图。本Demo是根据文章的思路,合成的代码。首先,感谢孙二喵的技术分享。

以下是最终效果图

02574b9799258f43a7ab84bce6bc59cf.gif

使用

版本 Cocos Creator 3.8.1

  1. 创建一个 Empty(2D) 项目

f080e303ac7117572eee3075628d1c09.png
  1. 保存场景,新建一个 Game.ts 脚本,把代码复制进去(代码在最后面)

bf29203dee0e723e495237a74ec56580.png
  1. 拖入Game.ts脚本至场景中

697e7c5f2482ba82e398caca0bf8602c.png
  1. (可选)在场景中添加一些静态刚体和碰撞体

0a3c17841e62746acc9b6bd2772787ba.png
  1. 运行预览

原理

坐标转换

触点坐标转到节点坐标

  • getUILocation

  • UITransform.convertToNodeSpaceAR

推荐阅读纯干货!一文搞懂 Cocos Creator 3.0 坐标转换原理

https://mp.weixin.qq.com/s/mV5EY4NMrpgCP9XFocrcGA

计算碰撞体

首先问题分解:已知:

  • 两个点的坐标

  • 线宽

求:

  • 围成该线段的四个点的坐标

297ccd958184676ae53e8db378ac5426.png

回顾一下,2D中的旋转的矩阵是:

旋转90度的矩阵为

旋转-90度的矩阵为

先计算方向向量,然后2个垂直方向的向量,分别乘以我们线段一半的宽度,最后起始点和结束点分别加上这2个向量,4个路径点

//方向向量
d = (end - start).normalize();
//垂直向量1
d1 = R_1 * d = (d.y,-d.x)
//垂直向量2
d2 = R_2 * d = (-d.y,d.x)
//求4个点
p1 = start + d1 * widhtHalf
p2 = start + d2 * widhtHalf
p3 = end + d1 * widhtHalf
p4 = end + d2 * widhtHalf
6fc75ae2fe13d5d1f91cdd916452f5d3.png

代码

import { _decorator, Component, EventTouch, find, Node, macro, Graphics, v2, Vec2, UITransform, v3, Color, RigidBody2D, PolygonCollider2D, PhysicsSystem2D } from 'cc';
const { ccclass, property } = _decorator;const __tempV2 = v2()
const __tempV3 = v3()type TypePoint = {x: number,y: number
}@ccclass('Game')
export class Game extends Component {private _canvasNode: Nodestart() {macro.ENABLE_MULTI_TOUCH = false;PhysicsSystem2D.instance.debugDrawFlags = 1;this._canvasNode = find("Canvas")this._canvasNode.on(Node.EventType.TOUCH_START, this.onTouchStart, this)this._canvasNode.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this)this._canvasNode.on(Node.EventType.TOUCH_END, this.onTouchEnd, this)this._canvasNode.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this)}private getUIPos(pos: Vec2) {__tempV3.set(pos.x, pos.y, 0)this._curGraphics.node.getComponent(UITransform).convertToNodeSpaceAR(__tempV3, __tempV3)pos.set(__tempV3.x, __tempV3.y)return pos;}private _curGraphics: Graphics;private onTouchStart(evt: EventTouch) {evt.getUILocation(__tempV2)this._pointList.length = 0;const node = new Node()node.layer = this._canvasNode.layer;this._canvasNode.addChild(node);this._curGraphics = node.addComponent(Graphics)this._curGraphics.strokeColor = Color.WHITE;this._curGraphics.lineWidth = 10;const { x, y } = this.getUIPos(__tempV2)this._curGraphics.moveTo(x, y)this._pointList.push({ x, y })}private _preK: number = 0private _pointList: TypePoint[] = []private onTouchMove(evt: EventTouch) {evt.getUILocation(__tempV2)const { x, y } = this.getUIPos(__tempV2)const { x: preX, y: preY } = this._pointList[this._pointList.length - 1];const diffX = x - preX;const diffY = y - preY;const dis = (Math.abs(diffX) + Math.abs(diffY))if (dis >= this._curGraphics.lineWidth) {const d = 0.001const curK = Math.abs(diffX) < d ? (Number.MAX_SAFE_INTEGER * Math.sign(diffX) * Math.sign(diffY)) : (diffY / diffX)if (this._pointList.length > 1) {const diffK = curK - this._preK;if (Math.abs(diffK) < d) {// 斜率相同去掉前一个点this._pointList.pop()}}this._pointList.push({ x, y })this._curGraphics.lineTo(x, y)this._curGraphics.stroke();this._preK = curK;}}private onTouchEnd(evt: EventTouch) {console.log(this._pointList.length)if (this._pointList.length > 1) {this._curGraphics.addComponent(RigidBody2D);for (let index = 0; index < this._pointList.length - 1; index++) {const start = this._pointList[index];const end = this._pointList[index + 1];const poly = this._curGraphics.addComponent(PolygonCollider2D);const d = v2(end.x - start.x, end.y - start.y).normalize();const widhtHalf = this._curGraphics.lineWidth / 2;const p1 = v2(d.y, -d.x).multiplyScalar(widhtHalf).add2f(start.x, start.y)const p2 = v2(-d.y, d.x).multiplyScalar(widhtHalf).add2f(start.x, start.y)const p3 = v2(d.y, -d.x).multiplyScalar(widhtHalf).add2f(end.x, end.y)const p4 = v2(-d.y, d.x).multiplyScalar(widhtHalf).add2f(end.x, end.y)poly.points = [p1, p2, p4, p3];poly.apply()}} else {this._curGraphics.node.destroy();}this._curGraphics = null;}
}

小结

简单来说,画线刚体就是根据路径点和线宽去生成碰撞体。

参考资料

[1]

https://forum.cocos.org/t/topic/142673: https://forum.cocos.org/t/topic/142673

364b098e6a67479f94abef30c5acf83b.jpeg

“点赞“ ”在看” 鼓励一下a36b1ea4fe56c51237831f5013d4211a.png

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

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

相关文章

产业园区中工业厂房的能源综合配置——工业园区综合能源数字化系统建设方案

以下内容转自微信公众号&#xff1a;PPP产业大讲堂&#xff0c;《产业园区中工业厂房的能源综合配置》。 园区工业地产中能源综合配置存在的问题 我国园区工业地产建设已历经近40年的发展, 园区在区域经济发展、产业集聚方面发挥了重要的载体和平台作用, 有力推动了我国社会经…

尚硅谷Docker基础篇和Dockerfile超详细整合笔记

Docker基础篇DockerFile Docker&#xff1a;您要如何确保应用能够在这些环境中运行和通过质量检测&#xff1f;并且在部署过程中不出现令人头疼的版本、配置问题&#xff0c;也无需重新编写代码和进行故障修复&#xff1f;而这个就是使用容器。Docker解决了运行环境和配置问题…

SMART PLC开放式以太网通信(UDP通信)

西门子S7-200 SMART PLC不仅支持开放式以太网通信,还支持MODBU-RTU,以及ModbusTcp通信,详细内容请参考下面文章: MODBUS-RTU主站通信 【精选】PLC MODBUS通信优化、提高通信效率避免权限冲突(程序+算法描述)-CSDN博客文章浏览阅读2.5k次,点赞5次,收藏10次。MODBUS通讯…

NVIDIA-SMI has failed because it couldn“t communicate with the NVIDIA driver .

文章目录 报错原因分析解决办法防患于未然 报错 执行nvidia-smi报错 NVIDIA-SMI has failed because it couldn"t communicate with the NVIDIA driver . Make sure that the atest NVIDIA driver is installed and running.运行使用gpu的docker容器时 NVIDIA Docker …

【小白专用】PHP基本语法 23.11.04

PHP基本语法 PHP是超文本预处理器 由服务器解析执行 可以与 html 进行混编(嵌入) ,PHP是一种弱类型语言 1.1 PHP标记 PHP和其他Web语言一样&#xff0c;都是用一对标记将PHP代码包含起来&#xff0c;以便和HTML代码区分开来。PHP支持4种风格的标记&#xff0c;如表所示。 标…

从零开始搭建微服务(一)

构建项目父工程 添加公共核心模块 安装nacos 安装nacos nacos 文档地址&#xff1a; https://nacos.io/zh-cn/docs/what-is-nacos.html 本文使用版本2.2.2 下载地址&#xff1a;https://github.com/alibaba/nacos/archive/refs/tags/2.2.2.zip 使用nacos 我们下载是源代码 解…

shell脚本代码混淆

文章目录 起因安装 Bashfuscator安装BashfuscatorBashfuscator的使用 起因 很多时候我并不希望自己的shell脚本被别人看到&#xff0c;于是我在想有没有什么玩意可以把代码加密而又正常执行&#xff0c;于是我想到了代码混淆&#xff0c;简单来看一下&#xff1a; 现在我的目…

自动识别图片文字表格:高效神器,告别繁琐手动操作

现代科技的快速发展为我们的生活带来了许多便利和效率提升。在数据处理和文档管理方面&#xff0c;自动化技术也日益成熟和普及。一项非常有用的技术是自动识别文字生成表格&#xff0c;它可以将大量的图片识别成文本并转换为表格形式&#xff0c;使得数据的整理和分析更加简便…

NFS服务以及静态路由及临时IP配置

目录 一、NFC服务基础知识 1、NFS服务初相识 2、NFS服务工作原理 二、NFC服务基础操作 1、NFS服务端配置 2、NFS服务 - exports 相关参数 3、NFS服务 - 命令相关 三、RPC 远程调度 四、静态路由及临时IP配置 1、Linux 静态路由相关命令 2、Linux 临时IP地址添加与删除…

基于葡萄串的采摘点定位方法

文章目录 概要所需设备方法基于RGB图像的YOLOV8目标检测基于深度图的区域种子生长利用峰值定位法来确定竖向位置核心代码演示效果概要 这里将介绍如何用图像识别方法来定位葡萄串采摘点,用于机器人自动采摘操作。 所需设备 深度相机,这里我用的是realsense-L515 方法 主…

Nacos-2.2.2源码修改集成高斯数据库GaussDB,postresql

一 &#xff0c;下载代码 Release 2.2.2 (Apr 11, 2023) alibaba/nacos GitHub 二&#xff0c; 执行打包 mvn -Prelease-nacos -Dmaven.test.skiptrue -Drat.skiptrue clean install -U 或 mvn -Prelease-nacos ‘-Dmaven.test.skiptrue’ ‘-Drat.skiptrue’ clean instal…

Spring Boot 整合SpringSecurity和JWT和Redis实现统一鉴权认证

&#x1f4d1;前言 本文主要讲了Spring Security文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#xff1a;努力…