2013-12-13 80 views
1

在cocos2d身体的锚和本地节点空间的原点,如果你给一个CCSprite的位置,它实际上意味着CCSprite的锚点的位置通常是从这个精灵的本地节点空间的原点不同(纹理的左下角),对吧? 但是,当我用Box2D中的纹理制作一个自定义多边形并给出主体位置时,我发现它意味着该主体的局部节点空间原点(0,0)的位置,它似乎是左下角我想知道在Box2D body中是否没有像cocos2D sprite中的锚点?身体位置是指位置体的本地坐标原点吗?如果我从纹理获取身体的形状(图片),这是否意味着身体的局部坐标原点是纹理的左下角? 我希望表达我的困惑显然​​....困惑与Box2D的

回答

0

当你创建一个Box2D的身体,你给它的初始位置。这不是质量中心,而是所有附属于该机构的固定装置的“容器”的位置。所有的固定装置都是相对于该点连接的。

例如,在此函数中定义的主体中,我将几个多边形(正方形)连接到身体。总体效果是创建一个巨大的字母“T”。

void MainScene::CreateBody() 
{ 
    Vec2 position(0,0); 

    // Create the body. 
    b2BodyDef bodyDef; 
    bodyDef.position = position; 
    bodyDef.type = b2_dynamicBody; 
    _body = _world->CreateBody(&bodyDef); 
    assert(_body != NULL); 

    // Now attach fixtures to the body. 
    FixtureDef fixtureDef; 
    PolygonShape polyShape; 
    vector<Vec2> vertices; 

    const float32 VERT_SCALE = .5; 
    fixtureDef.shape = &polyShape; 
    fixtureDef.density = 1.0; 
    fixtureDef.friction = 1.0; 
    fixtureDef.isSensor = false; 

    // Main Box 
    vertices.clear(); 
    vertices.push_back(Vec2(1*VERT_SCALE,1*VERT_SCALE)); 
    vertices.push_back(Vec2(-1*VERT_SCALE,1*VERT_SCALE)); 
    vertices.push_back(Vec2(-1*VERT_SCALE,-1*VERT_SCALE)); 
    vertices.push_back(Vec2(1*VERT_SCALE,-1*VERT_SCALE)); 
    polyShape.Set(&vertices[0],vertices.size()); 
    _body->CreateFixture(&fixtureDef); 
    _fixturePositions.push_back(CalculateAverage(vertices)); 

    // Down one 
    vertices.clear(); 
    vertices.push_back(Vec2(1*VERT_SCALE,-1*VERT_SCALE)); 
    vertices.push_back(Vec2(-1*VERT_SCALE,-1*VERT_SCALE)); 
    vertices.push_back(Vec2(-1*VERT_SCALE,-3*VERT_SCALE)); 
    vertices.push_back(Vec2(1*VERT_SCALE,-3*VERT_SCALE)); 
    polyShape.Set(&vertices[0],vertices.size()); 
    _body->CreateFixture(&fixtureDef); 
    _fixturePositions.push_back(CalculateAverage(vertices)); 

    // Up One 
    vertices.clear(); 
    vertices.push_back(Vec2(1*VERT_SCALE,3*VERT_SCALE)); 
    vertices.push_back(Vec2(-1*VERT_SCALE,3*VERT_SCALE)); 
    vertices.push_back(Vec2(-1*VERT_SCALE,1*VERT_SCALE)); 
    vertices.push_back(Vec2(1*VERT_SCALE,1*VERT_SCALE)); 
    polyShape.Set(&vertices[0],vertices.size()); 
    _body->CreateFixture(&fixtureDef); 
    _fixturePositions.push_back(CalculateAverage(vertices)); 

    // T Left Top 
    vertices.clear(); 
    vertices.push_back(Vec2(-1*VERT_SCALE,3*VERT_SCALE)); 
    vertices.push_back(Vec2(-3*VERT_SCALE,3*VERT_SCALE)); 
    vertices.push_back(Vec2(-3*VERT_SCALE,1*VERT_SCALE)); 
    vertices.push_back(Vec2(-1*VERT_SCALE,1*VERT_SCALE)); 
    polyShape.Set(&vertices[0],vertices.size()); 
    _body->CreateFixture(&fixtureDef); 
    _fixturePositions.push_back(CalculateAverage(vertices)); 

    // T Right Top 
    vertices.clear(); 
    vertices.push_back(Vec2(3*VERT_SCALE,3*VERT_SCALE)); 
    vertices.push_back(Vec2(1*VERT_SCALE,3*VERT_SCALE)); 
    vertices.push_back(Vec2(1*VERT_SCALE,1*VERT_SCALE)); 
    vertices.push_back(Vec2(3*VERT_SCALE,1*VERT_SCALE)); 
    polyShape.Set(&vertices[0],vertices.size()); 
    _body->CreateFixture(&fixtureDef); 
    _fixturePositions.push_back(CalculateAverage(vertices)); 

    _body->SetAngularVelocity(M_PI/8); 
} 

请注意,每个多边形的顶点都是相对于身体位置的,即(0,0)。

通过锚点显示相对于其位置的精灵。相对位置在(x,y)坐标中的范围[0,1]中表示。除非有很好的理由不这样做(对于效果),我通常将锚设置为(0.5,0.5),以便精灵的x,y显示中心与精灵像素位置显示在相同的位置。 See this post for more details on this.

所以创建精灵所有这些夹具:

空隙MainScene :: CreateSprites() { 视口& VP =视口::实例(); float32 ptmRatio = vp.GetPTMRatio();

对(INT IDX = 0; IDX < _fixturePositions.size(); IDX ++){ CCSprite *精灵= CCSprite ::创建( “arrow.png”); //默认的精灵锚点是(0.5,0.5)。这个 //正在完成这一点。 sprite-> setAnchorPoint(ccp(0.5,0.5)); AdjustNodeScale(sprite,1.0,ptmRatio); AdjustNodeScale(sprite,1.0,ptmRatio); _fixtureSprites.push_back(sprite); addChild(sprite); } }

您会注意到视口的使用。将Box2D“米”空间中的位置映射到屏幕的像素空间。 You can see a post with more info on that here或通过查看我在Box2d上完成的其他帖子(此主题是常见的)。你需要用你希望它是(米)和像素计量比(PTM比)的物理尺寸缩放精灵大小:

static void AdjustNodeScale(CCNode* node, float32 entitySizeMeters, float32 ptmRatio) 
{ 
    CCSize nodeSize = node->getContentSize(); 
    float32 maxSizePixels = max(nodeSize.width,nodeSize.height); 
    assert(maxSizePixels >= 1.0); 
    float32 scale = (entitySizeMeters*ptmRatio/maxSizePixels); 

    node->setScale(scale); 
} 

如果你只是有一个精灵,你可以使自己的立场与身体中心的位置重合并放置在顶部。如果您有多个精灵,你必须把和旋转每一个:

void MainScene::UpdateSprites() 
{ 
    for(int idx = 0; idx < _fixturePositions.size(); idx++) 
    { 
     CCPoint spritePosition = Viewport::Instance().Convert(_body->GetWorldPoint(_fixturePositions[idx])); 
     _fixtureSprites[idx]->setPosition(spritePosition); 
     float32 bodyAngle = _body->GetAngle(); 
     bodyAngle = MathUtilities::AdjustAngle(bodyAngle); 
     _fixtureSprites[idx]->setRotation(-CC_RADIANS_TO_DEGREES(bodyAngle)); 
    } 
} 

而结果是这样的:

enter image description here

您可以找到code for this entire project on github

对您有帮助吗?

+0

非常感谢,你的回答真的有帮助! – user3050371