如何删除 ThreeJS 中的 Box3?
How to remove Box3 in ThreeJS?
我正在使用 Box3
来检测路口,以便玩家可以收集硬币。我希望在检测到硬币与玩家相交后将其移除,但由于某种原因,我无法移除它的(硬币)Box3
.
我已经阅读了文档并推断出 Box3
与项目的几何形状相关联,但是移除几何形状并从场景中移除项目似乎并没有移除 Box3;它只是留在原地,仍然与玩家互动。
我的代码fiddle:https://jsfiddle.net/ImLost/g3mu1fqe/2/
代码:
function main() {
const canvas = document.querySelector('#canva');
const renderer = new THREE.WebGLRenderer({ canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
/* Camera */
const fov = 40;
const aspect = window.innerWidth / window.innerHeight;
const near = 0.1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 65, -45);
camera.up.set(0, 0, 1);
camera.lookAt(0, 0, 0);
const scene = new THREE.Scene();
/* Lights */
const mainLight = new THREE.DirectionalLight(0xffffff, .85);
mainLight.position.set(0, 20, 0);
scene.add(mainLight);
mainLight.castShadow = true;
mainLight.shadow.mapSize.width = 2048;
mainLight.shadow.mapSize.height = 2048;
/* Board */
const boardGeometry = new THREE.PlaneGeometry(50, 50);
const boardMaterial = new THREE.MeshToonMaterial({ color: 0xEEEEEE, side: THREE.DoubleSide });
const board = new THREE.Mesh(boardGeometry, boardMaterial);
board.rotation.x = Math.PI / 2; //The board must be placed flat on the x axis
scene.add(board);
/* Player */
const playerBox = new THREE.Box3() // Used to determine collisions
const playerGeometry = new THREE.BoxGeometry(1, 1, 1.5);
const playerMaterial = new THREE.MeshToonMaterial({ color: 0xAAAAAA });
const player = new THREE.Mesh(playerGeometry, playerMaterial);
player.geometry.computeBoundingBox(playerBox);
scene.add(player);
/* Box helper */
const playerHelper = new THREE.Box3Helper(playerBox, 0xffff00);
scene.add(playerHelper);
/* Coin */
const smallCollectibleRadius = .4
const bigCollectibleRadius = .6
const coinBox = new THREE.Box3();
const coinGeometry = new THREE.SphereGeometry(smallCollectibleRadius, 100, 100);
const coinMaterial = new THREE.MeshToonMaterial({ color: 0xffff00, emissive: 0xffff00 });
const coin = new THREE.Mesh(coinGeometry, coinMaterial);
coin.position.set(0, 0, 3)
scene.add(coin);
coin.geometry.computeBoundingBox(coinBox);
const coinHelper = new THREE.Box3Helper(coinBox, 0xffff00);
scene.add(coinHelper);
function checkCollision(box) {
var collision = playerBox.intersectsBox(box);
if (collision == true) {
return true
}
}
document.addEventListener("keypress", function (event) {
if (checkCollision(coinBox)) {
console.log("Yummy coin!")
coinGeometry.dispose()
coin.geometry.dispose()
scene.remove(coin)
}
});
function render(time) {
time *= 0.001;
const speed = 0.0005
const rotSpeed = 0.00005
const dir = new THREE.Vector3();
playerBox.copy(player.geometry.boundingBox).applyMatrix4(player.matrixWorld);
coinBox.copy(coin.geometry.boundingBox).applyMatrix4(coin.matrixWorld);
document.addEventListener("keypress", function (event) {
if (event.keyCode == 119) {
player.getWorldDirection(dir);
player.position.addScaledVector(dir, speed);
}
if (event.keyCode == 115) {
player.getWorldDirection(dir);
player.position.addScaledVector(dir, -speed);
}
if (event.keyCode == 97) {
player.rotation.y += rotSpeed
}
if (event.keyCode == 100) {
player.rotation.y -= rotSpeed
}
});
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
coinGeometry.dispose()
coin.geometry.dispose()
scene.remove(coin)
上面的代码不会使您的 coin
对象无效,也不会使它的 .geometry
属性 对象无效——它只是从内存中丢弃缓冲区和属性数据。其他属性,如 boundingBox
仍然存在。否则,当您将边界框复制到 coinBox
之后 硬币被“消耗”时,您会遇到错误。
现在,您可以通过将其设置为 null
:
来使整个硬币失效
scene.remove(coin)
coin = null
但是,JavaScript 是垃圾回收的,您仍然可以在对象实际从堆中删除之前访问该对象。我会推荐一个简单的逻辑解决方法:
scene.remove(coin)
coin.userData.consumed = true
coin = null
然后在您的渲染器和关键事件侦听器中,添加对新 属性:
的检查
document.addEventListener("keypress", function (event) {
if (coin !== null && !('consumed' in coin.userData) && checkCollision(coinBox)) {
playerBox.copy(player.geometry.boundingBox).applyMatrix4(player.matrixWorld);
if( coin !== null && !('consumed' in coin.userData) ){
coinBox.copy(coin.geometry.boundingBox).applyMatrix4(coin.matrixWorld);
}
我正在使用 Box3
来检测路口,以便玩家可以收集硬币。我希望在检测到硬币与玩家相交后将其移除,但由于某种原因,我无法移除它的(硬币)Box3
.
我已经阅读了文档并推断出 Box3
与项目的几何形状相关联,但是移除几何形状并从场景中移除项目似乎并没有移除 Box3;它只是留在原地,仍然与玩家互动。
我的代码fiddle:https://jsfiddle.net/ImLost/g3mu1fqe/2/
代码:
function main() {
const canvas = document.querySelector('#canva');
const renderer = new THREE.WebGLRenderer({ canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
/* Camera */
const fov = 40;
const aspect = window.innerWidth / window.innerHeight;
const near = 0.1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 65, -45);
camera.up.set(0, 0, 1);
camera.lookAt(0, 0, 0);
const scene = new THREE.Scene();
/* Lights */
const mainLight = new THREE.DirectionalLight(0xffffff, .85);
mainLight.position.set(0, 20, 0);
scene.add(mainLight);
mainLight.castShadow = true;
mainLight.shadow.mapSize.width = 2048;
mainLight.shadow.mapSize.height = 2048;
/* Board */
const boardGeometry = new THREE.PlaneGeometry(50, 50);
const boardMaterial = new THREE.MeshToonMaterial({ color: 0xEEEEEE, side: THREE.DoubleSide });
const board = new THREE.Mesh(boardGeometry, boardMaterial);
board.rotation.x = Math.PI / 2; //The board must be placed flat on the x axis
scene.add(board);
/* Player */
const playerBox = new THREE.Box3() // Used to determine collisions
const playerGeometry = new THREE.BoxGeometry(1, 1, 1.5);
const playerMaterial = new THREE.MeshToonMaterial({ color: 0xAAAAAA });
const player = new THREE.Mesh(playerGeometry, playerMaterial);
player.geometry.computeBoundingBox(playerBox);
scene.add(player);
/* Box helper */
const playerHelper = new THREE.Box3Helper(playerBox, 0xffff00);
scene.add(playerHelper);
/* Coin */
const smallCollectibleRadius = .4
const bigCollectibleRadius = .6
const coinBox = new THREE.Box3();
const coinGeometry = new THREE.SphereGeometry(smallCollectibleRadius, 100, 100);
const coinMaterial = new THREE.MeshToonMaterial({ color: 0xffff00, emissive: 0xffff00 });
const coin = new THREE.Mesh(coinGeometry, coinMaterial);
coin.position.set(0, 0, 3)
scene.add(coin);
coin.geometry.computeBoundingBox(coinBox);
const coinHelper = new THREE.Box3Helper(coinBox, 0xffff00);
scene.add(coinHelper);
function checkCollision(box) {
var collision = playerBox.intersectsBox(box);
if (collision == true) {
return true
}
}
document.addEventListener("keypress", function (event) {
if (checkCollision(coinBox)) {
console.log("Yummy coin!")
coinGeometry.dispose()
coin.geometry.dispose()
scene.remove(coin)
}
});
function render(time) {
time *= 0.001;
const speed = 0.0005
const rotSpeed = 0.00005
const dir = new THREE.Vector3();
playerBox.copy(player.geometry.boundingBox).applyMatrix4(player.matrixWorld);
coinBox.copy(coin.geometry.boundingBox).applyMatrix4(coin.matrixWorld);
document.addEventListener("keypress", function (event) {
if (event.keyCode == 119) {
player.getWorldDirection(dir);
player.position.addScaledVector(dir, speed);
}
if (event.keyCode == 115) {
player.getWorldDirection(dir);
player.position.addScaledVector(dir, -speed);
}
if (event.keyCode == 97) {
player.rotation.y += rotSpeed
}
if (event.keyCode == 100) {
player.rotation.y -= rotSpeed
}
});
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
coinGeometry.dispose()
coin.geometry.dispose()
scene.remove(coin)
上面的代码不会使您的 coin
对象无效,也不会使它的 .geometry
属性 对象无效——它只是从内存中丢弃缓冲区和属性数据。其他属性,如 boundingBox
仍然存在。否则,当您将边界框复制到 coinBox
之后 硬币被“消耗”时,您会遇到错误。
现在,您可以通过将其设置为 null
:
scene.remove(coin)
coin = null
但是,JavaScript 是垃圾回收的,您仍然可以在对象实际从堆中删除之前访问该对象。我会推荐一个简单的逻辑解决方法:
scene.remove(coin)
coin.userData.consumed = true
coin = null
然后在您的渲染器和关键事件侦听器中,添加对新 属性:
的检查document.addEventListener("keypress", function (event) {
if (coin !== null && !('consumed' in coin.userData) && checkCollision(coinBox)) {
playerBox.copy(player.geometry.boundingBox).applyMatrix4(player.matrixWorld);
if( coin !== null && !('consumed' in coin.userData) ){
coinBox.copy(coin.geometry.boundingBox).applyMatrix4(coin.matrixWorld);
}