在cocos2d身體的錨和本地節點空間的原點,如果你給一個CCSprite的位置,它實際上意味着CCSprite的錨點的位置通常是從這個精靈的本地節點空間的原點不同(紋理的左下角),對吧? 但是,當我用Box2D中的紋理製作一個自定義多邊形並給出主體位置時,我發現它意味着該主體的局部節點空間原點(0,0)的位置,它似乎是左下角我想知道在Box2D body中是否沒有像cocos2D sprite中的錨點?身體位置是指位置體的本地座標原點嗎?如果我從紋理獲取身體的形狀(圖片),這是否意味着身體的局部座標原點是紋理的左下角? 我希望表達我的困惑顯然....困惑與Box2D的
回答
當你創建一個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));
}
}
而結果是這樣的:
您可以找到code for this entire project on github。
對您有幫助嗎?
- 1. 困惑與WMQ
- 2. 困惑與Linux的
- 3. 困惑與蟒蛇
- 4. 困惑:context.getExternalFilesDir與Environment.getExternalStorageState();
- 5. 困惑與設計
- 6. 與活動困惑
- 7. 與everyauth相關的困惑
- 8. 困惑與Get-ChildItem cmdlet的
- 9. 對IAdaptable與IActionFilters的困惑
- 10. 與Java對象困惑
- 11. 困惑與C#「使用」
- 12. 困惑與動態SQL
- 13. 與AngularJS NG選項困惑
- 14. 困惑與我在Java
- 15. 困惑與Backbone.js分頁
- 16. 我有點困惑與PHP
- 17. 與symfony2捆綁困惑
- 18. 與筆尖文件困惑
- 19. 與和困惑*和[]()在C
- 20. 困惑的SqlDataSource
- 21. 困惑的ContentType
- 22. 對SimpleMembership的困惑
- 23. 由LinkedList的困惑
- 24. 困惑的jQuery .prev()
- 25. 困惑的Tkinter bind_class
- 26. 困惑的CSS名
- 27. 困惑C++的#include
- 28. 困惑中的Bash
- 29. 困惑在Python
- 30. 困惑在Python
非常感謝,你的回答真的有幫助! – user3050371