Phaser 4 Matter.js 物理系统实战指南:刚体、约束、复合体、传感器与碰撞过滤完整解析
2026/9/19 16:15:48 网站建设 项目流程

Phaser 4 Matter.js 物理系统实战指南:刚体、约束、复合体、传感器与碰撞过滤完整解析

【免费下载链接】phaserPhaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.项目地址: https://gitcode.com/gh_mirrors/ph/phaser

本文基于 Phaser 仓库中的官方技能文档(skills/physics-matter/SKILL.md)展开,系统讲解如何在 Phaser 4 场景中启用与使用 Matter.js 全刚体物理引擎。你将掌握刚体与复合体创建、约束(关节/弹簧)、传感器、碰撞过滤、指针拖拽、Tilemap 集成以及调试渲染的完整配置与调用方式,并能在实际项目中直接套用文中全部示例代码。

Matter.js 是 Phaser 内置的全刚体(full-body)物理引擎。与 Arcade Physics 的简化 AABB 碰撞不同,它支持刚性体、复合体、复合结构体、凸/凹多边形碰撞体、质量与密度、恢复系数(restitution)、稳定堆叠、动量守恒、约束、重力、休眠(sleeping)与静态体、圆角(chamfering)、碰撞查询(raycast、区域检测)以及时间缩放(慢动作/加速)等能力。下文将以场景插件this.matter为入口,从启用配置到高级玩法逐层展开。

快速开始:一个可运行的 Matter 场景

启用 Matter 物理只需要两步:在游戏配置中声明default: 'matter',并在场景中通过this.matter.add工厂创建物理对象。

class GameScene extends Phaser.Scene { create() { // Matter sprite(动态刚体,支持动画) this.player = this.matter.add.sprite(400, 200, 'player'); this.player.setBounce(0.5); this.player.setFriction(0.05); // Matter image(动态刚体,无动画,更轻量) const box = this.matter.add.image(300, 100, 'crate'); // 原始形状创建的静态刚体 this.matter.add.rectangle(400, 580, 800, 40, { isStatic: true }); // 启用指针拖拽(所有刚体可被鼠标/触屏拖起) this.matter.add.mouseSpring(); this.cursors = this.input.keyboard.createCursorKeys(); } update() { if (this.cursors.left.isDown) { this.player.setVelocityX(-5); } else if (this.cursors.right.isDown) { this.player.setVelocityX(5); } if (this.cursors.up.isDown && this.player.body.velocity.y > -0.1) { this.player.setVelocityY(-10); } } } // 在游戏配置中启用 Matter 物理 const config = { type: Phaser.AUTO, width: 800, height: 600, physics: { default: 'matter', matter: { gravity: { y: 1 }, enableSleeping: true, debug: true, setBounds: true // 在画布四周生成墙体 } }, scene: GameScene }; const game = new Phaser.Game(config);

注意update中的跳跃判断:this.player.body.velocity.y > -0.1用于近似判断玩家是否“已落地”(Matter 中速度单位为“每步的单位数”而非像素/秒),避免空中无限连跳。

核心概念:场景插件、世界与配置

场景插件this.matter(MatterPhysics)

MatterPhysics是场景级插件,负责 Phaser Scene 与单个 Matter Engine 实例之间的桥接(见 MatterPhysics.js 类注释)。它的关键属性:

  • this.matter.addFactory实例,用于创建刚体、约束和物理 Game Object,并自动加入世界。在 boot 方法 中实例化。
  • this.matter.worldWorld实例,管理引擎、边界、调试渲染,继承自EventEmitter(见 World.js)。
  • this.matter.body/bodies/composite/composites/constraint— 对 Matter.js 底层模块的直接引用(分别指向Matter.BodyMatter.BodiesMatter.CompositeMatter.CompositesMatter.Constraint),用于脱离 Phaser 封装的低层操作。
  • this.matter.bodyBoundsBodyBounds辅助类,用于按视觉边界对齐刚体(见 BodyBounds.js)。

世界this.matter.world

World在构造时即调用Engine.create(config)创建 Matter 引擎,并持有localWorld(包含所有刚体与约束的 World 复合体)。常用属性:

