物理引擎的基础概念
在使用JavaScript物理引擎之前,需要先理解几个核心概念。首先是刚体,指形状和大小在运动过程中不会发生变化的物体,是物理引擎中最基本的模拟单位。其次是世界,所有的刚体、约束、力都存在于这个世界中,引擎会基于物理规则计算世界中每个元素的状态。还有碰撞检测,引擎会自动判断两个刚体是否发生接触,并触发对应的回调逻辑。重力、摩擦力、弹性系数等也是常见的物理属性,我们可以通过配置这些属性调整模拟的真实度。

以Matter.js为例的环境搭建
Matter.js是目前最流行的轻量级JavaScript物理引擎之一,无需依赖其他库,直接在浏览器中运行。首先我们需要在项目中引入Matter.js,可以通过CDN引入,也可以下载源码本地引入。
如果是简单的演示项目,直接在HTML中通过script标签引入即可:
<script src="https://cdn.jsdelivr.net/npm/matter-js@0.18.0/build/matter.min.js"></script>
如果是在模块化项目中,也可以通过npm安装后引入:
// 安装命令:npm install matter-js import Matter from 'matter-js';
创建基础物理场景
一个最简单的物理场景需要包含世界、渲染器、刚体三个部分。下面的代码会创建一个带有重力的物理世界,并在页面中渲染一个下落的矩形刚体和一个固定的地面刚体。
// 解构Matter模块中的核心对象
const { Engine, Render, Runner, Bodies, World } = Matter;
// 1. 创建物理引擎实例,同时创建对应的世界
const engine = Engine.create();
// 配置世界的重力,x方向0,y方向1,模拟地球重力
engine.world.gravity.y = 1;
// 2. 创建渲染器,将物理世界的状态渲染到页面canvas上
const render = Render.create({
element: document.body, // 渲染容器
engine: engine, // 关联的引擎
options: {
width: 800, // canvas宽度
height: 600, // canvas高度
wireframes: false, // 关闭线框模式,显示填充样式
background: '#f5f5f5' // 背景颜色
}
});
// 3. 创建刚体
// 创建矩形刚体:参数分别是x坐标、y坐标、宽度、高度、配置项
const box = Bodies.rectangle(400, 50, 80, 80, {
label: '下落方块', // 刚体标签,用于标识
restitution: 0.8, // 弹性系数,0-1之间,值越大弹性越好
friction: 0.1 // 摩擦系数
});
// 创建地面刚体,isStatic设为true表示静态刚体,不受力的影响
const ground = Bodies.rectangle(400, 580, 810, 60, {
isStatic: true,
label: '地面',
render: {
fillStyle: '#666666' // 地面填充颜色
}
});
// 4. 将所有刚体添加到世界中
World.add(engine.world, [box, ground]);
// 5. 启动渲染器和引擎运行器
Render.run(render);
const runner = Runner.create();
Runner.run(runner, engine);代码核心逻辑说明
- Engine.create()会同时创建引擎和世界,世界是引擎的一个属性,所有物理元素都挂载到世界上。
- Render负责将物理世界的状态同步到canvas画布,不需要我们手动绘制每个刚体的位置。
- Bodies提供了创建常见形状刚体的方法,除了矩形还有圆形、多边形等,静态刚体适合做边界、地面等固定元素。
- Runner会按照固定的时间步长驱动引擎更新,自动计算刚体的位置、速度、碰撞等状态。
实现碰撞检测与事件监听
物理引擎的核心功能之一是自动处理碰撞,我们可以通过监听碰撞事件实现自定义逻辑,比如物体碰撞后改变颜色、播放音效等。
// 监听碰撞开始事件
Matter.Events.on(engine, 'collisionStart', (event) => {
const pairs = event.pairs; // 所有发生碰撞的刚体对
pairs.forEach(pair => {
const { bodyA, bodyB } = pair;
// 判断是否是下落方块和地面发生碰撞
if ((bodyA.label === '下落方块' && bodyB.label === '地面') ||
(bodyA.label === '地面' && bodyB.label === '下落方块')) {
console.log('方块碰到了地面');
// 碰撞后改变方块的颜色
bodyA.label === '下落方块' ? bodyA.render.fillStyle = '#ff0000' : bodyB.render.fillStyle = '#ff0000';
}
});
});常见物理效果扩展
添加鼠标交互
我们可以给刚体添加鼠标拖拽功能,让用户可以拖动页面中的物理物体。
const { Mouse, MouseConstraint } = Matter;
// 创建鼠标交互约束
const mouse = Mouse.create(render.canvas);
const mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2, // 约束刚度
render: {
visible: false // 不显示约束线
}
}
});
// 将鼠标约束添加到世界中
World.add(engine.world, mouseConstraint);
// 让渲染器的鼠标和页面鼠标同步
render.mouse = mouse;创建复合刚体
如果需要模拟复杂形状的物体,可以通过复合刚体实现,将多个基础刚体组合成一个整体。
// 创建一个由矩形和圆形组成的复合刚体
const compoundBody = Body.create({
parts: [
Bodies.rectangle(400, 200, 100, 40), // 矩形部分
Bodies.circle(350, 200, 20), // 左侧圆形
Bodies.circle(450, 200, 20) // 右侧圆形
],
restitution: 0.6
});
World.add(engine.world, compoundBody);使用注意事项
- 物理引擎的计算会消耗一定的性能,如果场景中的刚体数量过多,可以适当降低渲染帧率或者简化刚体形状。
- 刚体的质量、摩擦力、弹性等属性需要根据实际场景调整,参数差异会直接影响模拟效果的真实度。
- 如果需要和服务端同步物理状态,建议以固定的时间步长同步刚体的核心属性,避免不同客户端状态不一致。
- 静态刚体不适合做频繁的位置更新,如果需要移动边界,建议使用运动刚体而不是静态刚体。
总结
使用JavaScript物理引擎可以大幅降低物理效果开发的难度,不需要手动处理复杂的力学公式和碰撞检测逻辑。Matter.js作为轻量级的物理引擎,API设计简洁,适合大多数Web端的物理效果需求。实际使用中可以根据场景选择合适的引擎,比如需要3D物理效果可以选择ammo.js或者cannon.js。掌握物理引擎的核心概念和常用API后,就可以快速实现下落、碰撞、弹跳、拖拽等各种物理互动效果,提升Web应用的交互体验。
JavaScript物理引擎Matter_js刚体模拟碰撞检测修改时间:2026-06-07 03:18:43