P2物理引擎 Published on Dec 3, 2020 in 前端javascript with 0 comment ## P2物理引擎 ### 形状(shape) 对于物理来说,需要把模型抽象成简单的形状,最简单是长方体,球体,四棱锥之类的 ### 刚体(body) 刚体,有重心,位置,速度和许多用于碰撞的形状。创建刚体之后我们需要给他添加形状 可以给刚体设置质量,质量为0的刚体为静态刚体 ### Material 物理材料 我们来给一个物体定义一个物理材料 ```js let body = new p2.Body() let material = new p2.Material() body.material = material ``` ### ContactMaterial 定义当两种材料相遇时会发生什么,例如摩擦系数。您还可以设置其他内容,例如恢复,表面速度和约束参数等 ```js const contactMaterail = new p2.ContactMaterial(material1, material2, { friction: 0.3, // 摩擦力 restitution: 1, // 恢复系数 stiffness: 0.5, // 硬度 relaxation: 0.5, // 张弛 surfaceVelocity: 0 // 表面速度,默认值为0,例如传送带 // 参数还有 frictionStiffness, frictionRelaxation, }) ``` 下面我们来一个栗子: ```js const bodyShape1 = new p2.Box( width: 1, height: 1, material: new p2.Material() ) const bodyShape2 = new p2.Box( width: 1, height: 1, material: new p2.Material() ) const body1 = new p2.Body({mass: 1}) const body2 = new p2.Body({mass: 0.4}) const material1 = new p2.Material() const material2 = new p2.Material() body1.material = material1 body2.material = material2 const contactMaterial = new p2.ContactMaterial(bodyShape1.material, bodyShape2.material, { stiffness: 100, friction: 0.3 }) world.addContactMaterial(contactMaterial) world.addBody(body1) world.addBody(body2) ``` ### 物理世界(world) 物理世界可以理解成模拟物理现象的一个环境 > p2的单位坐标是50像素,如果p2的坐标是(1, 0),则对应的实际坐标是(50, 0) 创建地面 ```js const ground = new p2.Body({ angle: 0, position: [0, 0] }) ground.addShape(new p2.Plane()) // …… ``` > 在屏幕中,默认情况下地面是在上面,宽度无限,下面是天空,如果要想把地面变成下面,需要旋转180度,然后修改(body)地面的位置 例如: ```js const ground = new p2.Body({ angle: Math.PI, position: [0, world.height] }) ground.addShape(new p2.Plane()) // 把地面添加到物理世界中 world.addBody(ground) ``` ### 创建物理世界 ```js const world = new p2.World({ gravity: [0, -9.8] }) ``` 这里我们创建了一个物理世界,重力是9.8,在屏幕中的方向是向上的,当把`-9.8`改成 `9.8`就是在屏幕中的方向是向下的 要想看到物理现象,我们需要激活物理世界: ```js let lastTime let maxSubSteps = 5 // Max physics ticks per render frame let fixedDeltaTime = 1 / 60 // Physics "tick" delta time function animate (time) { requestAnimationFrame(animate) // Get the elapsed time since last frame, in seconds let deltaTime = lastTime ? (time - lastTime) / 1000 : 0 lastTime = time // Make sure the time delta is not too big (can happen if user switches browser tab) deltaTime = Math.min(1 / 10, deltaTime) // Move physics bodies forward in time world.step(fixedDeltaTime, deltaTime, maxSubSteps) // Render scene // render() // …… } ``` ## 物理世界中的一些事件 当物体事件发生碰撞时,物理世界会触发一些事件 这些事件有: * beginContact * endContact * impact * postBroadphase * postStep * preSolve 本文由 tutustack 创作,采用 知识共享署名4.0 国际许可协议进行许可本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名