2016-01-09 6 views
2

Я использую Box2D, чтобы создать простую игру, и я хотел бы, чтобы добиться чего-то вроде этого:Box2D изменение угла круг сталкивается без перемещения круга

У меня есть круг с «стрелкой», указывающий на это текущий угол. При нажатии на клавиатуру угол увеличит значение, и угол круга изменится, как видно на втором рисунке ниже. Initial Circle, where angle of the Circle = 0

Начальное состояние круга, где угол окружности = 0. Линия указывает на 0 градусов.

Final Circle, where angle of the Circle = 15

Это следующее состояние круга после клавиатуры мыши от пользователя. Угол круга теперь составляет 15 градусов.

Чтобы сделать преобразование, я сделал что-то вроде этого:

void MyCirclecle::turnBall(float angle) 
{ 
    body_->SetTransform(body_->GetWorldPoint(b2Vec2(0,0)), body_->GetAngle() + (angle * b2_pi/180)); 
} 

Круг вращается в правильном направлении, но круг движется одновременно. При каждом щелчке он будет двигаться немного вверх или вправо, а после 180 градусов он слегка сдвинется вниз или влево. В конце концов, после 360 градусов, он будет немного помещен поверх исходного состояния. Я также попытался использовать body_->GetWorldCenter() и body_->GetPosition() для первого параметра SetTransform, но я все равно получаю то же самое. Есть ли способ, который я мог бы сделать, чтобы не перемещать круг, но может изменить угол, с которым он сталкивается?

+0

Я думаю, проблема в том, что центр вашей сложной формы не является центром круга, а скорее центром формы, определяемой как по кругу, так и по линии. Попробуйте рисовать маркер в центре сложной формы. Вы пытались использовать револьверный сустав? –

ответ

0

Изменение угла окружности при относительном положении тела b2Vec2(0, 0) без линейного перемещения она осуществляется с MyCircle::turnBall методом реализован как:

void MyCirclecle::turnBall(float angle) 
{ 
    body_->SetTransform(body_->GetPosition(), body_->GetAngle() + (angle * b2_pi/180)); 
} 

То, что вы видите круг линейного перемещения, как вы однако предполагает, что круг не находится в относительном положении тела b2Vec2(0, 0). Где-то каким-то образом положение вашего круга изменилось от происхождения тела.

По меньшей мере, в Box2D 2.3.2, конструктор формы b2CircleShape задает переменную-член m_p (через m_p.SetZero();), так что она находится в начале тела. Поэтому я подозреваю, что либо ваш код явно меняет значение m_p, либо имеет некоторое повреждение памяти (это меняет его для вас).

OTOH, если то, что вы действительно хотите, является способом поворота круга по его относительному смещению (независимо от того, что может быть) из его тела (так что перемещение тела, пока круг только вращается), вам понадобится метод MyCircle::turnBall еще вот так:

void MyCirclecle::turnBall(float rotate_amount) 
{ 
    const float rotate_amount_in_rads = rotate_amount * b2_pi/180; 
    const float c = cos(rotate_amount_in_rads); 
    const float s = sin(rotate_amount_in_rads); 

    const b2Vec2 pivot_point = body_->GetWorldPoint(circle_shape_.m_p); 
    const b2Transform xfm = body_->GetTransform(); 
    const b2Vec2 p = xfm.p - pivot_point; 
    const float x = p.x * c - p.y * s; 
    const float y = p.x * s + p.y * c; 

    const b2Vec2 pos = b2Vec2(x, y) + pivot_point; 
    const float angle = xfm.q.GetAngle() + rotate_amount_in_rads; 
    body_->SetTransform(pos, angle); 
}