August
August

Reputation: 708

SpriteKit - Draw dynamic line between Joints

I am trying to programmatically build a pendulum using iOS SpriteKit using the built in physics.

Currently, I have the pendulum pivot, a weight, and a limited joint that allows the weight to swing... But, I have no idea on how to code a line (rod) between the pivot and weight.

I assume that drawing a line with SKShapeNode would be a start...?

-(void)setupPendulum
{
    pivot = [SKSpriteNode spriteNodeWithImageNamed:@"pivot.png"];
    pivot.position = CGPointMake(self.size.width / 2, self.size.height / 2);
    pivot.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:1.0];
    pivot.physicsBody.dynamic = NO;
    pivot.physicsBody.affectedByGravity = NO;
    pivot.xScale = 0.25;
    pivot.yScale = 0.25;
    [self addChild:pivot];

    weight = [SKSpriteNode spriteNodeWithImageNamed:@"weight.png"];
    weight.position = CGPointMake(150, 512);
    weight.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:100.0];
    weight.physicsBody.dynamic = YES;
    weight.physicsBody.affectedByGravity = YES;
    weight.physicsBody.mass = 0.5;
    weight.xScale = 0.75;
    weight.yScale = 0.75;
    [self addChild:weight];

    SKPhysicsBody *ab = pivot.physicsBody;
    SKPhysicsBody *bb = weight.physicsBody;
    CGPoint ap = pivot.position;
    CGPoint bp = weight.position;
    SKPhysicsJointLimit *joints = [SKPhysicsJointLimit jointWithBodyA:ab
                                                                bodyB:bb
                                                              anchorA:ap
                                                              anchorB:bp];
    [self.physicsWorld addJoint:joints];
}

Upvotes: 2

Views: 2096

Answers (2)

HeliNinja
HeliNinja

Reputation: 381

My project required the SKPhysicsJointLimit instead of the pin so after a lot of trial and error I found the following solution. The line is removed and drawn in didSimulatePhysics. The line connects the "satelliteShip" as it orbits around the "motherShip". I'm new to all this so I appreciate any feedback on this approach.

Setup variable first:

SKShapeNode *_lineNode;

Now draw the line in didSimulatePhysics:

- (void)didSimulatePhysics {
    if (_lineNode){
        [_lineNode removeFromParent];
    }
    SKNode *satelliteShip = [self childNodeWithName:kSatelliteShipName];
    CGMutablePathRef pathToDraw;
    pathToDraw = CGPathCreateMutable();
    CGPathMoveToPoint(pathToDraw, NULL, motherShip.position.x, motherShip.position.y);
    CGPathAddLineToPoint(pathToDraw, NULL, satelliteShip.position.x, satelliteShip.position.y);
    CGPathCloseSubpath(pathToDraw);

    _lineNode = [SKShapeNode node];
    _lineNode.path = pathToDraw;
    CGPathRelease(pathToDraw);
    _lineNode.strokeColor = [SKColor grayColor];
    [self addChild:_lineNode];
}

Upvotes: 5

August
August

Reputation: 708

The correct direction was to look at SKPhysicsJointPin, which can use a SKShapeNode or SKSpriteNode (etc.).

https://developer.apple.com/library/iOS/documentation/SpriteKit/Reference/SKPhysicsJointPin_Ref/Reference/Reference.html

Note About my question and the comments on it:

Since there isn't very much documentation (now) on SpriteKit beyond the (small book sized) reference by Apple and a grip of single-class-app examples/tutorials online -- most peoples responses are to, "just look it up + Cocos2d in google" and just re-do that. That's nice en all, but I'm not a copy-paste kinda of person. I like to learn the best way which is sustainable and reusable. This is why I asked what the best way to do it vs. posting busted Cocos2d ported copy-paste code and letting someone fill in the blanks like I see happen too often.

Upvotes: 1

Related Questions