  • engineMatterJS.Engine实例。
  • localWorldMatterJS.World复合体,包含所有刚体与约束。
  • enabled— 布尔值,false时暂停模拟;autoUpdatetrue时每个游戏帧自动执行引擎步进。
  • walls{ left, right, top, bottom }边界墙刚体(未启用时为null)。

世界配置(MatterWorldConfig)

配置通过游戏配置或场景配置的physics.matter传入,其字段定义见 MatterWorldConfig.js:

属性默认值作用
gravity{ x: 0, y: 1 }重力向量;设为false可禁用
setBoundsfalsetrue{ x, y, width, height, thickness, left, right, top, bottom };其中thickness默认 64,四个方向墙体默认均创建
enableSleepingfalse允许刚体静止时休眠,可提升稳定性与性能
positionIterations6位置求解精度,越大模拟质量越高但性能越低
velocityIterations4速度求解精度
constraintIterations2约束稳定性
timing.timeScale10冻结模拟,0.1慢动作,1.2加速
enabledtrue世界是否启用
correction1应用于更新的时间校正因子
autoUpdatetrue每个游戏帧自动调用Engine.update
restingThresh4Resolver 静止阈值
restingThreshTangent6Resolver 静止切向阈值
positionDampen0.9Resolver 位置阻尼
positionWarming0.8Resolver 位置预热
frictionNormalMultiplier5Resolver 摩擦法向乘数
debugfalsetrueMatterDebugConfig对象
runner{}Matter Runner 选项,runner.fps用于固定时间步长

从源码 MatterPhysics.js 可以看到,restingThreshpositionDampen等求解器参数在插件构造时通过GetValue(this.config, ...)读取并写入Resolver模块。配置合并逻辑位于 getConfig 方法:场景配置优先于游戏配置sceneConfigmatter覆盖gameConfigmatter)。

setBounds与迭代次数等物理参数在 World.js 的setBounds(第 796 行)、引擎创建逻辑中生效。

Matter Game Object:三种接入方式

Phaser 提供两个内置物理 Game Object 类,以及一个可给任意 Game Object 注入物理能力的函数:

  • Phaser.Physics.Matter.Sprite— 继承Sprite并混入全部 Matter 组件,通过this.matter.add.sprite(x, y, key, frame, options)创建,支持动画。实现见 MatterSprite.js。
  • Phaser.Physics.Matter.Image— 继承Image并混入全部 Matter 组件,通过this.matter.add.image(x, y, key, frame, options)创建,无动画支持、更轻量。实现见 MatterImage.js。
  • MatterGameObject(world, gameObject, options)— 把全部 Matter 组件注入任意已有 Game Object,通过this.matter.add.gameObject(mySprite, options)创建。实现见 MatterGameObject.js。

MatterSpriteMatterImage默认按纹理尺寸生成矩形刚体,可通过options.shape覆盖默认形状。对应工厂方法位于 Factory.js:image(820 行)、tileBody(849 行)、sprite(876 行)、gameObject(904 行)。

Matter 组件(Mixin)速查

所有 Matter Game Object 都会混入以下组件方法,组件源码位于 components/ 目录(对应 12 个 mixin 文件:Bounce、Collision、Force、Friction、Gravity、Mass、Sensor、SetBody、Sleep、Static、Transform、Velocity):

组件关键方法
VelocitysetVelocity(x, y)setVelocityX(x)setVelocityY(y)getVelocity()setAngularVelocity(v)getAngularVelocity()setAngularSpeed(s)getAngularSpeed()
ForceapplyForce(vec2)applyForceFrom(position, force)thrust(speed)thrustLeft(speed)thrustRight(speed)thrustBack(speed)
BouncesetBounce(value)— 恢复系数,范围 0~1
FrictionsetFriction(value, air?, fstatic?)setFrictionAir(value)setFrictionStatic(value)
MasssetMass(value)setDensity(value)centerOfMass(getter)
GravitysetIgnoreGravity(bool)
SensorsetSensor(bool)isSensor()
StaticsetStatic(bool)isStatic()
SleepsetToSleep()setAwake()setSleepThreshold(n)setSleepEvents(start, end)
CollisionsetCollisionCategory(cat)setCollisionGroup(group)setCollidesWith(cats)setOnCollide(cb)setOnCollideEnd(cb)setOnCollideActive(cb)setOnCollideWith(body, cb)
SetBodysetRectangle(w, h, opts)setCircle(r, opts)setPolygon(r, sides, opts)setTrapezoid(w, h, slope, opts)setBody(config, opts)setExistingBody(body)
Transform同步 Matter 刚体与 Game Object 之间的位置

常见模式详解

世界配置与运行时调整

// 运行时调整重力与边界 this.matter.world.setGravity(0, 2); // 参数:x, y, scale(默认 0.001) this.matter.world.disableGravity(); this.matter.world.setBounds(0, 0, 1600, 1200, 64, true, true, true, true); this.matter.set60Hz(); // 固定 60Hz 时间步长 this.matter.world.autoUpdate = false; // 关闭自动步进,改用手动 // 手动步进:this.matter.step(16.666); this.matter.pause(); // 暂停 / 恢复 this.matter.resume();

set60Hz()/set30Hz()的实现是把world.getDelta指向update60Hz/update30Hz并强制autoUpdate = true(见 MatterPhysics.js),World中对应的步进函数见 World.js 第 1307、1320 行。step(delta)则会绕过enabled/autoUpdate检查直接推进一帧模拟。

创建 Sprite / Image 与自定义形状

const player = this.matter.add.sprite(200, 300, 'hero'); // 默认矩形刚体,匹配纹理尺寸 // 通过 options.shape 指定自定义形状 const ball = this.matter.add.image(400, 100, 'ball', null, { shape: { type: 'circle', radius: 24 } }); const hex = this.matter.add.sprite(300, 100, 'hex', null, { shape: { type: 'polygon', sides: 6, radius: 32 } }); const ship = this.matter.add.sprite(400, 200, 'ship', null, { shape: { type: 'fromVerts', verts: '0 0 40 0 40 40 20 60 0 40' } }); // 使用 PhysicsEditor 导出的形状 JSON const shapes = this.cache.json.get('shapes'); const enemy = this.matter.add.sprite(500, 200, 'enemy', null, { shape: shapes.enemy }); // 给已有 Game Object 注入物理能力 const existingSprite = this.add.sprite(100, 100, 'box'); this.matter.add.gameObject(existingSprite, { restitution: 0.8 }); // existingSprite 现在拥有了 setVelocity、setBounce 等方法

PhysicsEditor JSON 的解析由 PhysicsEditorParser.js 完成;工厂侧fromPhysicsEditor与其对应,另支持fromSVG(把 SVG 路径转为顶点)与fromJSON

刚体配置选项(MatterBodyConfig)

作为任意工厂方法的options参数传入:

