在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