Crashalot
Crashalot

Reputation: 34523

SpriteKit: better way to temporarily change velocity on sprite?

Let's say node A is moving with an original velocity vector of (0, 9.8). After a collision with node B, node A should move backwards temporarily, say with a vector of (0, -2), but after 0.2 seconds, resume its original velocity. In other words, node A should simulate the effects of a bump from node B before continuing its original trajectory.

This needs to happen in four directions, so we cannot rely on gravity (which only works in one direction).

We plan to do something like this:

func didBeginContact(contact: SKPhysicsContact!) {
        let collision:UInt32 = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask)

        let dx = nodeB?.physicsBody?.velocity.dx
        let dy = nodeB?.physicsBody?.velocity.dy

        nodeB.runAction(                
            SKAction.sequence([
                SKAction.runBlock {
                    nodeB?.physicsBody?.applyImpulse( CGVectorMake(0, -2.0))
                },
                SKAction.waitForDuration(0.2)
            ]),
            completion: {
                nodeB?.physicsBody?.velocity.dx = dx
                nodeB?.physicsBody?.velocity.dy = dy
            }
        )

}

However, this seems messy. Is there a better way to do this with Swift?

Upvotes: 0

Views: 867

Answers (2)

sabiland
sabiland

Reputation: 2614

Just a tip: I've noticed strange physics-engine breaks (NOT crashes, but physics got corrupted somehow) if I modified physicsBody.velocity directly.

Update method should be used for this.

Upvotes: 1

rakeshbs
rakeshbs

Reputation: 24572

It's a good idea to use intermediate variables when you have complex code.

let dx = nodeB?.physicsBody?.velocity.dx
let dy = nodeB?.physicsBody?.velocity.dy

let waitAction = SKAction.waitForDuration(0.2)

let runAction = SKAction.runBlock({ () -> Void in
    nodeB?.physicsBody?.applyImpulse( CGVectorMake(0, -2.0))
    return
})

let sequenceAction = SKAction.sequence([runAction,waitAction])

nodeB?.runAction(sequenceAction, completion: { () -> Void in
    nodeB?.physicsBody?.velocity.dx = dx!
    nodeB?.physicsBody?.velocity.dy = dy!
})

Upvotes: 1

Related Questions