  • labelisStaticisSensorangle(弧度)、timeScaleignoreGravityignorePointer
  • density(默认 0.001,根据密度自动计算质量)、massrestitution(弹性/反弹 0~1)
  • friction(0~1)、frictionAir(空气阻力)、frictionStatic(静止时的黏滞)
  • slop(重叠容差)、chamfer{ radius: 5 }圆角)
  • collisionFilter: { category: 0x0001, mask: 0xFFFFFFFF, group: 0 }
  • onCollideCallbackonCollideEndCallbackonCollideActiveCallback
  • shape(仅 Game Object 使用):{ type: 'circle', radius: 24 }或 PhysicsEditor 数据

完整字段定义见 MatterBodyConfig.js 与 MatterCollisionFilter.js。

速度、力与推力

sprite.setVelocity(3, -5); // 单位为“每步单位”,不是像素/秒 sprite.setVelocityX(-3); sprite.setAngularVelocity(0.05); const vel = sprite.getVelocity(); // { x, y } // 力的数值非常小(0.01 ~ 0.1) sprite.applyForce({ x: 0.05, y: 0 }); sprite.applyForceFrom(position, { x: 0.02, y: -0.02 }); // 相对刚体角度的定向推力 sprite.thrust(0.05); // 前进 sprite.thrustBack(0.05); // 后退 sprite.thrustLeft(0.03); // 左平移 sprite.thrustRight(0.03); // 右平移 // 通过 this.matter 批量操作 this.matter.setVelocity(arrayOfBodies, 2, -3); this.matter.applyForce(arrayOfBodies, { x: 0.01, y: 0 });

约束(关节与弹簧)

constraint(bodyA, bodyB, length?, stiffness?, options?)同时提供jointspring两个别名(见 Factory.js 第 612、644、674 行的jointspringconstraint):

