当前位置: 首页 > news >正文

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

相关文章:

  • Ubuntu定时执行日志备份及删除脚本
  • PySpark 优雅的解决依赖包管理
  • 如何在idea中使用maven搭建tomcat环境
  • 【网络协议】聊聊HTTPS协议
  • 一 Java初探
  • NoSQL数据库使用场景以及架构介绍
  • stable diffusion安装踩坑之clip安装、git报错
  • C4D 2024终于发布,速度翻倍!模拟模块大更新!
  • 【数据结构与算法】JavaScript实现哈希表
  • JavaEE-博客系统2(功能设计)
  • CM3D2 汉化杂记
  • 048基于web+springboot的校园资料分享平台
  • Android Studio(对话框AlertDialog)
  • Ansible概述以及模块
  • 一个可以自动把微信聊天收到的二维码图片实时提取出来并分类的软件
  • 77. Combinations
  • JavaScript对象详解
  • node入门
  • web标准化(下)
  • 工程优化暨babel升级小记
  • 回顾2016
  • 简单基于spring的redis配置(单机和集群模式)
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 线上 python http server profile 实践
  • 优秀架构师必须掌握的架构思维
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 树莓派用上kodexplorer也能玩成私有网盘
  • #QT项目实战(天气预报)
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • $.ajax中的eval及dataType
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (二)linux使用docker容器运行mysql
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (强烈推荐)移动端音视频从零到上手(下)
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • ***详解账号泄露:全球约1亿用户已泄露
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .gitattributes 文件
  • .net core使用ef 6
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .net项目IIS、VS 附加进程调试
  • .so文件(linux系统)
  • @Autowired 与@Resource的区别
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • @基于大模型的旅游路线推荐方案
  • [Android 13]Input系列--获取触摸窗口
  • [C\C++]读入优化【技巧】
  • [c++] 单例模式 + cyberrt TimingWheel 单例分析
  • [C++]AVL树怎么转
  • [CakePHP] 在Controller中使用Helper