官方文档,开发者指南12章

开发者指南的作者是国外的slackmoehrle,中文官网上的翻译很好,但缺少10,11,12。10和11是原作者没编辑好,在此翻译下12章。原文链接:https://github.com/chukong/programmers-guide/blob/v3.3/chapters/12.md

第十二章:物理效果
你的游戏一路下来变得很不错。游戏里有精灵,相关游戏机制,你在编辑代码上已经有了提升。你开始觉得你的游戏可以玩了。当你意识到你的游戏还需要模仿真实世界时你要做什么?对的,碰撞检测,重力,弹性和摩擦。这一章讲的就是物理效果的实现以及怎么使用一个物理引擎。我会解释什么时候,什么地方以及为什么使用物理引擎。

物理很麻烦,我真的需要吗?
有时你的需求很简单不至于使用物理引擎。也许通过使用节点,update(),方框以及containsPoint()或intersectsRect()这些函数就足够了。例如:

void update(float dt)
{
  auto p = touch->getLocation();
  auto rect = this->getBoundingBox();

  if(rect.containsPoint(p))
  {
      // do something, intersection
  }
}

这种机制能满足很简单的需求,又并不复杂到吓人。但当你有100个精灵都在更新检查和其他物件的互动呢?这仍可以实现但CPU以及帧效率将会大大降低。以至于你的游戏无法正常运行。一个物理引擎可以为我们解决这些问题而且扩展性更好。这样说也许不太清晰,让我们看一个简单的例子,分析以及模仿它。理论和实践会使我们很好掌握这一章。

// create a static PhysicsBody
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(Vec2(400, 400));

// sprite will use physicsBody
sprite->setPhysicsBody(physicsBody);

//add contact event listener
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(onContactBegin, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

尽管这个例子实现的东西很简单,但代码看上去挺复杂的。如果我们再仔细分析它实际上只有几个步骤:
创建一个物理物件。
创建一个精灵。
精灵设置属性,和物理物件绑定。
创建一个监听器来回应开始接触事件。
当我们一步一步看代码时,它们会变得很容易理解。为了更好地理解物理引擎的所有细节,你需要知道下面的术语和概念。
物理上的术语和概念
翻译未完待续

物理术语和概念

Bodies
PhysicsBody持有物件的物理属性。这些属性包括质量,位置,旋转角度,速度以及阻尼(比较高级的物理概念可以理解为阻碍物体运动的程度)。PhysicBody对象是形状的骨干。PhysicBody没有形状除非你给它绑定形状。

Material
Materials描述材质属性
-density(密度):参与计算质量
-friction(摩擦):使物体之间的滑动更逼真
-restitution(弹性):物体弹跳的属性。这个属性的值通常设置在0和1之间。0代表不弹,1代表完全弹性。(完全弹性就是反弹时没有能量损失)

Shapes
Shapes(形状)描述碰撞的几何属性。通过绑定形状到Bodies来定义一个物体的形状。你可以绑定很多shape到一个body来定义具有复杂形状的物体。每个形状和PhysicsMaterial对象有关而且包含以下属性:type(种类),area(面积),mass(质量),moment(转矩),offset(偏移/重心),tag(标志)。其中的一些属性你可能不太熟悉。
-type:描述形状种类,如圆形,方形,多边形。
-area:参与计算质量,密度和面积得出质量。
-mass:body重要的属性,给出一个力或在一个重力场中计算出加速度。
-moment:决定了物体转动一个角度需要多少力矩。
-offset:物体重力分布的中心以物体自身坐标系为准。
-tag:开发者能利用它容易识别形状。你也许记得你能标记所有的节点对象来更容易地识别和获取它们。
翻译未完待续

引擎中默认提供以下的形状:
-PhysicsShape: 实现了PhysicsShape base 类.
-PhysicsShapeCircle: 实心圆,没有创建空心圆的方法
-PhysicsShapePolygon: 实心凸多边形
-PhysicsShapeBox: 方形是实心凸多边形的一种
-PhysicsShapeEdgeSegment: 一条线段
-PhysicsShapeEdgePolygon:空心多边形,空心多边形由多个线段组成
-PhysicsShapeEdgeBox:空心方形,空心方形由四条线段组成
-PhysicsShapeEdgeChain: 链状。这是一种连接多条边的有效方法。

Contacts/Joints(连接/关节)
连接对象和关节对象描述了物体如何相互连接

World(世界)
世界是个容器,你所有的物理对象被添加到世界中,物理对象在世界中仿真。你添加bodies,shapes和constranints到世界中然后以世界为整体统一更新。世界控制着这些东西如何影响彼此。大部分物理操作的接口都需要一个世界对象。
到此为止已经有很多需要记的东西,手头上留着这些术语,当需要时可以回来看看。