const rigid = this.matter.add.constraint(bodyA, bodyB, 100, 1); // 刚性关节 const spring = this.matter.add.constraint(bodyA, bodyB, 200, 0.02, { damping: 0.05 }); const pin = this.matter.add.constraint(bodyA, bodyB, 0, 0.9); // 销钉关节 // 世界约束:把刚体钉在世界空间某点 this.matter.add.worldConstraint(body, 50, 0.5, { pointA: { x: 400, y: 100 } }); // 偏移连接点 this.matter.add.constraint(bodyA, bodyB, 80, 1, { pointA: { x: 20, y: 0 }, // 相对 bodyA 中心的偏移 pointB: { x: -20, y: 0 } // 相对 bodyB 中心的偏移 }); this.matter.getConstraintLength(constraint); // 两个锚点之间的距离 this.matter.world.removeConstraint(constraint); // 从世界移除

复合体(堆叠、链条、软体)

// 网格状堆叠 const stack = this.matter.add.stack(100, 100, 5, 4, 10, 10, (x, y) => { return this.matter.bodies.rectangle(x, y, 40, 40); }); // 图像堆叠(Matter Image 网格) const imageStack = this.matter.add.imageStack('crate', null, 100, 100, 5, 4, 5, 5); // 用约束把复合体内的刚体链起来 this.matter.add.chain(stack, 0.5, 0, -0.5, 0, { stiffness: 0.7 }); // 网格(约束组成的网格,可选交叉斜撑) this.matter.add.mesh(stack, 5, 4, true, { stiffness: 0.5 }); // 软体(参数顺序:x, y, cols, rows, colGap, rowGap, crossBrace, particleRadius, bodyOpts, constraintOpts) this.matter.add.softBody(200, 100, 5, 5, 0, 0, true, 10, { friction: 0.1 }, { stiffness: 0.5 }); // 内置复合体:牛顿摆、小车、金字塔 this.matter.add.newtonsCradle(300, 50, 5, 20, 200); this.matter.add.car(400, 300, 120, 30, 25);

上述方法的工厂签名均可在 Factory.js 中确认:imageStack(394 行)、stack(437 行)、pyramid(463 行)、chain(487 行)、mesh(506 行)、newtonsCradle(525 行)、car(548 行)、softBody(576 行)。

复合刚体(Compound Bodies)

把多个形状合并为单个刚体,第一个部件作为父体:

const partA = this.matter.bodies.rectangle(0, 0, 60, 20); const partB = this.matter.bodies.circle(0, -30, 15); const compoundBody = this.matter.body.create({ parts: [partA, partB] }); // 挂到 Game Object 上 const player = this.matter.add.sprite(400, 200, 'hero'); player.setExistingBody(compoundBody);

所有部件共享位置、角度与速度。约束必须作用于父体,不能直接作用在子部件(parts)上。

休眠系统(Sleep)

静止的刚体可以休眠以跳过模拟,需要先在配置中开启enableSleeping: true

if (body.isSleeping) { /* 刚体处于静止休眠 */ } sprite.setSleepThreshold(30); // 数值越低越快入睡(默认 60) sprite.setToSleep(); // 强制入睡 sprite.setAwake(); // 强制唤醒 sprite.setSleepEvents(true, true); // 开启 sleepstart / sleepend 事件 this.matter.world.on('sleepstart', (event, body) => { /* 刚体入睡 */ }); this.matter.world.on('sleepend', (event, body) => { /* 刚体醒来 */ });

传感器(Sensors)

传感器检测碰撞但不产生物理反应,适合触发区域、拾取物、探测区:

const trigger = this.matter.add.rectangle(400, 300, 100, 100, { isSensor: true, isStatic: true }); sprite.setSensor(true); // 在 Game Object 上切换 sprite.isSensor(); // 查询状态 // 传感器同样触发普通碰撞事件——用 collisionstart/end 判断进出

碰撞分类与过滤

Matter 使用位掩码:category(该刚体属于哪一组,须为 2 的幂)、mask(该刚体与哪些类别碰撞)以及group(快捷方式:相同正数 = 总是碰撞,相同负数 = 永不碰撞,0 = 使用 category/mask):

const PLAYER = this.matter.world.nextCategory(); // 0x0002(最多 32 个类别) const ENEMY = this.matter.world.nextCategory(); // 0x0004 const GROUND = this.matter.world.nextCategory(); // 0x0008 player.setCollisionCategory(PLAYER); player.setCollidesWith([ENEMY, GROUND]); bullet.setCollisionCategory(0x0010); bullet.setCollidesWith([ENEMY, GROUND]); // 子弹跳过玩家 // 碰撞组:相同负数 = 相互永不碰撞 const noCollide = this.matter.world.nextGroup(true); spriteA.setCollisionGroup(noCollide); spriteB.setCollisionGroup(noCollide); // 也可在刚体配置中直接写:collisionFilter: { category, mask, group } // 批量:this.matter.setCollisionCategory([bodyA, bodyB], ENEMY);

