javascript - 为什么 MatterJS 物理坐标与 DOM 元素有偏移?

标签 javascript physics matter.js

我正在通过向物理引擎添加盒子来运行 MatterJS 物理模拟,同时创建具有相同尺寸的 DOM 元素。

然后,我循环遍历物理框以获取它们的坐标。然后我使用这些坐标来定位相应的 DOM 元素。这似乎工作正常,除了我的静态“地面”框周围似乎有一个 10 像素的不可见半径?

我的盒子是 40x40 像素。地面为 400 像素。盒子在 350 像素处停止下落。那么为什么会有 10 像素的差异呢?

Here is an example of the issue in CodePen

编辑:如果我在 Canvas 中渲染相同的框,则不存在差异。 Codepen Canvas

class Box {
  constructor(world, x, y, w, h, options) {
    // add box to physics simulation
    this.physicsBox = Matter.Bodies.rectangle(x, y, w, h, options);
    Matter.Composite.add(world, this.physicsBox);

    // add DOM box at the same coordinates
    this.div = document.createElement("box");
    document.body.appendChild(this.div);
    this.div.style.width = w + "px";
    this.div.style.height = h + "px";
    this.update();
  }

  update() {
    let pos = this.physicsBox.position;
    let angle = this.physicsBox.angle;
    let degrees = angle * (180 / Math.PI);
    this.div.style.transform = `translate(${pos.x}px, ${pos.y}px) rotate(${degrees}deg)`;
  }
}

let engine;
let boxes = [];

setupMatter();
addObjects();
gameLoop();

function setupMatter() {
  engine = Matter.Engine.create();
}

function addObjects() {
  boxes.push(
    new Box(engine.world, 250, 20, 40, 40),
    new Box(engine.world, 300, 350, 40, 40),
    new Box(engine.world, 320, 70, 40, 40),
    new Box(engine.world, 0, 400, 800, 60, { isStatic: true })
  );
}

function gameLoop() {
  // update the physics world
  Matter.Engine.update(engine, 1000 / 60);
  // update the DOM world
  for (let b of boxes) {
    b.update();
  }
  requestAnimationFrame(() => this.gameLoop());
}
html,
body {
  background-color: #4b4b4b;
  color: white;
  margin: 0px;
  padding: 0px;
}

box {
  margin: 0px;
  padding: 0px;
  box-sizing: border-box;
  position: absolute;
  display: block;
  background-color: rgba(45, 188, 232, 0.687);
  transform-origin: 20px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>

最佳答案

问题是当你设置盒子的 x,y 位置时,你没有考虑高度。所以显示的位置与实际位置不符。

我真正改变的唯一一行是 this.div.style.transform = `translate(${pos.x}px, ${pos.y}px)rotate(${ Degrees}deg) `;.

造成 10 像素差异的原因是 60 像素深的底座显示太低 30 像素(深度的一半),而 40 像素深的框显示太低 20 像素 - 底座上方净 10 像素。当我尝试将高度设置为 1px 时,一切看起来都不错,这就是我发现该错误的原因。

class Box {
  constructor(world, x, y, w, h, options) {
    // add box to physics simulation
    this.physicsBox = Matter.Bodies.rectangle(x, y, w, h, options);
    Matter.Composite.add(world, this.physicsBox);

    // add DOM box at the same coordinates
    this.div = document.createElement("box");
    document.body.appendChild(this.div);
    this.div.style.width = w + "px";
    this.div.style.height = h + "px";
    this.width = w;
    this.height = h;
    this.update();
  }

  update() {
    let pos = this.physicsBox.position;
    let angle = this.physicsBox.angle;
    let degrees = angle * (180 / Math.PI);
    this.div.style.transform = `translate(${pos.x - (this.width/2)}px, ${pos.y-(this.height/2)}px) rotate(${degrees}deg)`;
  }
}

let engine;
let boxes = [];

setupMatter();
addObjects();
gameLoop();

function setupMatter() {
  engine = Matter.Engine.create();
}

function addObjects() {
  boxes.push(
    new Box(engine.world, 250, 20, 40, 40),
    new Box(engine.world, 300, 350, 40, 40),
    new Box(engine.world, 320, 70, 40, 40),
    new Box(engine.world, 0, 400, 800, 60, { isStatic: true })
  );
}

function gameLoop() {
  // update the physics world
  Matter.Engine.update(engine, 1000 / 60);
  // update the DOM world
  for (let b of boxes) {
    b.update();
  }
  requestAnimationFrame(() => this.gameLoop());
}
html,
body {
  background-color: #4b4b4b;
  color: white;
  margin: 0px;
  padding: 0px;
}

box {
  margin: 0px;
  padding: 0px;
  box-sizing: border-box;
  position: absolute;
  display: block;
  background-color: rgba(45, 188, 232, 0.687);
  transform-origin: 20px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>

关于javascript - 为什么 MatterJS 物理坐标与 DOM 元素有偏移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67604421/

相关文章:

javascript - 解决 Node.js 中的 "Uncaught ReferenceError: require is not defined"错误

javascript - Typescript 对象 [对象数组] 在 Ionic 3 中没有方法 'includes'

algorithm - 台球AI

physics - 两个移动四面体之间的连续碰撞检测

c# - 简单的二维火箭动力学

javascript - Matter.js 计算所需的力

javascript - 如何在 Phaser 3 中使用 Sprite 的 X 和 Y 位置来实现 "Fling"物理?

javascript - 访问数组中的所有其他项 - JavaScript

javascript - polymer 绑定(bind)数据到使用 innerHTML 加载的元素