我正在使用 Matter.js 开发一个项目,我希望一般启用重力,但我希望能够在特定时间为单个对象禁用和重新启用它。我不想将该对象设置为静态,因为我希望物理引擎以其他方式处理它,我只是不希望重力影响它。
我发现这个问题通常涉及禁用重力,但正如我所说,我希望重力适用于大多数物体。有没有一种简单的方法可以做到这一点?
我正在使用 Matter.js 开发一个项目,我希望一般启用重力,但我希望能够在特定时间为单个对象禁用和重新启用它。我不想将该对象设置为静态,因为我希望物理引擎以其他方式处理它,我只是不希望重力影响它。
我发现这个问题通常涉及禁用重力,但正如我所说,我希望重力适用于大多数物体。有没有一种简单的方法可以做到这一点?
这是一个简单的代码片段,您可以打开/关闭它来完成您的要求(body
应该忽略重力的对象在哪里,并且noGravity
是一个可以切换以打开和关闭它的布尔值):
Events.on(engine, 'beforeUpdate', function() {
var gravity = engine.world.gravity;
if (noGravity) {
Body.applyForce(body, body.position, {
x: -gravity.x * gravity.scale * body.mass,
y: -gravity.y * gravity.scale * body.mass
});
}
});
禁用内置重力,然后有选择地应用您自己的重力,类似这样,但只过滤您想要的物体:
engine.world.gravity.scale = 0;
Events.on(engine, 'beforeUpdate', function() {
var bodies = Composite.allBodies(engine.world);
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
if (body.isStatic || body.isSleeping)
continue;
body.force.y += body.mass * 0.001;
}
});
我知道这是一个老问题,但现在你可以使用这个:
body.ignoreGravity = true;
我发现这很容易实现。只需在 Matter 源代码中查找 Engine._bodiesApplyGravity 函数,然后放置您需要的任何条件即可排除主体。
Engine._bodiesApplyGravity = function (bodies, gravity) {
var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;
if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
return;
}
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
// I just added body.ignoreGravity
if (body.isStatic || body.isSleeping || body.ignoreGravity)
continue;
// apply gravity
body.force.y += body.mass * gravity.y * gravityScale;
body.force.x += body.mass * gravity.x * gravityScale;
}
};
这似乎提供了一种反作用力。我不确定 200 是从哪里来的,它刚刚起作用。也许引擎每个周期计算两次力。
playerBody.force.y = -engine.world.gravity.y / 200;
您将不得不在每个周期运行它以保持它。
就我而言,我想要一个对象跟随鼠标。设置isStatic: true
使重力不适用于让我完全控制对象的位置。