物理系统
2D物理系统
2D物理系统
2.4版本cocos中需要手动开启物理引擎(需要在onLoad方法内执行):
1 | cc.director.getPhysicsManager().enabled = true |
想要开启一个节点的物理系统,需要给这个节点添加两个组件:
- RigidBody 刚体组件
- Collider 碰撞组件
RigidBody 刚体
RigidBody
- Enabled Contact Listener
- 开启物理碰撞检测
- Bullet
- 防止高速移动的物体穿过墙面或地面等刚体
- Type
- 几种刚体类型
- static 静态刚体
- kinematic 不受外力
- Dynamic 动态刚体
- Animated 设置线速度和角速度驱动的刚体
- 几种刚体类型
- Allow Sleep
- 允许刚体静止不动时进入睡眠状态,降低CPU占用率
- Gravity Scale
- 重力倍数,1为1倍重力
- Linear Damping
- 线性速度衰减系数
- Angular Damping
- 角速度衰减系数
- Linear Velocity
- 线性初速度
- Angular Velocity
- 角初速度
- Fixed Rotation
- 禁止物体旋转
- Awake OnLoad
- 是否在初始化时唤醒此刚体
将AwakeOnLoad设置为false,
在代码中可以通过修改刚体组件的awake为true,来开启刚体:
1 | this.getComponent(cc.RigidBody).awake = true |
给刚体施加力
- 参数1:force 在x、y轴上的大小分量
- 参数2:point 作用点
- 参数3:wake 是否唤醒刚体
1
rb.applyForce(force:cc.Vec2, point:cc.Vec2, wake:boolean)
施加力到刚体的质心上
- 参数1:force 在x、y轴上的大小分量
- 参数2:wake 是否唤醒刚体
1
rb.applyForceToCenter(force:cc.Vec2, wake:boolean)
施加扭力
- 参数1:torque 扭力大小
- 参数2:wake 是否唤醒
1
rb.applyTorque(torque:number, wake:boolean)
施加冲量
- 参数1:impulse 冲量在x、y轴上的大小分量
- 参数2:point 作用点
- 参数3:wake 是否唤醒
1
rb.applyLinearImpulse(impulse:cc.Vec2, point:cc.Vec2, wake:boolean)
施加角速度冲量
- 参数1:impulse 角速度冲量大小
- 参数2:wake 是否唤醒
1
rb.applyAngularImpulse(impulse:number, wake:boolean)
力与冲量
cocos中主要有两种方式移动一个物体:
- 力 Force
- 物体本身移动的内力
- 力会随时间修改物体的坐标和旋转角度
- 添加物体内在力的API:
- applyForce
- applyForceToCenter
- applyTorque
- 冲量 Impulse
- 从外界推动物体的外力
- 冲量会立刻改变物体的坐标或旋转角度
- 冲量(如线性初速度、角初速度),会根据衰减系数而逐渐减弱,直到物体的变化完全停止
- 添加物体外力的API:
- applyLinearImpulse
- applyAngularImpulse
Collider 物理碰撞体
碰撞组件
RigidBody必须在组件上存在Collider碰撞体的情况下才能生效,
Collider碰撞组件具有以下的基础属性:
- Density 密度
- Sensor 是否是传感器类型
- 设置了传感器的碰撞物本身不会产生碰撞效果,但是可以监听到碰撞事件
- 常用场景:某个特殊点监听到玩家的碰撞之后,触发事件(场景跳转/交互效果)
- Friction 摩擦系数
- Restitution 弹性系数
- Tag
- 和collider属性一样,tag用于在碰撞回调中识别碰撞体的类型
碰撞回调
想要触发碰撞体的碰撞回调,
需要开启碰撞体RigidBody的Enabled Contact Listener属性,
碰撞回调函数中有3个参数:
- contact 碰撞信息
- self 碰撞物自己
- other 另一个碰撞物
1 | // 开始碰撞 |
关于cc.PhysicsContact类型,可以获取到以下碰撞信息:
- colliderA 碰撞体A
- colliderB 碰撞体B
- disabled 禁用
- disabledOnce 在当前时间步(dt)中忽略此接触信息
- getWorldMainfold() 获取世界坐标系下的碰撞信息
- 获取到的碰撞信息具有以下成员:
- points 碰撞点数组,常见有1-2个碰撞点
- normal 碰撞点上的法向量,由自身碰撞体指向对方碰撞体
- 获取到的碰撞信息具有以下成员:
- getMainfold() 获取局部坐标系下的碰撞信息
- getImpulse() 获取冲量信息
- 在onPostSolve回调中可以获取到,返回值包含2个参数:
- normalImpulses 向量冲量
- tangentImpulse 切线冲量
- 在onPostSolve回调中可以获取到,返回值包含2个参数:
- getFriction/setFriction/resetFriction() 获取/设置/重置摩擦力系数
- getRestitution/setRestitution/resetRestitution() 获取/设置/重置弹性系数
- isTouching() 碰撞体是否已经解除
物理检测
物理系统管理器
cocos中有3种物理检测的方法:
- 点检测
- 矩形检测
- 射线检测
点检测
检测某个指定点位是否存在碰撞体,
如果存在多个碰撞体,只会返回一个随机结果,
只能用于测试dynamic刚体
1 | let pysicsCollider = cc.director.getPhysicsManager().testPoint(point) |
矩形检测
矩形检测需要指定一个世界坐标系下的矩形,
如果一个碰撞体的包围盒与矩阵存在重叠部分,会返回该碰撞体
同样只能检测dynamic类型的碰撞体:
1 | let rect = cc.rect(0, 0, 300, 300) |
射线检测
射线检测根据指定的线段,来判断线段穿过的碰撞体,
返回线段在穿过碰撞体的法向量、点位以及其它一些信息
用法:
1 |
|
参数说明:
- p1 线段起点
- p2 线段终点
- type 射线类型,在cc.RayCastType中定义,包括以下4种
- All:检测射线路径上的所有碰撞体,检测到的结果顺序不是固定的
- AllClosest: 返回射线路径上的所有碰撞体,但是会对返回值进行筛选,只返回每个碰撞体与射线接触的第一个点
- Any:
- 官方解释:检测射线路径上任意,一旦检测到任何碰撞体,立即结束检测
- 实际使用:返回的是最远的碰撞体
- Closest:检测射线路径上最近的碰撞体,默认值
物理检测实现自动寻路
实现代码:
1 |
|