0

I just want to create two circles with the same axis, and make one being controlled by touch events. In java, I just had to create two bodies and one RevoluteJoint and that was it. I am new to iOS development (so I only learnt Swift) and I would like to do the same using SpriteKit

I wrote this, but it seems like I need to manage the touch event myself. Isn't there a 'grabbable body' option so I don't have to make all the calculations by myself to make the wheel follow the user fingers, but just in rotation.

override func didMoveToView(view: SKView) {

    /* Setup your scene here */
    inner=SKSpriteNode(imageNamed:"inner")
    outer=SKSpriteNode(imageNamed:"outer")

    inner.physicsBody=SKPhysicsBody(circleOfRadius: inner.frame.size.width/2)
    inner.physicsBody!.dynamic=true
    inner.physicsBody!.allowsRotation=true

    outer.physicsBody=SKPhysicsBody(circleOfRadius: outer.frame.size.width/2)

    physicsWorld.gravity=CGVectorMake(0, 0)

    addChild(inner)
    addChild(outer)

    var joint1=SKPhysicsJointPin.jointWithBodyA(inner.physicsBody, bodyB: outer.physicsBody, anchor: CGPoint(x: 0, y: 0))

    physicsWorld.addJoint(joint1)
}
Myoch
  • 793
  • 1
  • 6
  • 24
  • I think this [tutorial](http://www.raywenderlich.com/80586/make-line-drawing-game-sprite-kit-swift) might help you. – Jurik May 29 '15 at 11:04
  • Well, if I am going that way, this website has amazing tutorials for LiquidFun, which is an extension of Box2D. I just thought SpriteKit could try to compete with Box2D, but I guess I was wrong. – Myoch May 29 '15 at 15:50
  • Not really, because SpriteKit has a few 'bugs' that are (especially if you need good physics) really annoying. Take a look at [this question](http://stackoverflow.com/questions/27671391/spritekit-physics-in-swift-ball-slides-against-wall-instead-of-reflecting/) – Jurik May 30 '15 at 12:29

1 Answers1

0

I ended up creating a pseudo MouseJoint as follows:

in the didMoveToView, I initialize a very heavy ball that does not interact with any other body:

    target=SKShapeNode(circleOfRadius: 10.0);
    target.fillColor=UIColor.clearColor();
    target.strokeColor=UIColor.clearColor();
    target.name="target";

    target.physicsBody=SKPhysicsBody(circleOfRadius: 10.0);
    target.physicsBody!.dynamic=true;
    target.physicsBody!.collisionBitMask=0;
    target.physicsBody!.contactTestBitMask=0;
    target.physicsBody!.density=20000.0;

and then I listen to mouse events as follows

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    let touch=touches.first as! UITouch
    let location=touch.locationInNode(self)
    let prev_location=touch.previousLocationInNode(self)
    let node=self.nodeAtPoint(location);

    addChild(target);

    target.position=location;
    target.zPosition=node.zPosition+1;

    mouseJoint=SKPhysicsJointSpring.jointWithBodyA(target.physicsBody!, bodyB: node.physicsBody!, anchorA: location, anchorB: prev_location)


    physicsWorld.addJoint(mouseJoint);
}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {


    let touch=touches.first as! UITouch
    let location=touch.locationInNode(self)

    target.position.x=location.x;
    target.position.y=location.y;



    }

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {

    mouseJoint.bodyB.velocity=CGVector(dx:0, dy:0);
    mouseJoint.bodyB.angularVelocity=0;
    physicsWorld.removeJoint(mouseJoint);
        target.removeFromParent();

}

Since my other bodies are pinned, rotation is the only possible motion.

As there is no "resting length" of a spring joint in SpriteKit, it seems crucial to have a ball much heavier than the body you're trying to rotate, as otherwise, the equilibrium point won't be the final touch location.

Myoch
  • 793
  • 1
  • 6
  • 24