使用.intersect/. intersectsbox来处理对象碰撞的三个ejs



嗨,我正在制作一个基本的breakout/arkanoid游戏。现在我只有一个球拍和一个在屏幕上弹来弹去的球。我试着让碰撞工作,这样当球击中球拍时,它会弹开。我一直试图使用边界框来实现这一点,但我遇到了一个问题,其中。intersect/。intersectsbox没有正确注册一个交集,我不知道为什么。下面是我到目前为止的代码-

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();

现在我已经设置了,所以相交函数只是记录到控制台,所以我可以告诉发生了什么。我不知道我做错了什么,请帮忙就太好了。

Box3.intersect

.intersect (box: Box3): thisbox -与之相交的框。

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

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

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

Box3.intersectsBox

.intersectsBox (box: Box3):布尔值box -用于检查是否与。

相交叉的方框确定此框是否与此框相交。

intersectsBox函数返回一个简单的true/false,因此您可以判断两个盒子是否碰撞。

还要注意,您的边界框是相对于相关的几何图形的。如果你对Mesh进行了变换,那么你还需要对边界框进行变换。Box3 docs上的示例代码实际上突出了这一点:

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 );

完整例子:

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);
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
background: skyblue;
}
<script src="https://threejs.org/build/three.min.js"></script>

最新更新