参考:http://www.wukai.me/2015/12/28/threejs-collision/
1:
创建Raycaster, 设置摄像机。
this.rayCaster = new THREE.Raycaster();
this.rayCaster.camera = camera;
2:
this.spaceShip 是玩家操作的类,我创建了一个专门用于检测碰撞的THREE.BoxGeometry
this.stoneList 是 需要被检测碰撞的物体 从屏幕里向外飞出,通过 new THREE.Sprite(new THREE.SpriteMaterial({ map: texture })); 创建
下面是检测碰撞的逻辑, 在update中每帧进行调用 private isCollision () { if(this.spaceShip && this.stoneList.length) { // 获取到用于检测碰撞的BoxGeometry的geometry; let geometry = this.spaceShip.crashGeometry; // 获取当前操作物体的坐标作为原点 let originPoint = this.spaceShip.position.clone(); // 遍历Geometry上每个顶点,用射线对其进行碰撞检测 // @ts-ignore for (let vertexIndex = 0; vertexIndex < geometry.vertices.length; vertexIndex++) { // 顶点原始坐标 // @ts-ignore let localVertex = geometry.vertices[vertexIndex].clone(); // 顶点经过变换后的坐标 let globalVertex = localVertex.applyMatrix4(this.spaceShip.matrix); let directionVector = globalVertex.sub(this.spaceShip.position); this.rayCaster.set(originPoint, directionVector.clone().normalize()) let collisionResults = this.rayCaster.intersectObjects(this.stoneList); if (collisionResults.length > 0) { let dis = collisionResults[0].distance; let length = directionVector.length(); // 发生碰撞 if(dis < length) { // @ts-ignore let gameObjectId = collisionResults[0].object.parent.gameObjectID; this.removeStone(gameObjectId); let chance = UserData.i.chance - 1; if(chance < 0) { CommandManager.i.pushCommandInfo({ cmdName: CommandName.ReplaceSceneCmd, isUpgrade: false }) } else { UserData.i.chance--; } break; } } } } }