アンカー ポイントを中心に回転する長方形のスプライトで構成される CCNode サブクラスがあります。オブジェクトがワールドに表示されますが、b2RevoluteJoint が正しく機能していないようです。オブジェクトは単に静的なままです。
これが私の RotatingArm クラスの外観です。
-(id) init {
if (self = [super init]) {
rect = [CCSprite spriteWithFile:@"square.png"];
[self addChild:rect z:1];
}
return self;
}
-(void) addBodyToWorld: (b2World*) world {
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(self.position.x / PTM_RATIO,self.position.y / PTM_RATIO);
bodyDef.userData = self;
bodyDef.fixedRotation = true;
self->body = world->CreateBody(&bodyDef);
b2PolygonShape shape;
shape.SetAsBox(rect.contentSize.width/PTM_RATIO/2,rect.contentSize.height/PTM_RATIO/2);
[self createFixture:&shape forBody:body];
[self addRotationJointInWorld:world];
}
- (void) addRotationJointInWorld:(b2World*)world {
CCSprite *sprite = [CCSprite spriteWithFile:@"anchor.png"];
sprite.color = ccc3(50, 250, 50);
[self addChild:sprite z:2];
b2BodyDef rotationpointdef;
rotationpointdef.type = b2_staticBody;
rotationpointdef.position.Set(0,0);
rotationpointdef.userData = sprite;
rotationpointdef.fixedRotation = TRUE;
rotationpoint = world->CreateBody(&rotationpointdef);
b2PolygonShape rotationpointbox;
rotationpointbox.SetAsBox(sprite.boundingBox.size.width / PTM_RATIO / 2.0,
sprite.boundingBox.size.height / PTM_RATIO / 2.0);
[self createFixture:&rotationpointbox forBody:rotationpoint];
b2RevoluteJointDef armJointDef;
armJointDef.Initialize(rotationpoint, body, b2Vec2(rect.boundingBox.size.width/2/PTM_RATIO/2,rect.boundingBox.size.height/2/PTM_RATIO/2));
armJointDef.enableMotor = TRUE;
armJointDef.enableLimit = NO;
armJointDef.motorSpeed = 2;
armJointDef.maxMotorTorque = 4800;
armJoint = (b2RevoluteJoint*)world->CreateJoint(&armJointDef);
}
-(void) createFixture: (b2Shape*) shape forBody:(b2Body *) thebody {
b2FixtureDef fixtureDef;
fixtureDef.shape = shape;
fixtureDef.density = 10.0f;
thebody->CreateFixture(&fixtureDef);
}
次に、メインのゲーム レイヤーで、回転する腕のオブジェクトを次のようにインスタンス化します。
RotatingArm *arm = [[[RotatingArm alloc] init] autorelease];
arm.position = ccp(screen.width/2, screen.height/2);
[self addChild:arm z:3];
[arm addBodyToWorld:_world];
メイン ゲーム レイヤーには、スプライトの位置を更新する update メソッドもあります。
-(void) update: (ccTime) dt {
world->Step(dt, 10, 10);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *)b->GetUserData();
sprite.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}