我是three.js的新手,我正在尝试一个非常基本的射击游戏。用户应该拍一个彩色的箱子(盒子)。当他这样做时,箱子就会消失,出现另一个随机的箱子,依此类推。
if (intersects.length > 0) {
intersects[0].object.material.color.setHex(Math.random() * 0xffffff);
scene.remove(object);
create_cube();
animate();
...
着陆时,它运作非常顺利。完全没有滞后。但是我拍摄的盒子越多,游戏就越开始滞后。
我在内存分配或垃圾收集方面做错了吗?
这是一个JSfiddle:https://jsfiddle.net/k0s2nmru/
(虽然我的代码作为单独的页面工作正常,但放在JSfiddle中时它似乎不起作用)
更新
我添加了three.js附带的统计数据。即使游戏开始滞后,他们仍然每秒给予我相当不错的帧数(高达150或更多)。也许我没有以正确的方式实施它?
答案 0 :(得分:3)
乍一看,我看到了3种优化代码的方法
1)在没有必要时不要调用动画或渲染
function onDocumentMouseDown(event) {
var mouse3D = new THREE.Vector3();
var raycaster = new THREE.Raycaster();
mouse3D.normalize();
controls.getDirection(mouse3D);
raycaster.set(controls.getObject().position, mouse3D);
var intersects = raycaster.intersectObjects(objects);
if (intersects.length > 0) {
intersects[0].object.material.color.setHex(Math.random() * 0xffffff);
scene.remove(object);
create_cube();
animate(); // DON'T DO THIS
}
renderer.render(scene, camera); // DON'T DO THIS
}
渲染是在一个紧凑的循环中完成的,由requestAnimationFrame控制。不仅你不需要在循环之外调用它们,你破坏了requestAnimationFrame优化(如果你这样做)(循环的几个实例同时运行)
2)总是尝试使渲染最佳。
controls.getObject().translateX(velocity.x * delta);
controls.getObject().translateY(velocity.y * delta);
controls.getObject().translateZ(velocity.z * delta);
if (controls.getObject().position.y < 10) {
为什么不用controls.getObject()?
的结果创建一个临时变量3)重复利用你能做的一切
在yomotsu答案的行中,但有点不同:为什么不关闭已被击中的立方体的可见性,改变其颜色和位置,并使其再次可见?
答案 1 :(得分:1)
删除对象时,必须删除对象中使用的几何体材质和纹理。因为资源在渲染器中缓存。
scene.remove( mesh );
// clean up
geometry.dispose();
material.dispose();
texture.dispose();