javascript Matter.js计算所需的力

qgelzfjb  于 2023-05-27  发布在  Java
关注(0)|答案(3)|浏览(314)

我试着对一个物体施力。让它以鼠标位置相对于对象产生的Angular 移动。
我有Angular

targetAngle = Matter.Vector.angle(myBody.pos, mouse.position);

现在我需要施加一个力,让物体沿着这个Angular 移动。我应该在下面的applyForce方法的值中输入什么?

// applyForce(body, position, force)

  Body.applyForce(myBody, {
    x : ??, y : ??
  },{
    x:??, y: ?? // how do I derive this force??
  });

我在这里的x和y值中放什么,才能让身体沿着鼠标和身体之间的Angular 移动。

qrjkbowd

qrjkbowd1#

要施加一个力来移动你的对象在那个方向上,你需要采取的正弦和余弦的Angular 弧度。你只需要传递对象的位置作为第一个向量,而不应用转矩(旋转)。

var targetAngle = Matter.Vector.angle(myBody.pos, mouse.position);
var force = 10;

Body.applyForce(myBody, myBody.position, {
  x: cos(targetAngle) * force, 
  y: sin(targetAngle) * force
});

如果你需要的话,applyForce()的文档也在这里。
(我知道这个问题很老了,我或多或少是为了那些偶然遇到它的人而做的)

8i9zcol2

8i9zcol22#

您可以依赖Matter.Vector模块,并使用它来减去,归一化和乘以位置向量:

var force = 10;
var deltaVector = Matter.Vector.sub(mouse.position, myBody.position);
var normalizedDelta = Matter.Vector.normalise(deltaVector);
var forceVector = Matter.Vector.mult(normalizedDelta, force);
Body.applyForce(myBody, myBody.position, forceVector);
1hdlvixo

1hdlvixo3#

计算振幅:你必须在模拟循环中施加力

重点关注力的幅度/持续时间部分,重要的是要知道您应该在每个模拟步骤中随时间施加一次力,这可以从beforeUpdate回调中完成:

  • https://brm.io/matter-js/docs/classes/Body.html#method_applyForce
  • 键盘移动在matter.js中不稳定

比如说

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 hello world,允许您使用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>
// module aliases
var Engine = Matter.Engine,
    Render = Matter.Render,
    Runner = Matter.Runner,
    Bodies = Matter.Bodies,
    Composite = Matter.Composite;

// create an engine
var engine = Engine.create();

// create a renderer
var render = Render.create({
    element: document.body,
    engine: engine
});

// create two boxes and a ground
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 });

// add all of the bodies to the world
Composite.add(engine.world, [boxA, boxB, ground]);

// Move boxA with ASDW
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]?.();
  });
});

// run the renderer
Render.run(render);

// create runner
var runner = Runner.create();

// run the engine
Runner.run(runner, engine);
</script>
</body>
</html>

约束条件

另一种方法是使用约束,它隐式地将力正确地添加到循环中。
特别地,存在用于鼠标用例的鼠标约束帮助器:How to allow only a single body to move using Matter-js Mouse
鼠标约束非常容易使用,您所需要的只是从www.example.com改编的代码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: {
    // allow bodies on mouse to rotate
    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>
// module aliases
var Engine = Matter.Engine,
    Render = Matter.Render,
    Runner = Matter.Runner,
    Bodies = Matter.Bodies,
    Composite = Matter.Composite;

// create an engine
var engine = Engine.create();

// create a renderer
var render = Render.create({
    element: document.body,
    engine: engine
});

// create two boxes and a ground
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 });

// add all of the bodies to the world
Composite.add(engine.world, [boxA, boxB, ground]);

// Add mouse control
const mouse = Matter.Mouse.create(render.canvas)
const mouseConstraint = Matter.MouseConstraint.create(engine, {
  mouse,
  constraint: {
    // allow bodies on mouse to rotate
    angularStiffness: 0,
    render: {
      visible: false
    }
  }
})
Composite.add(engine.world, mouseConstraint)
render.mouse = mouse;

// run the renderer
Render.run(render);

// create runner
var runner = Runner.create();

// run the engine
Runner.run(runner, engine);
</script>
</body>
</html>

相关问题