javascript - Matter.JS 约束在对象旋转后就像弹弓一样
问题描述
我在使用 MatterJS 库进行简单测试时遇到了问题。
我想构建一种通过设置其第一个元素的速度和角度来控制的火车(链,蛇)(请参阅下面的代码)。我希望有一些刚度和阻尼,但是在应用一些旋转约束之后开始像弹弓一样,扩展然后将两个对象移动到随机方向。
这是某种浮点问题吗?我在当前的引擎设置等方面没有发现任何问题。可以以某种方式处理吗?
测试片段(包含主游戏类和实用键盘功能):
function keyboard(value) {
let key = {};
key.value = value;
key.isDown = false;
key.isUp = true;
key.press = undefined;
key.release = undefined;
key.downHandler = event => {
if (event.key === key.value) {
if (key.isUp && key.press) key.press();
key.isDown = true;
key.isUp = false;
event.preventDefault();
}
};
key.upHandler = event => {
if (event.key === key.value) {
if (key.isDown && key.release) key.release();
key.isDown = false;
key.isUp = true;
event.preventDefault();
}
};
//Attach event listeners
const downListener = key.downHandler.bind(key);
const upListener = key.upHandler.bind(key);
window.addEventListener(
"keydown", downListener, false
);
window.addEventListener(
"keyup", upListener, false
);
// Detach event listeners
key.unsubscribe = () => {
window.removeEventListener("keydown", downListener);
window.removeEventListener("keyup", upListener);
};
return key;
}
const Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Body = Matter.Body,
Bodies = Matter.Bodies,
Mouse = Matter.Mouse,
Runner = Matter.Runner,
Composite = Matter.Composite;
class Game {
constructor(document) {
this.engine = Engine.create({
gravity: {
y: 0,
}
});
let position = {x: 100, y: 100};
this.createLeader(position);
position.x -= 70;
this.createFollower(position);
this.attachFollower();
this.setupControls();
Runner.run(this.engine);
this.setupRender();
}
createLeader = (position) => {
this.leader = Bodies.rectangle(
0,
0,
64,
64,
{
//restitution: 0.8,
position,
density: 0.1
}
);
World.addBody(this.engine.world, this.leader);
}
createFollower = (position) => {
this.follower = Bodies.rectangle(
0,
0,
45,
45,
{
//restitution: 0.8,
position,
density: 0.01,
}
);
World.addBody(this.engine.world, this.follower);
}
attachFollower = () => {
let attachTo = [{x: -30, y: -10}, {x: -30, y: 10}];
let attachableAt = [{x: 20, y: -10}, {x: 20, y: 10}];
this.constraints = attachableAt.map((point, index) => {
return Matter.Constraint.create({
bodyA: this.leader,
pointA: attachTo[index],
bodyB: this.follower,
pointB: point,
//length: 20,
stiffness: 0.01,
damping: 0.1
});
});
Composite.add(this.engine.world, [this.leader, this.follower, ...this.constraints]);
}
setupControls = () => {
this.right = keyboard('d');
requestAnimationFrame(this.update);
}
setupRender = () => {
var render = Render.create({
element: document.body,
engine: this.engine,
options: {
width: window.innerWidth,
height: window.innerHeight,
showAngleIndicator: true,
wireframes: true,
wireframeBackground: '#000000',
showBounds: true,
}
});
Render.run(render);
}
update = () => {
if(this.right.isDown) {
this.leader.angle += 0.001;
}
requestAnimationFrame(this.update);
}
}
function onLoad() {
game = new Game(document);
}
onLoad();
* {
padding: 0;
margin: 0
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>
重现问题的步骤:
- 运行代码片段
- 按住“D”键可旋转对象约 10 分钟。300度。
- 释放“D”键
结果:两个物体都飞走了
解决方案
推荐阅读
- sql - 如何从一个表中获取包含另一表的详细信息的记录计数
- node.js - NodeJS child_process.spawn() 截断长输出
- c++ - 使用 rxcpp 和 cpr 的计时器事件(获取请求)
- c++ - 在 C++ 中使用所有 32 位整数的算术溢出?
- python - 如何将列表中的特定项目称为另一个列表
- powershell - PowerShell:迭代多个变量未按预期工作
- c++ - 书中令人费解的段落:`Cross-Platform Development with Qt 6 and Modern C++`
- google-cloud-platform - GCP GKE 入口运行状况检查
- php - 在php中创建动态表单
- laravel - 无法进入最后一页和 bootstrap laravel 分页的倒数第二