术语

  • Bodies主体:PhysicsBody持有一个对象的物理属性,包括mass(质量)、position(位置)、rotation(旋转)、velocity(速度)、damping(阻尼)。PhysicsBody对象是形状的主干部分,但它本身并没有形状,直到你附加一个形状到它身上。
  • Material材料:描述材料的属性
    density:密度,用来计算父体的质量属性。
    restitution:恢复,用于使用物体碰撞,它的取值范围是从0到1。0意味着不发生碰撞,1意味着完全碰撞。
    friction:摩擦力,用于使物体沿着彼此滑动更真实。
  • Shapes形状:描述碰撞几何。定义一个主体时可以附加形状上去。当你想定义一个很复杂的形状时,你可以附加很多形状到一个主体上。每个形状都对应一个​​PhysicsMaterial​​对象,这个对象包含以下这些属性:
    type(类型):形状分类,有circle、box、polygon等
    area(区域):用于计算主体的质量属性,通过density和area计算出质量。
    mass(质量):物质的质量。
    moment(时刻):决定期望的角加速度所需的扭矩。
    offset(偏离):在本地坐标系中,主体的重力中心的偏离量
    tag(标签):可以让开发者更容易识别形状。就是说可以给形状打标记。
  • shapes形状:有以下这些
    PhysicsShape
    PhysicsShapeCircle
    PhysicsShapePolygon
    PhysicsShapeBox
    PhysicsShapeEdgeSegment
    PhysicsShapeEdgePolygon
    PhysicsShapeEdgeBox
    PhysicsShapeEdgeChain
  • Contacts/Joints联系/连接:Contacts和Joints对象描述了主体如何附加到彼此上。
  • World世界:World世界容器就是你的物理主体要添加到的地方和它们被模拟的地方,你可添加主体bodies、shapes形状、constraint限速到world世界中,然后,可以将world作为一个整体更新。world控制着所有项之间的互相作用。与物理API的大部分交互将与PhysicsWorld对象进行。

PhysicsWorld与PhysicsBody

PhysicsWorld
PhysicsWorld对象被用来模拟现实世界。PhysicsWorld深度集成在Scene场景这个层次。
创建一个Scene场景包含一个PhysicsWorld对象,只需要调用initWithPhysics():

if( !Scene::initWithPhysics() )
{

}

每个PhysicsWorld对象都有一些属性与之关联:

  • gravity(重力): 全球重力应用到world,默认是Vec2(0.0f, -98.0f)。
  • speed(速度): 设置物理世界的速度,它是模拟执行的频率,默认是1.0。
  • updateRate(更新频率): 设置物理世界的更新频率。更新频率是EngineUpdateTimes/PhysicsWorldUpdateTimes的值。
  • substeps(子步): 在物理世界的更新设置分步数量。

更新物理世界的过程称为步进。 默认情况下,PhysicsWorld会随时间自动更新。 这叫做自动步进。可以关闭自动步进,通过调用​​setAutoStep(false)​​​。关闭了自动步进后,你就要手动设置步进,可以通过调用​​step(time)​​来完成。Substeps被用于使用比单个帧更精确的时间增量将物理世界向前推进多次。 这允许对步进过程进行更精细的控制,包括更多的流体运动。

PhysicsBody
​​​PhysicsBody​​​对象有position(位置)和velocity(速度)。你可以将forces(外力)、movement(动作)、 damping(阻尼) 、 impulses (推动)应用到​​PhysicsBody​​​对象上。
​​​PhysicsBody​​​对象可以是静态的,也可以是动态的。动态的可以被用户手动移动,而静态的则不动。Node(节点)提供了setPhysicsBody()方法用来关联一个​​PhysicsBody​​对象到节点对象上。

auto visibleSize = Director::getInstance()->getVisibleSize();
s_centre = Vec2(visibleSize.width/2, visibleSize.height/2);

auto physicsBody = PhysicsBody::createBox(Size(65.0f, 81.0f),
PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setDynamic(false);

//create a sprite
auto sprite = Sprite::create("whiteSprite.png");
sprite->setPosition(s_centre);
addChild(sprite);

//apply physicsBody to the sprite
sprite->addComponent(physicsBody);

//add five dynamic bodies
for (int i = 0; i < 5; ++i)
{
physicsBody = PhysicsBody::createBox(Size(65.0f, 81.0f),
PhysicsMaterial(0.1f, 1.0f, 0.0f));

//set the body isn't affected by the physics world's gravitational force
physicsBody->setGravityEnable(false);

//set initial velocity of physicsBody
physicsBody->setVelocity(Vec2(cocos2d::random(-500,500),
cocos2d::random(-500,500)));
physicsBody->setTag(10);

sprite = Sprite::create("blueSprite.png");
sprite->setPosition(Vec2(s_centre.x + cocos2d::random(-300,300),
s_centre.y + cocos2d::random(-300,300)));
sprite->addComponent(physicsBody);

addChild(sprite);
}