part
导入3D引擎库
import * as CANNON from "cannon-es"
创建three.js中物体与地面
// 创建球体
const spereGeometry = new THREE.SphereGeometry(1, 20, 20)
const spereMaterial = new THREE.MeshStandardMaterial()
const sphere = new THREE.Mesh(spereGeometry, spereMaterial)
sphere.castShadow = true
scene.add(sphere)
// 创建平面
const floor = new THREE.Mesh(
new THREE.PlaneGeometry(20, 20),
new THREE.MeshStandardMaterial()
)
floor.position.set(0, -5, 0)
floor.rotation.x = -Math.PI / 2
floor.receiveShadow = true
scene.add(floor)
// 开启灯光, 添加环境光和平行光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)
const dirLight = new THREE.DirectionalLight(0xffffff, 0.5)
dirLight.castShadow = true
scene.add(dirLight)
仅仅通过three中的物体实现物理效果是无法实现的
需要借助 CANNON 创建物理世界的小球
- 需要注意:想要页面中物体具有物理世界的效果(有重力,有碰撞效果),那么就必须在物理世界再创造一个物体
- 普通小球是在:渲染引擎进行渲染,引擎只负责不断的画画,绘制出它该有的样子
- 物理世界小球是在:物理引擎就行计算其该有的物理效果,渲染引擎不断的从物理引擎中获取小球物理数据,然后进行绘制
- 设置完物理世界的物体后,记得将两个世界的小球进行关联,将真实世界小球位置坐标赋给所看到(普通小球)的小球坐标,详情下面render函数
const world = new CANNON.World() // 创建物理世界
world.gravity.set(0, -9.8, 0) // 设置世界重力,y向下为负,真实世界重力加速度为9.8NM
const sphereShape = new CANNON.Sphere(1) // 半径为1的小球形状
// 设置物体材质
const sphereWorldMaterial = new CANNON.Material()
// 创建物理世界的物体,类似于假世界的 Mesh步骤
const sphereBody = new CANNON.Body({
shape: sphereShape,
position: new CANNON.Vec3(0, 0, 0),
mass: 1, // 小球质量 (相互碰撞会有什么效果)
material: sphereWorldMaterial, // 材质
})
// 将物体添加到物理世界
world.addBody(sphereBody)
render渲染函数中对物体位置信息赋值
const render = () => {
// 更新物理引擎世界的物体
world.step(1 / 120, 0.02) // 每帧渲染120次
// 将物理世界小球位置坐标赋值给普通小球
sphere.position.copy(sphereBody.position)
controls.update()
renderer.render(scene, camera)
requestAnimationFrame(render) // 请求动画会给render传递一个时间,为当前请求动画帧执行的毫秒数
}
render()
监听物理小球碰撞事件 collide,加入碰撞音效
const hitSound = new Audio(require('../assets/audio/yes.mp3'))
function HitEvent(e) {
console.log(e);
const impactStrength = e.contact.getImpactVelocityAlongNormal() // 获取碰撞的强度
console.log(impactStrength); // 两次碰撞,第一次8.1, 第二次1.1
hitSound.play() // 碰撞时播放声音
}
sphereBody.addEventListener('collide', HitEvent) // 碰撞反弹了几下,就会执行几下
第一次碰撞力度8.8..Nm, 第二次碰撞力度1.8..Nm
- body 要碰撞的物体
- target 要被碰撞的物体
- contect 碰撞的信息,包含坐标,力度,时间等信息