Steve
Steve

Reputation: 4975

Adding a gravitational field about SpriteNode

I have a game with a character who is affected by normal gravity as he jumps across platforms. He collects coins and power ups. I'm making a power up that makes coins gravitate to the characterSpriteNode.

In the case that magneticPowerUp = true I want it to appear that a gravitational field has activated about the character that makes only the coins attract to the character, like a magnetic field.

I've been fideling with Epic Bytes SO answer here but i'm not having much luck as i don't have much experience with vectors and haven't got too deep into physicsBody.

So I just can't work out the part that will make the coins move once it has decided the coin is close enough to move to the char.

My thoughts are something like this:

override func update(currentTime: NSTimeInterval) {

        if magneticPowerUp {

            for coin in scoreNode.children {

                let disp = CGVector(dx: coin.position.x-character.position.x, dy: coin.position.y-character.position.y)
                let radius = sqrt(disp.dx*disp.dx+disp.dy*disp.dy) // Distance between character and coin

                if radius < character.frame.height * 3 {

                     // Use physics methods here to push the coin to the character
                    let dt: CGFloat = 1.0/60.0
                    let strength: CGFloat = 10000

                    let m1 = character.physicsBody!.mass*strength
                    let m2 = coin.physicsBody!.mass*strength

                    let force = (m1*m2)/(radius*radius);
                    let normal = CGVector(dx: disp.dx/radius, dy: disp.dy/radius)
                    let impulse = CGVector(dx: normal.dx*force*dt, dy: normal.dy*force*dt)

                    // Something wrong with this?
                    coin.physicsBody!.velocity = CGVector(dx: coin.physicsBody!.velocity.dx + impulse.dx, dy: coin.physicsBody!.velocity.dy + impulse.dy)



                }
            }
        }
    }

Upvotes: 0

Views: 510

Answers (1)

Edison
Edison

Reputation: 11987

SpriteKit has SKFieldNode for creating gravity and magnets that apply to bodies. Normally it deflects charged bodies instead of attracting them like ferromagnetism in the real world.

If you want a field that attracts things you'll need a radialGravityField() method around your hero. To attract specific things like your coins you would use categoryBitMask on the hero field and fieldBitMask on the coin sprites you want to attract.

With the electricField() method you could also have your hero attract different bodies with stronger or weaker forces. Or even attract and repel different bodies at the same time. You can use the charge property of physics bodies.

Code examples:

        var field:SKFieldNode?

        switch( name )
        {
        case .Electric:
            var electric = SKFieldNode.electricField()
            electric.strength = 100.0
            bestBodyMass = 0.5
            impulseMultiplier = 400
            field = electric
        case .Magnetic:
            var magnetic = SKFieldNode.magneticField()
            magnetic.strength = 1.0
            bestBodyMass = 0.5
            impulseMultiplier = 400
            field = magnetic
         }

The Apple documentation for SKFieldNode is awesome. https://developer.apple.com/reference/spritekit/skfieldnode

Here's are two cool YT videos showing the effect.

https://www.youtube.com/watch?v=-mjRPgP0oAE

https://www.youtube.com/watch?v=JGk3agy-c50

Upvotes: 2

Related Questions