Box2D:无法让b2RevoluteJoint正常工作

时间:2012-03-26 16:51:11

标签: iphone objective-c box2d

我正在尝试使用b2Box模拟与铰链连接的两个物体(我使用b2RevoluteJoint)的行为。这是两个对象在一开始的相对(重叠)位置。

它们都有一个红点(它们位于相同的全局坐标处)。我希望较长的物体围绕这个点旋转。这是代码(anchorView是小方块,rotorView是长棍子):

- (void)viewDidLoad {
    [super viewDidLoad];

    UIView *anchorView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 30, 30)];
    anchorView.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.2];
    UIView *anchorDot = [[UIView alloc] initWithFrame:CGRectMake(13, 13, 4, 4)];
    anchorDot.backgroundColor = [UIColor redColor];
    [self.view addSubview:anchorView];
    [anchorView addSubview:anchorDot];

    UIView *rotorView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 300, 30)];
    rotorView.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.2];
    UIView *rotorDot = [[UIView alloc] initWithFrame:CGRectMake(13, 13, 4, 4)];
    rotorDot.backgroundColor = [UIColor redColor];
    [self.view addSubview:rotorView];
    [rotorView addSubview:rotorDot];

    b2Vec2 gravity; gravity.Set(0.0f, -9.81f);

    world = new b2World(gravity);    
    world->SetContinuousPhysics(true);

    // Static anchor
    b2BodyDef anchor;
    anchor.position.Set(anchorView.center.x / PTM, (1004.0 - anchorView.center.y) / PTM);
    anchor.type = b2_staticBody;    
    b2Body* anchorBody = world->CreateBody(&anchor);

    b2PolygonShape anchorBox;
    anchorBox.SetAsBox(anchorView.frame.size.width / PTM / 2.0, anchorView.frame.size.height / PTM / 2.0);
    anchorBody->CreateFixture(&anchorBox, 0.0);

    // Dynamic rotor
    b2BodyDef rotor;
    rotor.position.Set(rotorView.center.x / PTM, (1004.0 - rotorView.center.y) / PTM);
    rotor.type = b2_dynamicBody;
    b2Body *rotorBody = world->CreateBody(&rotor);

    b2PolygonShape rotorBox;
    rotorBox.SetAsBox(rotorView.frame.size.width / PTM / 2.0, rotorView.frame.size.height / PTM / 2.0);
    rotorBody->CreateFixture(&rotorBox, 0.0);

    rotorView.tag = (int)rotorBody;

    // Joint
    b2RevoluteJointDef jointDef;
    jointDef.Initialize(anchorBody, rotorBody, anchorBody->GetWorldCenter());
    world->CreateJoint(&jointDef);

    // doing stuff
    rotorBody->SetAngularVelocity(5.0);

    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(onTimer:) userInfo:rotorView repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];            
}

- (void)onTimer:(NSTimer *)theTimer {
    int32 velocityIterations = 8;
    int32 positionIterations = 1;

    UIView *rotorView = [theTimer userInfo];
    b2Body *rotorBody = (b2Body *)rotorView.tag;

    world->Step(0.3f / 60.0f, velocityIterations, positionIterations);

    CGFloat angle = rotorBody->GetAngle();
    b2Vec2 c = rotorBody->GetWorldCenter();

    rotorView.center = CGPointMake(c.x * PTM, 1004.0 - c.y * PTM);

    CGAffineTransform rt = CGAffineTransformMakeRotation(angle);
    rotorView.transform = rt;
}

开始这之后,我得到了一种不同类型的动作。这是它的样子(为了澄清,我添加了几个笔画):

更确切地说,红点不是绑在一起,但是身体中心之间的距离总是保持不变,好像有一根绳子在我画了虚线。

如果我查看调试器中的jointDef.localAnchorB,它包含长棒坐标系中红点的右坐标。我做错了什么?

1 个答案:

答案 0 :(得分:0)

解决。这一切都与这两条线有关:

CGFloat angle = rotorBody->GetAngle();

CGAffineTransform rt = CGAffineTransformMakeRotation(angle);

Box2D和Cocoa Touch使用不同的方向来计算旋转角度,因此它必须是:

CGAffineTransform rt = CGAffineTransformMakeRotation(-angle);