计算振幅:您必须在模拟循环中应用力量
关注力的振幅/持续时间部分,重要的是要知道您应该在每个模拟步骤中一次性地施加力量,这可以通过beforeUpdate
回调函数完成:
所以类似于:
const moveForce = 0.01
const keysDown = new Set()
const keyHandlers = {
KeyW: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, { x: 0, y: -moveForce } )
},
KeyS: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, { x: 0, y: moveForce } )
},
}
document.addEventListener("keydown", event => {
keysDown.add(event.code)
});
document.addEventListener("keyup", event => {
keysDown.delete(event.code)
});
Matter.Events.on(engine, 'beforeUpdate', event => {
;[...keysDown].forEach(k => {
keyHandlers[k]?.();
});
});
这是一个完整的最小可运行示例,它修改了
Matter.js 你好,世界,让你可以使用ASDW键移动其中一个框。
asdw.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ASDW</title>
<script src="node_modules/matter-js/build/matter.min.js"></script>
</head>
<body>
<script>
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Bodies = Matter.Bodies,
Composite = Matter.Composite;
var engine = Engine.create();
var render = Render.create({
element: document.body,
engine: engine
});
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
Composite.add(engine.world, [boxA, boxB, ground]);
const moveForce = 0.01
const keysDown = new Set()
const keyHandlers = {
KeyW: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, { x: 0, y: -moveForce } )
},
KeyS: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, { x: 0, y: moveForce } )
},
KeyA: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, { x: -moveForce, y: 0 } )
},
KeyD: () => {
Matter.Body.applyForce(boxA, {
x: boxA.position.x,
y: boxA.position.y
}, { x: moveForce, y: 0 } )
},
}
document.addEventListener("keydown", event => {
keysDown.add(event.code)
});
document.addEventListener("keyup", event => {
keysDown.delete(event.code)
});
Matter.Events.on(engine, 'beforeUpdate', event => {
;[...keysDown].forEach(k => {
keyHandlers[k]?.();
});
});
Render.run(render);
var runner = Runner.create();
Runner.run(runner, engine);
</script>
</body>
</html>
约束
另一种方法是使用约束,它们会隐式地将力正确地添加到循环中。
特别是有一个鼠标约束助手可用于鼠标用例:如何使用Matter-js Mouse允许仅移动一个物体
鼠标约束非常容易使用,您只需要使用此代码即可:https://github.com/liabru/matter-js/blob/0.19.0/examples/constraints.js#L145
const mouse = Matter.Mouse.create(render.canvas)
const mouseConstraint = Matter.MouseConstraint.create(engine, {
mouse,
constraint: {
angularStiffness: 0,
render: {
visible: false
}
}
})
Composite.add(engine.world, mouseConstraint)
render.mouse = mouse;
这使您可以通过单击并拖动它们来拖动任何块。
基于Matter.js hello world的最小可运行示例:
mouse.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mouse</title>
<script src="node_modules/matter-js/build/matter.js"></script>
</head>
<body>
<script>
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Bodies = Matter.Bodies,
Composite = Matter.Composite;
var engine = Engine.create();
var render = Render.create({
element: document.body,
engine: engine
});
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
Composite.add(engine.world, [boxA, boxB, ground]);
const mouse = Matter.Mouse.create(render.canvas)
const mouseConstraint = Matter.MouseConstraint.create(engine, {
mouse,
constraint: {
angularStiffness: 0,
render: {
visible: false
}
}
})
Composite.add(engine.world, mouseConstraint)
render.mouse = mouse;
Render.run(render);
var runner = Runner.create();
Runner.run(runner, engine);
</script>
</body>
</html>