首页 > 移动开发 > 其他综合 > 正文
7.14.3 创建精灵刚体
2015-11-25 13:31:19     我来说两句      
收藏    我要投稿

在已经完成了物理世界的创建之后,接下来的工作就是创建世界中物体。Box2DTest项目提供了一种精灵与刚体的混合对象。细心的读者应该能够想到这是一种将Cocos2D-X引擎与Box2D引擎融合的方式。这样游戏当中的一个对象,就具备了两个引擎中元素的共同属性。

精灵刚体就是类PhysicsSprite。它是Cocos2D-X引擎中类Sprite的派生,同时持有了一个Box2D引擎中Body的指针。从其头文件中,读者就能够看出它是一个混血儿。

//精灵刚体
class PhysicsSprite : public Sprite
{
public:
//构造函数
    PhysicsSprite();
//设置刚体对象
    void setPhysicsBody(b2Body * body);
    virtual bool isDirty(void);
    virtual AffineTransform  nodeToParentTransform(void);
private:
//刚体对象的指针
    b2Body* m_pBody;    // strong ref
};

在Box2DTest项目中,只存在精灵刚体。之前在创建物理世界的时候,同时创建了一个外框。因此接下来的代码,就是创建位于框里的刚体。

代码7-17  添加精灵刚体的函数

void Box2DTestLayer::addNewSpriteAtPosition(Vec2 p)
{
   //输出添加精灵刚体的位置
    CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
    Node* parent = getChildByTag(kTagParentNode);
   
    //随机选择精灵所用的纹理
    int idx = (CCRANDOM_0_1() > .5 ? 0:1);
    int idy = (CCRANDOM_0_1() > .5 ? 0:1);
    //创建一个新的精灵刚体对象
    PhysicsSprite *sprite = new PhysicsSprite();
    //初始化纹理图片
    sprite->initWithTexture(m_pSpriteTexture, RectMake(32 * idx,32 * idy,32,32));
    sprite->autorelease();
    //将精灵刚体添加至绘制引擎中
    parent->addChild(sprite);
    //设置精灵刚体的位置
    sprite->setPosition( Vec2Make( p.x, p.y) );
   
    //定义动态物体
    //物体采用矩形的形状
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
    //创建物体
    b2Body *body = world->CreateBody(&bodyDef);
   
    //定义矩形外形
    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m box
   
    //定义动态物体的框架
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;   
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.3f;
    //创建框架
    body->CreateFixture(&fixtureDef);
    //将物体传递给精灵刚体
    sprite->setPhysicsBody(body);
}

通过上述代码7-17的功能,就可以将一个精灵刚体添加到两个世界当中。这只是一个简单的示例。无论是渲染引擎中的精灵对象,还是物理引擎中的物体对象,都是十分简单的。读者需要掌握的是其原理,在实际游戏制作过程中,学会应用此技术。在具备了创建精灵刚体的功能后,就还剩下最后一部分内容,那就是应该如何来同步两个世界的运转。这是一个普遍的问题。只要想在游戏中使用物理引擎的开发者都会遇到。每个人都会有自己的答案。而下面的代码7-18只是给出了其中的一种。

代码7-18  同步两个世界的数据

// 引擎绘制时,将会自动调用。返回值为精灵的位置以及角度变换矩阵
AffineTransform  PhysicsSprite::nodeToParentTransform(void)
{
    //获得物理世界中刚体的坐标
    b2Vec2 pos  = m_pBody->GetPosition();
    //将物理世界坐标转化为绘制世界的坐标
    float x = pos.x * PTM_RATIO;
    float y = pos.y * PTM_RATIO;
    //计算由于锚点带来的差异
    if ( isIgnoreAnchorPointForPosition() ) {
        x += m_tAnchorPointInPoints.x;
        y += m_tAnchorPointInPoints.y;
    }
 
    //获得物体的角度
    float radians = m_pBody->GetAngle();
    float c = cosf(radians);
    float s = sinf(radians);

    if( ! m_tAnchorPointInPoints.equals(Vec2(0,0) ){
        x += c*-m_tAnchorPointInPoints.x + -s*-m_tAnchorPointInPoints.y;
        y += s*-m_tAnchorPointInPoints.x + c*-m_tAnchorPointInPoints.y;
    }

    // 创建转换矩阵
    m_tTransform = AffineTransform Make( c,  s,
        -s,    c,
        x,    y );

    return m_tTransform;
}

上述的代码将会完成物理世界与绘制世界间的信息同步。其实,两个世界同步的信息主要就是物体与精灵之间的交互。而交互的内容就是位置和角度。图7-25就是Box2DTest项目的运行画面。图中那些A、B、C、D的盒子,就是精灵刚体对象。读者可以在空白处点击,就会创建新的精灵刚体对象。


 

点击复制链接 与好友分享!回本站首页
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:7.14.2 调试绘图DebugDraw
下一篇:7.15 本章小结
相关文章
图文推荐
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站