首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对object collision threeJS使用.intersection/.intersectsBox

对object collision threeJS使用.intersection/.intersectsBox
EN

Stack Overflow用户
提问于 2021-02-04 01:11:45
回答 1查看 607关注 0票数 1

嗨,我正在用threeJS开发一个基本的突破/阿卡诺德游戏。现在我只有一个球拍和一个在屏幕上弹来弹去的球。我正在尝试让碰撞工作,这样当球击中球拍时,它就会反弹离开。我一直在尝试使用边界框来实现这一点,但是我遇到了一个问题,即.intersection/.intersectsBox没有正确地注册一个交叉点,我不知道为什么。下面是我到目前为止的代码-

代码语言:javascript
复制
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new THREE.BoxGeometry(5, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
var cubeBoxHelper = new THREE.BoxHelper(cube, 0xff0000);
var boundingBoxPaddle = new THREE.Box3().setFromObject(cubeBoxHelper);
cubeBoxHelper.update();

const geometrySphere = new THREE.SphereGeometry(1, 32, 32);
const materialSphere = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const sphere = new THREE.Mesh(geometrySphere, materialSphere);
var sphereBoxHelper = new THREE.BoxHelper(sphere, 0xff0000);
var boundingBoxBall = new THREE.Box3().setFromObject(sphereBoxHelper);
sphereBoxHelper.update();

scene.add(cube, cubeBoxHelper, sphere, sphereBoxHelper);

sphere.position.y = 5;
camera.position.z = 15;
camera.position.y = 10;

var xSpeed = 0.0005;
var dx = 0.1;
var dy = 0.1;

function bounce()
{
    if (sphere.position.x < -19 || sphere.position.x > 18.5)
    {
        dx = -dx;
    }
    if (sphere.position.y < -5 || sphere.position.y > 19)
    {
        dy = -dy;
    }
    sphere.position.x += dx;
    sphere.position.y += dy;
    sphereBoxHelper.update();
}

function intersect()
{
    if (boundingBoxBall.intersect(boundingBoxPaddle) == true)
    {
        console.log("intersection");
    }
}

const animate = function ()
{
    requestAnimationFrame(animate);

    document.addEventListener("keydown", onDocumentKeyDown, false);
    function onDocumentKeyDown(event)
    {
        var keyCode = event.which;
        if (keyCode == 65 && cube.position.x >= -18.5)
        {
            cube.position.x -= xSpeed;
        }
        else if (keyCode == 68 && cube.position.x <= 18)
        {
            cube.position.x += xSpeed;
        }
        cubeBoxHelper.update();
    };
    bounce();
    intersect();
    sphereBoxHelper.update();
    renderer.render(scene, camera);
};

animate();

现在我已经设置了它,所以intersect函数只会记录到控制台,这样我就可以知道发生了什么。任何帮助都是很好的,因为我不确定我做错了什么。

EN

回答 1

Stack Overflow用户

发布于 2021-02-04 05:29:23

Box3.intersect

.intersect (框: Box3 ):此框-要与之相交的框。

计算this和box的交集,将此box的上界设置为两个box的上界中较小的一个,并将此box的下界设置为两个box的下界中的较大者。如果没有重叠,则使此框为空。

这个函数实际做的是用来自boundingBoxPaddle的信息更新boundingBoxBall,甚至可能将boundingBoxBall设置为一个空框!

我认为你真正想要的功能是:

Box3.intersectsBox

.intersectsBox (框: Box3 ):布尔框-用于检查交集的框。

确定此长方体是否与长方体相交。

intersectsBox函数返回一个简单的true/false,因此您可以判断这两个框是否发生了冲突。

另请注意,您的边界框相对于关联的几何体。如果变换Mesh,则还需要变换边界框。Box3 docs上的示例代码实际上突出显示了这一点:

代码语言:javascript
复制
const box = new THREE.Box3();

// ...

// in the animation loop, compute the current bounding box with the world matrix
box.copy( mesh.geometry.boundingBox ).applyMatrix4( mesh.matrixWorld );

完整示例:

代码语言:javascript
复制
let W = window.innerWidth;
let H = window.innerHeight;

const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true
});
document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(28, 1, 1, 1000);
camera.position.set(0, 0, 50);
camera.lookAt(scene.position);
scene.add(camera);

const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 0, -1);
camera.add(light);

let geo = new THREE.BoxBufferGeometry(5, 5, 5);
geo.computeBoundingBox();
let mat = new THREE.MeshPhongMaterial({
  color: "red"
});
const left = new THREE.Mesh(geo, mat);
left.position.set(-15, 0, 0)
scene.add(left);
const right = new THREE.Mesh(geo, mat);
right.position.set(15, 0, 0)
scene.add(right);

geo = new THREE.SphereBufferGeometry(1, 16, 16);
geo.computeBoundingBox();
mat = new THREE.MeshPhongMaterial({
  color: "yellow"
});
const ball = new THREE.Mesh(geo, mat);
scene.add(ball);

function render() {
  renderer.render(scene, camera);
}

function resize() {
  W = window.innerWidth;
  H = window.innerHeight;
  renderer.setSize(W, H);
  camera.aspect = W / H;
  camera.updateProjectionMatrix();
  render();
}

let rate = 0.1;
let goingRight = true;
let ballBox = new THREE.Box3();
let wallBox = new THREE.Box3();

function animate() {
  render();

  ball.position.x += ((goingRight) ? 1 : -1) * rate;
  ball.updateMatrix();
  ball.updateMatrixWorld(true);

  ballBox.copy(ball.geometry.boundingBox);
  ballBox.applyMatrix4(ball.matrixWorld);

  if (goingRight) {
    wallBox.copy(right.geometry.boundingBox);
    wallBox.applyMatrix4(right.matrixWorld);
    if (ballBox.intersectsBox(wallBox)) {
      goingRight = false;
    }
  } else {
    wallBox.copy(left.geometry.boundingBox);
    wallBox.applyMatrix4(left.matrixWorld);
    if (ballBox.intersectsBox(wallBox)) {
      goingRight = true;
    }
  }

  requestAnimationFrame(animate);
}

window.addEventListener("resize", resize);

resize();
requestAnimationFrame(animate);
代码语言:javascript
复制
html,
body {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
  background: skyblue;
}
代码语言:javascript
复制
<script src="https://threejs.org/build/three.min.js"></script>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66032362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档