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