【前端】Matter:过滤与高级碰撞检测
在物理引擎中,控制物体的碰撞行为是物理模拟的核心之一。Matter.js 提供了强大的碰撞检测机制和碰撞过滤功能,让开发者可以控制哪些物体能够相互碰撞,如何处理复杂的碰撞情况。本文将详细介绍 碰撞过滤 (Collision Filtering) 与 高级碰撞检测 (Advanced Collision Detection),并通过实例展示如何在应用中使用这些技术。
碰撞过滤 (Collision Filtering)
碰撞过滤 是一种控制物体是否会相互碰撞的机制。通过设置物体的碰撞过滤属性,我们可以定义不同的规则来实现复杂的碰撞逻辑。例如,我们可以让某些物体只与特定物体碰撞,或者禁止它们与其他物体发生碰撞。
碰撞过滤的基本概念
在 Matter.js 中,每个刚体都有一个 collisionFilter
属性,该属性包含以下三个关键值:
category
: 碰撞类别,一个物体可以属于多个类别。mask
: 碰撞掩码,决定该物体能与哪些类别碰撞。group
: 碰撞组,物体可以分配到同一碰撞组内,组内物体是否相互碰撞由组的数值决定。
每个物体都有默认的 category
和 mask
,其中默认情况下,所有物体的 category
都是 0x0001
,mask
是 0xFFFFFFFF
(可以与所有类别碰撞)。
设置碰撞类别和掩码
通过自定义 category
和 mask
,可以灵活控制物体之间的碰撞关系。例如,如果我们希望某些物体只与特定类别的物体发生碰撞,可以使用以下代码:
const { Engine, Render, Runner, World, Bodies } = Matter;// 创建引擎和渲染器
const engine = Engine.create();
const render = Render.create({element: document.body,engine: engine,options: {width: 800,height: 600,wireframes: false}
});// 定义碰撞类别
const defaultCategory = 0x0001;
const categoryA = 0x0002;
const categoryB = 0x0004;// 创建物体并分配类别和掩码
const ballA = Bodies.circle(300, 200, 40, {collisionFilter: {category: categoryA,mask: categoryB // 只与类别B的物体碰撞}
});const ballB = Bodies.circle(500, 200, 40, {collisionFilter: {category: categoryB,mask: categoryA // 只与类别A的物体碰撞}
});const ground = Bodies.rectangle(400, 600, 810, 60, { isStatic: true });World.add(engine.world, [ballA, ballB, ground]);Engine.run(engine);
Render.run(render);
在这个例子中,ballA
属于类别 categoryA
,它的 mask
设为 categoryB
,这意味着它只会与属于类别 categoryB
的物体碰撞。同样,ballB
也只会与属于 categoryA
的物体碰撞,而不与其他类别的物体碰撞。
碰撞组
除了 category
和 mask
,还可以使用 group
来实现更精细的碰撞控制。碰撞组 (Collision Groups) 允许将多个物体分配到同一个组,并控制组内物体的碰撞行为。不同于 category
和 mask
,group
的值可以是正数或负数:
- 正数:组内物体相互碰撞。
- 负数:组内物体不会相互碰撞。
例如,我们可以创建一个由多个部件组成的物体(如车轮和车身),并使其在物体内部不会发生碰撞,但可以与外部的物体发生碰撞。
const wheelA = Bodies.circle(300, 400, 40, {collisionFilter: {group: -1}
});const wheelB = Bodies.circle(500, 400, 40, {collisionFilter: {group: -1}
});const ground = Bodies.rectangle(400, 600, 810, 60, { isStatic: true });// 轮子和地面会发生碰撞,但两个轮子之间不会
World.add(engine.world, [wheelA, wheelB, ground]);Engine.run(engine);
Render.run(render);
在这里,wheelA
和 wheelB
都属于碰撞组 -1
,因此它们不会相互碰撞,但它们可以与其他物体(例如地面)发生碰撞。
高级碰撞检测 (Advanced Collision Detection)
Matter.js 中的高级碰撞检测功能允许你检测并处理更加复杂的碰撞事件,比如检测特定物体的碰撞、获取碰撞接触点、以及响应特定碰撞事件。
监听碰撞事件
Matter.js 提供了事件监听器,可以在物体发生碰撞时触发特定的回调函数。以下是常用的三个碰撞事件:
collisionStart
: 两个物体开始碰撞时触发。collisionActive
: 两个物体在碰撞过程中持续触发。collisionEnd
: 两个物体碰撞结束时触发。
你可以通过 Matter.Events.on()
来监听这些碰撞事件。例如:
Matter.Events.on(engine, 'collisionStart', function(event) {const pairs = event.pairs;pairs.forEach(pair => {const { bodyA, bodyB } = pair;console.log(`Collision detected between ${bodyA.label} and ${bodyB.label}`);});
});
在这个例子中,当两个物体开始碰撞时,会在控制台中输出相关信息。
检测碰撞的详细信息
当物体发生碰撞时,Matter.js 提供了关于碰撞点、碰撞深度等的详细信息。你可以使用这些信息来实现更加细致的碰撞处理。
以下是一个例子,展示如何获取碰撞的接触点:
Matter.Events.on(engine, 'collisionStart', function(event) {const pairs = event.pairs;pairs.forEach(pair => {const { bodyA, bodyB, collision } = pair;const { supports } = collision;console.log(`Collision point: x=${supports[0].x}, y=${supports[0].y}`);});
});
supports
是碰撞的接触点坐标数组,你可以使用这些坐标来执行更多的逻辑,比如根据碰撞点触发爆炸、声音效果或粒子效果。
手动处理碰撞
除了依赖引擎的自动处理,你还可以通过监听事件手动修改物体的碰撞行为。以下是一个示例,展示如何在物体碰撞时改变物体的颜色:
Matter.Events.on(engine, 'collisionStart', function(event) {const pairs = event.pairs;pairs.forEach(pair => {pair.bodyA.render.fillStyle = '#FF0000';pair.bodyB.render.fillStyle = '#FF0000';});
});
在这个例子中,当两个物体发生碰撞时,它们的颜色会变成红色。通过这种方式,你可以根据碰撞的结果来实现自定义的视觉效果。
碰撞的条件过滤
有时我们只想对特定的碰撞进行处理,而忽略其他的碰撞。可以通过在事件监听器中添加条件过滤来实现这一点。例如,如果你只想处理特定物体的碰撞,可以这样实现:
Matter.Events.on(engine, 'collisionStart', function(event) {const pairs = event.pairs;pairs.forEach(pair => {if (pair.bodyA.label === 'ball' && pair.bodyB.label === 'ground') {console.log('Ball hit the ground!');}});
});
在这个示例中,只有当 ball
碰到 ground
时,才会触发日志输出。这样可以避免处理无关的碰撞事件。
性能优化
高级碰撞检测和复杂的碰撞过滤可能会影响性能,尤其是在处理大量物体时。为了保持物理引擎的性能,以下是一些优化技巧:
- 简化碰撞形状: 使用简单的几何形状(如矩形、圆形)代替复杂的多边形。
- 减少不必要的碰撞检测: 使用碰撞过滤或分层逻辑,避免处理无关的物体碰撞。
- 降低引擎更新频率: 调整
engine.timing.timeScale
来控制引擎的更新频率,减少每帧计算的负载。
总结
在本教程中,我们深入探讨了 Matter.js 中的 碰撞过滤 和 高级碰撞检测。通过碰撞过滤,可以精确控制物体的碰撞行为,定义复杂的碰撞规则。而通过高级碰撞检测,可以获取碰撞的详细信息,监听碰撞事件并自定义碰撞响应逻辑。
这些功能使得 Matter.js 能够处理复杂的物理交互,提供了更大的灵活性,适用于需要细致控制和优化的物理模拟场景。
相关文章:

【前端】Matter:过滤与高级碰撞检测
在物理引擎中,控制物体的碰撞行为是物理模拟的核心之一。Matter.js 提供了强大的碰撞检测机制和碰撞过滤功能,让开发者可以控制哪些物体能够相互碰撞,如何处理复杂的碰撞情况。本文将详细介绍 碰撞过滤 (Collision Filtering) 与 高级碰撞检测…...

wps图标没有坐标轴标题怎么办?wps表格不能用enter下怎么办?
目录 wps图标没有坐标轴标题怎么办 一、在WPS PPT中添加坐标轴标题 二、在WPS Excel中添加坐标轴标题 wps表格不能用enter下怎么办 一、检查并修改设置 二、检查单元格保护状态 三、使用快捷键实现换行 wps图标没有坐标轴标题怎么办 一、在WPS PPT中添加坐标轴标题 插入…...

在ESP-IDF环境中如何进行多文件中的数据流转-FreeRTOS实时操作系统_流缓存区“xMessageBuffer”
一、建立三个源文件和对应的头文件 建立文件名,如图所示 图 1-1 二、包含相应的头文件 main.h 图 2-1 mess_send.h mess_rece.h和这个中类似,不明白的大家看我最后面的源码分享 图2-2 三、声明消息缓存区的句柄 大家注意,在main.c中定义的是全局变…...

ConcurrentLinkedQueue适合什么样的使用场景?
ConcurrentLinkedQueue 是 Java 中一种无界线程安全的队列,适合多线程环境中的高并发场景。以下是一些它特别适合的使用场景: 1. 高频读操作,低频写操作 ConcurrentLinkedQueue 对于实际应用中读操作相对频繁,写操作较少的场景非…...

C语言 | Leetcode C语言题解之第480题滑动窗口中位数
题目: 题解: struct Heap {int* heap;int heapSize;int realSize;bool (*cmp)(int, int); };void init(struct Heap* obj, int n, bool (*cmp)(int, int)) {obj->heap malloc(sizeof(int) * (n 1));obj->heapSize 0;obj->cmp cmp; }bool c…...

LabVIEW开发如何实现降维打击
在LabVIEW开发中实现“降维打击”可以理解为利用软件优势和高效工具来解决复杂的问题,将多维度、多层次的技术简化为容易操作和管理的单一维度,达到出其不意的效果。以下是几种关键策略: 1. 模块化设计与封装 将复杂系统分解为若干模块&…...

docker 文件目录迁移
文章参考 du -hs /var/lib/docker/ 命令查看磁盘使用情况。 du -hs /var/lib/docker/docker system df命令,类似于Linux上的df命令,用于查看Docker的磁盘使用情况: rootnn0:~$ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 7 2 122.2…...

Markdown 标题
Markdown 标题 Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式化的HTML代码。Markdown 的语法简洁明了,广泛用于撰写文档、博客文章、笔记等。本文将详细介绍 Markdown 的标题语法及其在文档中的应用。 Markdown 标题语法 在…...

【动手学电机驱动】TI InstaSPIN-FOC(5)Lab04 力矩控制
TI InstaSPIN-FOC(1)电机驱动和控制测试平台 TI InstaSPIN-FOC(2)Lab01 闪灯实验 TI InstaSPIN-FOC(3)Lab03a 测量电压电流漂移量 TI InstaSPIN-FOC(4)Lab02b 电机参数辨识 TI Insta…...

Mysql的CommunicationsException
一、报错内容 com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 1,500,378 milliseconds ago. The last packet sent successfully to the server was 1,500,378 milliseconds ago. is longer than the s…...

C++学习笔记----9、发现继承的技巧(二)---- 重用目的的继承
现在你对继承的基本语法已经比较熟悉了,是时候探索继承是c语言中重要属性的一个主要原因了。继承是一个装备允许你平衡既有代码。本节会举出基于代码重用目的的继承的例子。 1、WeatherPrediction类 假想你有一个任务,写一个程序来发出简单的天气预报&a…...

锐评 Nodejs 设计模式 - 创建与结构型
本系列文章的思想,都融入了 让 Java 再次伟大 这个全新设计的脚手架产品中,欢迎大家使用。 单例模式与模块系统 Node 的单例模式既特殊又简单——凡是从模块中导出的实例天生就是单例。 // database.js function Database(connect, account, password)…...

【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制
💯 欢迎光临清流君的博客小天地,这里是我分享技术与心得的温馨角落 💯 🔥 个人主页:【清流君】🔥 📚 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 📚 🌟始终保持好奇心&…...

15分钟学Go 第4天:Go的基本语法
第4天:基本语法 在这一部分,将讨论Go语言的基本语法,了解其程序结构和基础语句。这将为我们后续的学习打下坚实的基础。 1. Go语言程序结构 Go语言程序的结构相对简单,主要包括: 包声明导入语句函数语句 1.1 包声…...

【Qt】Qt的介绍——Qt的概念、使用Qt Creator新建项目、运行Qt项目、纯代码方式、可视化操作、认识对象模型(对象树)
文章目录 Qt1. Qt的概念2. 使用Qt Creator新建项目3. 运行Qt项目3.1 纯代码方式实现3.2 可视化操作实现 4. 认识对象模型(对象树) Qt 1. Qt的概念 Qt 是一个跨平台的 C 图形用户界面应用程序开发框架。它是软件开发者提供的用于界面开发的程序框架&#…...

论文笔记:PTR: Prompt Tuning with Rules for Text Classification
Abstract 手动设计大量语言提示麻烦且易出错,而自动生成的提示,在非小样本场景下验证其有效性昂贵且耗时。因此,提示调优以处理多类别分类任务仍然具有挑战。为此,本文提出使用规则进行多类别文本分类提示调优(PTR&…...

服务器和中转机协同工作以提高网络安全
服务器和中转机(代理服务器)可以通过多种方式协同工作来提高网络安全。 常见的协同工作策略: 1. 使用代理服务器作为安全网关 访问控制:代理服务器可以作为网络的入口点,实施访问控制策略,如基于IP地址、…...

Java利用itextpdf实现pdf文件生成
前言 最近公司让写一个数据页面生成pdf的功能,找了一些市面代码感觉都太麻烦,就自己综合性整合了一个便捷的工具类,开发只需简单组装数据直接调用即可快速生成pdf文件。望大家一起学习!!! 代码获取方式&am…...

2010年国赛高教杯数学建模C题输油管的布置解题全过程文档及程序
2010年国赛高教杯数学建模 C题 输油管的布置 某油田计划在铁路线一侧建造两家炼油厂,同时在铁路线上增建一个车站,用来运送成品油。由于这种模式具有一定的普遍性,油田设计院希望建立管线建设费用最省的一般数学模型与方法。 1. 针对两炼…...

datawhale大模型bot应用开发--task3:工作流
目录 一、介绍:Coze工作流 1.1工作流应用场景 1.2什么是工作流 1.3思考环节 二、各个工作流详情 2.1情感分类工作流 2.2 随机数工作流 2.3 必应搜索工作流 2.4 天气查询工作流 三、集合上面五个工作流的总工作流 一、介绍:Coze工作流 1.1工作…...

期货配资系统风控逻辑开发/完整源代码
期货配资系统风控逻辑的开发是确保系统安全、稳定、高效运行的关键环节。以下是对期货配资系统风控逻辑开发的详细分析: 一、风险识别与评估 风险来源分析: 市场风险:期货市场价格波动带来的风险。信用风险:投资者或配资方违约的…...

汽车免拆诊断案例 | 2023款零跑C01纯电车后备厢盖无法电动打开和关闭
故障现象 一辆2023款零跑C01纯电车,累计行驶里程约为2万km,车主进厂反映,后备厢盖无法电动打开和关闭。 故障诊断 接车后试车,操作后备厢盖外侧、驾驶人侧及遥控钥匙上的后备厢盖开启按钮,可以听到后备厢盖解锁的…...

分布式存储架构 与分布式一致性协议
分布式存储架构可以分为无中心节点架构和有中心节点架构。它们的设计在系统中的角色分配、数据管理、协调方式等方面有所不同。 1. 无中心节点架构(Decentralized/Peer-to-Peer Architecture) 在无中心节点的分布式存储架构中,所有节点都是…...

Unity Apple Vision Pro 保姆级开发教程 - Simulator 模拟器使用
教程视频 Apple VisionPro Simulator 模拟器使用教程 VsionOS Simulator 简介 visionOS Simulator 是一个用于开发和测试 visionOS 应用程序的工具。它模拟 Apple Vision Pro 的运行环境,帮助开发者在没有硬件设备的情况下创建、调试和优化他们的应用程序。VisionO…...

Vue 之 插件与组件的区别
在 Vue.js 中,插件(Plugin)和组件(Component)都是用来扩展 Vue 功能的重要工具,但它们的应用场景和使用方式有所不同。本文将通过对比的方式,帮助开发者更好地理解两者的区别,并通过…...

了解 ChatGPT 中的公平性问题
了解 ChatGPT 中的公平性问题 最近,OpenAI 又发布了一篇新的博客。他们谈论了一个有趣又重要的话题——用户的身份如何影响 ChatGPT 的回答。 这项研究揭示了一个鲜明的事实,那就是 AI 可能会无意间对人类产生刻板印象。很可能这些刻板印象源自 AI 训练过程中使用的数据,而这…...

【PHP】安装swoole时报错:No package ‘libbrotlienc‘ found
一、环境 Debian 11(bullseye) PHP 8.2.14 Swoole 5.1.4 二、过程 今天在安装Swoole 5.1.4的时候报错,错误信息如下: configure: error: Package requirements (libbrotlienc) were not met:No package libbrotlienc foundConsider adjusting the PK…...

postgresql执行计划解读案例
简介 SQL优化中读懂执行计划尤其重要,以下举例说明在执行计划中常见的参数其所代表的含义。 创建测试数据 -- 创建测试表 drop table if exists customers ; drop table if exists orders ; drop table if exists order_items ; drop table if exists products ;…...

Matlab实现粒子群优化算法优化随机森林算法模型 (PSO-RF)(附源码)
目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 粒子群优化算法(PSO)是一种启发式搜索方法,灵感来源于鸟类群体觅食的行为。在PSO中,每个解都是搜索空间中的一个“粒子”,这些粒子以一定的速度飞行&am…...

使用 EasyExcel 相邻数据相同时行和列的合并,包括动态表头、数据
前言 在处理 Excel 文件时,经常会遇到需要对表格中的某些单元格进行合并的情况,例如合并相同的行或列。Apache POI 是一个强大的工具,但它使用起来相对复杂。相比之下,EasyExcel 是一个基于 Apache POI 的轻量级 Excel 处理库&am…...