我用Rapier.js做了一個簡單的例子來說明我在CodePen 上的問題。
我正在嘗試使用物理引擎 Rapier 的 JavaScript API 來渲染帶有碰撞檢測的 DOM 元素。如果元素大小相同,則它按預期作業,但如果兩個不同大小的矩形相互互動,則對齊關閉。在CodePen中,您可以看到兩個因重力而落到地上的盒子。底部的正確停在地面上,但頂部的仍然懸停在底部的上方。如果我將框更改為相同的高度,那么它們會按預期作業。我究竟做錯了什么?
import RAPIER from "https://cdn.skypack.dev/@dimforge/rapier2d-compat";
const createBox = (id) => {
const element = document.getElementById(id);
const rect = element.getBoundingClientRect();
const rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic().setTranslation(
rect.x,
rect.y
);
const rigidBody = world.createRigidBody(rigidBodyDesc);
const colliderDesc = RAPIER.ColliderDesc.cuboid(
rect.width / 2,
rect.height / 2
);
world.createCollider(colliderDesc, rigidBody);
return [rigidBody, element];
};
await RAPIER.init();
const gravity = { x: 0.0, y: 9.81 };
const world = new RAPIER.World(gravity);
const groundRect = document.getElementById(`ground`).getBoundingClientRect();
const colliderDesc = RAPIER.ColliderDesc.cuboid(
groundRect.width / 2,
groundRect.height / 2
).setTranslation(groundRect.x, groundRect.y);
world.createCollider(colliderDesc);
const [oneBody, oneElement] = createBox(`one`);
const [twoBody, twoElement] = createBox(`two`);
const gameLoop = () => {
world.step();
const oneTranslation = oneBody.translation();
oneElement.style.left = `${oneTranslation.x}px`;
oneElement.style.top = `${oneTranslation.y}px`;
const twoTranslation = twoBody.translation();
twoElement.style.left = `${twoTranslation.x}px`;
twoElement.style.top = `${twoTranslation.y}px`;
requestAnimationFrame(gameLoop);
};
gameLoop();
uj5u.com熱心網友回復:
Rapier 長方體的中心位于矩形的中間,而不是左上角。所以你需要在你的 DOM 元素定位中考慮到這一點:
import RAPIER from "https://cdn.skypack.dev/@dimforge/rapier2d-compat";
const createBox = (id) => {
const element = document.getElementById(id);
const rect = element.getBoundingClientRect();
console.log(rect);
const rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic().setTranslation(
rect.x rect.width / 2,
rect.y rect.height / 2
);
const rigidBody = world.createRigidBody(rigidBodyDesc);
const colliderDesc = RAPIER.ColliderDesc.cuboid(
rect.width / 2,
rect.height / 2
);
world.createCollider(colliderDesc, rigidBody);
return [rigidBody, element, rect];
};
await RAPIER.init();
const gravity = { x: 0.0, y: 9.81 };
const world = new RAPIER.World(gravity);
const groundRect = document.getElementById(`ground`).getBoundingClientRect();
const colliderDesc = RAPIER.ColliderDesc.cuboid(
groundRect.width / 2,
groundRect.height / 2
).setTranslation(groundRect.x groundRect.width / 2, groundRect.y groundRect.height / 2);
world.createCollider(colliderDesc);
const [oneBody, oneElement, oneRect] = createBox(`one`);
const [twoBody, twoElement, twoRect] = createBox(`two`);
const gameLoop = () => {
world.step();
const oneTranslation = oneBody.translation();
oneElement.style.left = `${oneTranslation.x - oneRect.width / 2}px`;
oneElement.style.top = `${oneTranslation.y - oneRect.height / 2}px`;
const twoTranslation = twoBody.translation();
twoElement.style.left = `${twoTranslation.x - twoRect.width / 2}px`;
twoElement.style.top = `${twoTranslation.y - twoRect.height / 2}px`;
requestAnimationFrame(gameLoop);
};
gameLoop();
另請記住,您沒有在此處考慮輪換。對于這個特定的示例來說它并不重要,因為它們不會旋轉,但如果它們旋轉,您的渲染將與物理所做的不匹配。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/510219.html