nextCategory()nextGroup(isNonColliding)的实现位于 World.js 第 1095、1109 行。

碰撞回调

// 按刚体设置回调(Matter Game Object 上) player.setOnCollide((pair) => { /* pair.bodyA, pair.bodyB */ }); player.setOnCollideEnd((pair) => { /* 碰撞结束 */ }); player.setOnCollideActive((pair) => { /* 仍在碰撞中 */ }); player.setOnCollideWith(enemy, (body, pair) => { /* 命中特定刚体 */ }); // Game Object 级别事件(在 Game Object 本身上触发) player.on('collide', (bodyA, bodyB, pair) => {}); player.on('collideEnd', (bodyA, bodyB, pair) => {});

Tilemap 集成

const map = this.make.tilemap({ key: 'level' }); const tileset = map.addTilesetImage('tiles', 'tiles-img'); const layer = map.createLayer('Ground', tileset, 0, 0); layer.setCollisionByProperty({ collides: true }); // 必须先设置碰撞 this.matter.world.convertTilemapLayer(layer); // 为每个碰撞瓦片创建 MatterTileBody // 若瓦片定义了 Tiled 碰撞形状(矩形、圆形、多边形)则使用之,否则使用瓦片包围盒。 // 访问瓦片刚体:tile.physics.matterBody // 单独处理某瓦片:this.matter.add.tileBody(tile, { isStatic: true, friction: 0.5 }); // 地图变化后:this.matter.world.convertTiles([tile1, tile2]);

底层实现由 MatterTileBody.js 包装瓦片与 Matter 刚体,convertTilemapLayer/convertTiles见 World.js 第 1045、1069 行。

三类摩擦

Matter.js 有三种相互独立的摩擦值:

sprite.setFriction(0.1); // 动摩擦:运动过程中的阻力(0~1) sprite.setFrictionStatic(0.5); // 静摩擦:开始运动前的阻力 sprite.setFrictionAir(0.05); // 空气阻力:环境拖拽(默认 0.01) sprite.setFriction(0.1, 0.02, 0.3); // 一次设置全部三项:动摩擦、空气、静摩擦

由顶点构造复杂形状

// 从顶点字符串创建刚体(凹形会自动分解为凸形) const body = this.matter.add.fromVertices(400, 300, '0 0 40 0 40 40 20 60 0 40'); // 多组顶点构造复杂形状 const vertexSets = [ [{ x: 0, y: 0 }, { x: 40, y: 0 }, { x: 40, y: 40 }], [{ x: 40, y: 40 }, { x: 20, y: 60 }, { x: 0, y: 40 }] ]; this.matter.add.fromVertices(300, 200, vertexSets);

凹形的凸分解依赖poly-decomp库,其在 MatterPhysics.js 通过Common.setDecomp(require('./poly-decomp'))注入(模块位于 poly-decomp/)。

指针约束(鼠标/触屏拖拽)

// 启用对所有 Matter 刚体的点击拖拽 const pc = this.matter.add.mouseSpring({ stiffness: 0.2, damping: 0.1 }); pc.active = false; // 临时禁用 body.ignorePointer = true; // 阻止特定刚体被拖拽 pc.stopDrag(); // 程序化释放当前拖拽 pc.destroy(); // 彻底移除 // 世界上的拖拽事件 this.matter.world.on('dragstart', (body, part, constraint) => {}); this.matter.world.on('drag', (body, constraint) => {}); this.matter.world.on('dragend', (body, constraint) => {});

实现位于 PointerConstraint.js,工厂入口mouseSpring/ 别名pointerConstraint见 Factory.js。

查询(射线与命中测试)

const hits = this.matter.intersectPoint(pointer.x, pointer.y); // 某点处的刚体 const contains = this.matter.containsPoint(body, x, y); // 点是否在刚体内 const inRegion = this.matter.intersectRect(100, 100, 200, 200); // 矩形区域内的刚体 const rayHits = this.matter.intersectRay(0, 300, 800, 300, 1); // 射线检测 const colliding = this.matter.intersectBody(playerBody); // 刚体重叠查询 // 带回调的重叠检测 this.matter.overlap(playerBody, enemyBodies, (bodyA, bodyB, info) => { console.log('Overlapping', bodyA, bodyB); });

