2013-12-13 75 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