参考: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;
}
}
}
}
}