调试渲染

// 在 matter 配置的 debug 属性中传入以下选项 // 布尔开关:showBody、showStaticBody、showVelocity、showCollisions、showSensors、 // showJoint、showPositions、showBounds、showAxes、showAngleIndicator、showSleeping、 // showConvexHulls、showInternalEdges、renderFill、renderLine // 颜色/样式:lineColor、lineThickness、fillColor、staticLineColor、staticFillColor、 // sensorLineColor、jointColor、pinColor、springColor、anchorColor、positionColor // 运行时切换调试显示 this.matter.world.drawDebug = false; this.matter.world.debugGraphic.visible = false; // 单独设置刚体或约束的渲染样式 this.matter.world.setBodyRenderStyle(body, 0xff0000, 1, 2, 0x00ff00, 0.5); this.matter.world.setConstraintRenderStyle(constraint, 0xffff00, 1, 2);

debug支持布尔值或完整的MatterDebugConfig对象(如showBodyshowStaticBodyshowBroadphaseshowSleepingstaticBodySleepOpacity等),全部字段与默认值见 MatterDebugConfig.js,渲染样式设置见 World.js 第 387、474 行的setBodyRenderStyle/setConstraintRenderStyle

事件系统

所有事件都通过this.matter.world触发(World继承自EventEmitter,见 World.js),并代理全部 Matter.js 底层事件。事件常量定义于 events/ 目录:

