Анимация тела?
Я использую Box2D с Cocos2D в моей игре. Мне известно, что у Cocos2D есть API анимации с именем CCMoveTo. Я хочу сделать то же самое в Box2D с b2Bodies. Я хочу иметь возможность установить точку назначения и время анимации с точки, в которой она изначально находится. Кто-нибудь знает, возможно ли это или нет? Я просто стараюсь сделать это как можно проще.
Я открыт для идей и предложений!
Спасибо!
Edit1: Хорошо, поэтому я хочу, чтобы мои b2Bodys постоянно следили за моим CCSprite. Существует проблема с кодом, который вы мне показали.
В моем.h я делаю это:
b2World *world;
b2Body *body;
Затем я немного изменил метод, и теперь он выглядит так:
for (body = world->GetBodyList(); body != nil; body = body->GetNext())
{
CCSprite *bodyNode = body->GetUserData();
if (bodyNode != nil)
{
// this transfers the body's position and rotation to the sprite
bodyNode.position = [Helper toPixels:body->GetPosition()];
float angle = body->GetAngle();
bodyNode.rotation = -(CC_RADIANS_TO_DEGREES(angle));
// and this would do the exact opposite
b2Vec2 pos = [Helper toMeters:bodyNode.position];
body->SetTransform(pos, CC_DEGREES_TO_RADIANS(bodyNode.rotation));
body->SetLinearVelocity(b2Vec2(0.0f, 0.0f));
body->SetAngularVelocity(0.0f);
}
}
Поэтому я использовал ivars вместо переменной instance. Это нормально? Также я получаю 2 ошибки:
Я получаю переменную Cannot Initialize типа 'CCSprite' со значением типа 'void' в строке body->GetUserData
Я также получаю: Использование необъявленного идентификатора "Помощник". Я поместил эти 2 вспомогательных метода в свой класс, но я просто не уверен, что такое Помощник.
Edit2: как это выглядит? Я решил оставить методы в своем классе, а не создавать новый специально для него.
// for each body, get its assigned BodyNode and update the sprite's position
for (body = world->GetBodyList(); body != nil; body = body->GetNext())
{
CCSprite* sprite = (CCSprite*)body->GetUserData();
if (sprite != nil)
{
// this transfers the body's position and rotation to the sprite
sprite.position = [self toPixels:body->GetPosition()];
float angle = body->GetAngle();
sprite.rotation = -(CC_RADIANS_TO_DEGREES(angle));
// and this would do the exact opposite
b2Vec2 pos = [self toMeters:sprite.position];
body->SetTransform(pos, CC_DEGREES_TO_RADIANS(sprite.rotation));
body->SetLinearVelocity(b2Vec2(0.0f, 0.0f));
body->SetAngularVelocity(0.0f);
}
}
}
// convenience method to convert a CGPoint to a b2Vec2
-(b2Vec2)toMeters:(CGPoint)point
{
return b2Vec2(point.x / CTM_RATIO, point.y / CTM_RATIO);
}
// convenience method to convert a b2Vec2 to a CGPoint
-(CGPoint)toPixels:(b2Vec2)vec
{
return ccpMult(CGPointMake(vec.x, vec.y), CTM_RATIO);
}
1 ответ
Вы можете полностью изменить отношения CCSprite и b2Body, временно или постоянно. Обычно в вашем методе обновления CCSprite будет установлен на позицию b2Body. Если у вас есть CCSprite, который использует CCMoveTo для перемещения в определенную позицию, вы можете вместо этого назначить b2Body позицию и вращение спрайта.
Все, что вам нужно сделать, это определить, когда и каким спрайтом управлять телом:
// for each body, get its assigned BodyNode and update the sprite's position
for (b2Body* body = world->GetBodyList(); body != nil; body = body->GetNext())
{
BodyNode* bodyNode = body->GetUserData();
if (bodyNode != nil)
{
// this transfers the body's position and rotation to the sprite
bodyNode.position = [Helper toPixels:body->GetPosition()];
float angle = body->GetAngle();
bodyNode.rotation = -(CC_RADIANS_TO_DEGREES(angle));
// and this would do the exact opposite
b2Vec2 pos = [Helper toMeters:bodyNode.position];
body->SetTransform(pos, CC_DEGREES_TO_RADIANS(bodyNode.rotation));
body->SetLinearVelocity(b2Vec2(0.0f, 0.0f));
body->SetAngularVelocity(0.0f);
}
}
Методы Helper определяются следующим образом:
// convenience method to convert a CGPoint to a b2Vec2
+(b2Vec2) toMeters:(CGPoint)point
{
return b2Vec2(point.x / PTM_RATIO, point.y / PTM_RATIO);
}
// convenience method to convert a b2Vec2 to a CGPoint
+(CGPoint) toPixels:(b2Vec2)vec
{
return ccpMult(CGPointMake(vec.x, vec.y), PTM_RATIO);
}