Search code examples
iosobjective-csprite-kitskphysicsjoint

Simple pin joint in SpriteKit doesn't work as expected


I'd like to make a pendulum. Starting with an SKScene and everything defaulted, I do the following...

- (void)createSceneContents {
    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.view.bounds];

    // object 1 is the fulcrum
    SKSpriteNode *object1 = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(5, 5)];
    [self addChild:object1];
    object1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:object1.frame.size];
    object1.physicsBody.dynamic = NO;
    object1.position = self.view.center;

    // object2 is like a broomstick, which I will pin to the fulcrum
    SKSpriteNode *object2 = [SKSpriteNode spriteNodeWithColor:[UIColor greenColor] size:CGSizeMake(90, 2)];
    [self addChild:object2];
    object2.anchorPoint = CGPointMake(0.0, 0.5);
    object2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:object2.frame.size];
    object2.position = self.view.center;

    // pin the physics bodies
    SKPhysicsJointPin *pinJoint = [SKPhysicsJointPin jointWithBodyA:object1.physicsBody bodyB:object2.physicsBody anchor:object1.position];
    [self.physicsWorld addJoint:pinJoint];
}

If I don't add the pin logic, as expected the fulcrum stays in the middle of the scene and the broomstick falls to the floor, so I know the broomstick is subject to gravity. After adding the pin, I get this:

enter image description here

No motion. Why? This causes no motion either...

[object2.physicsBody applyForce:CGVectorMake(0, -5)];

I expect the broomstick to swing and oscillate because it's pinned to the fulcrum. I've seen articles about positioning the nodes first, before joints, but I've done that. Am I wrong to expect the broom to swing? How can I get it to do so?


Solution

  • Node 2 have bad defined anchorPoint, here an upload an example:

    Full code of example

    Image:

    3 Seconds running code

    Swift 3 code:

        let nodeSize = CGSize(width: 10, height: 10)
        let node = SKSpriteNode(color: .red, size: nodeSize)
        node.physicsBody = SKPhysicsBody(rectangleOf: nodeSize)
        node.physicsBody?.isDynamic = false
        self.addChild(node)
    
        let node2Size = CGSize(width: 60, height: 8)
        let node2 = SKSpriteNode(color: .green, size: node2Size)
        node2.position = CGPoint(x: 30, y: 0)
        node2.physicsBody = SKPhysicsBody(rectangleOf: node2Size)
        node2.physicsBody?.mass = 1.0
        self.addChild(node2)
    
    
        let a = SKPhysicsJointPin.joint(withBodyA: node.physicsBody! , bodyB: node2.physicsBody!, anchor: CGPoint(x: 0.0, y: 0.0))
        self.physicsWorld.add(a)
    

    Objective-C:

    SKSpriteNode *object1 = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(5, 5)];
    [self addChild:object1];
    object1.position = self.view.center;
    object1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:object1.frame.size];
    object1.physicsBody.dynamic = NO;
    
    SKSpriteNode *object2 = [SKSpriteNode spriteNodeWithColor:[UIColor greenColor] size:CGSizeMake(90, 2)];
    [self addChild:object2];
    object2.position = CGPointMake(self.view.center.x+45, self.view.center.y);
    
    object2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:object2.frame.size];
    
    SKPhysicsJointPin *pinJoint = [SKPhysicsJointPin jointWithBodyA:object1.physicsBody bodyB:object2.physicsBody anchor:self.view.center];
    [self.physicsWorld addJoint:pinJoint];