事件回调签名触发时机
'collisionstart'(event, bodyA, bodyB)两个刚体首次开始碰撞
'collisionactive'(event, bodyA, bodyB)两个刚体仍在碰撞中
'collisionend'(event, bodyA, bodyB)两个刚体停止碰撞
'beforeupdate'(event)引擎步进更新前
'afterupdate'(event)引擎步进更新后
'beforeadd'(event)刚体/约束被添加前
'afteradd'(event)刚体/约束被添加后
'beforeremove'(event)刚体/约束被移除前
'afterremove'(event)刚体/约束被移除后
'dragstart'(body, part, constraint)指针开始拖拽刚体
'drag'(body, constraint)指针正在拖拽刚体
'dragend'(body, constraint)指针停止拖拽刚体
'sleepstart'(event, body)刚体入睡(需启用setSleepEvents
'sleepend'(event, body)刚体唤醒(需启用setSleepEvents
'pause'世界暂停
'resume'世界恢复

碰撞事件包含event.pairs—— 碰撞对数组,每个元素含bodyAbodyB、碰撞深度与法线。世界暂停/恢复的实现见 World.js 第 1125、1143 行的pause/resume

API 快速参考

this.matter.add(Factory)

  • Game Objects:sprite(x, y, key, frame?, opts?)image(x, y, key, frame?, opts?)gameObject(go, opts?)tileBody(tile, opts?)
  • 刚体形状:rectangle(x, y, w, h, opts?)circle(x, y, r, opts?)polygon(x, y, sides, r, opts?)trapezoid(x, y, w, h, slope, opts?)fromVertices(x, y, verts, opts?)fromPhysicsEditor(x, y, config, opts?)fromSVG(x, y, xml, scale?, opts?)fromJSON(x, y, config, opts?)
  • 约束:constraint(a, b, len?, stiff?, opts?)(别名jointspring)、worldConstraint(body, len?, stiff?, opts?)mouseSpring(opts?)(别名pointerConstraint
  • 复合体:stack(x, y, cols, rows, colGap, rowGap, cb)imageStack(key, frame, x, y, cols, rows)pyramid(...)chain(composite, xA, yA, xB, yB, opts?)mesh(composite, cols, rows, cross, opts?)softBody(...)car(x, y, w, h, wheelSize)newtonsCradle(x, y, num, size, len)

this.matter(MatterPhysics)批量与工具方法

pause()resume()set60Hz()set30Hz()step(delta?)setVelocity(bodies, x, y)setAngularVelocity(bodies, v)applyForce(bodies, force)applyForceFromAngle(bodies, speed, angle?)containsPoint(body, x, y)intersectPoint(x, y)intersectRect(x, y, w, h, outside?)intersectRay(x1, y1, x2, y2, width?)intersectBody(body)overlap(target, bodies?, cb?)setCollisionCategory(bodies, value)setCollisionGroup(bodies, value)setCollidesWith(bodies, cats)alignBody(body, x, y, align)

this.matter.world(World)

setBounds(x?, y?, w?, h?, thickness?, l?, r?, t?, b?)setGravity(x?, y?, scale?)disableGravity()add(object)remove(object, deep?)removeConstraint(constraint)convertTilemapLayer(layer, opts?)convertTiles(tiles, opts?)nextCategory()nextGroup(isNonColliding?)getAllBodies()has(body)pause()resume()

this.matter上的 Matter.js 底层模块引用

body(Matter.Body)、bodies(Matter.Bodies)、composite(Matter.Composite)、composites(Matter.Composites)、constraint(Matter.Constraint)、collision(Matter.Collision)、detectorquerypairpairsresolveraxesboundssvgvectorvertices(别名verts)。这些模块的完整清单与用途注释见 MatterPhysics.js,对应底层库文件位于 lib/(含 Body、Composite、World、Detector、Engine、Bodies、Composites、Vertices、Constraint 等完整 Matter.js 模块)。

易踩的坑(Gotchas)

  • 力的数值极小。力用0.010.1,速度用115。两者都不是像素单位。
  • setBody/setRectangle等会重置所有属性—— 质量、摩擦、碰撞过滤、回调都会被清空,更换形状后需要重新设置。
  • 约束必须指向父体,不能指向复合刚体的parts子部件。
  • 碰撞类别最多 32 个。每次nextCategory()占用一个 bit。
  • collisionFilter.group优先于 category/mask。相同正数 = 总是碰撞;相同负数 = 永不碰撞;0 或不同 = 回退到 category/mask。
  • 传感器仍需匹配的碰撞过滤条件才会触发事件。
  • Matter 位置是质心,不是左上角(与 Arcade Physics 不同)。
  • 休眠事件需要显式开启:sprite.setSleepEvents(true, true)
  • Tilemap 转换前必须先设置碰撞(如setCollisionByProperty)。
  • 恢复系数取Math.max(bodyA.restitution, bodyB.restitution)—— 弹力更大的一方决定结果。
  • body.ignorePointer = true可阻止指针约束拖拽该刚体。

源码文件地图

路径职责
src/physics/matter-js/MatterPhysics.js场景插件(this.matter),暴露全部 Matter 模块
src/physics/matter-js/World.js世界管理、引擎、边界、调试、事件代理
src/physics/matter-js/Factory.jsthis.matter.add—— 全部创建方法
src/physics/matter-js/MatterSprite.js物理精灵(Sprite + Matter 组件)
src/physics/matter-js/MatterImage.js物理图像(Image + Matter 组件)
src/physics/matter-js/MatterGameObject.js向任意 Game Object 注入 Matter 组件
src/physics/matter-js/MatterTileBody.js用 Matter 刚体包装单个瓦片
src/physics/matter-js/PointerConstraint.js点击拖拽刚体约束
src/physics/matter-js/BodyBounds.js按视觉边界对齐刚体
src/physics/matter-js/PhysicsEditorParser.js解析 PhysicsEditor JSON 为刚体
src/physics/matter-js/components/Mixin:Velocity、Force、Collision、SetBody、Sensor、Bounce、Friction、Mass、Gravity、Static、Sleep、Transform
src/physics/matter-js/events/事件常量(COLLISION_START、DRAG_START、SLEEP_START 等)
src/physics/matter-js/typedefs/TypeDefs:MatterWorldConfig、MatterBodyConfig、MatterCollisionFilter、MatterConstraintConfig、MatterDebugConfig 等
src/physics/matter-js/lib/打包进 Phaser 的 Matter.js 库模块

关联技能与进一步阅读

Matter 物理通常与以下主题配合使用:游戏初始化与配置(skills/game-setup-and-config/SKILL.md)、精灵与图像创建(skills/sprites-and-images/SKILL.md)、轻量级物理替代方案 Arcade Physics(skills/physics-arcade/SKILL.md)以及瓦片地图关卡搭建(skills/tilemaps/SKILL.md)。若需从 Phaser 3 迁移到 Phaser 4,可参考 skills/v3-to-v4-migration/SKILL.md。

【免费下载链接】phaserPhaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.项目地址: https://gitcode.com/gh_mirrors/ph/phaser

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询