Andy Lebowitz
Andy Lebowitz

Reputation: 1501

applyImpulse not working when touching node

I have a circle on the screen that will slowly get bigger (incidentally, Balloon class is a type of SKShapeNode). In touchesBegan I click on the circle and it prints that I touched it, however no impulse is applied. How can I find the issue? I'm fairly new to SpriteKit.

import SpriteKit
import GameplayKit

class GameScene: SKScene {

var radius = 40.0

var balloon : Balloon? = nil

override func didMove(to view: SKView) {

    balloon = Balloon(radius: radius, position: CGPoint(x: frame.midX, y: frame.minY + 250))
    balloon?.name = "balloon"

    let physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(radius))
    physicsBody.affectedByGravity = false
    balloon?.physicsBody = physicsBody
    balloon?.physicsBody?.isDynamic = true

    let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
    borderBody.friction = 0
    self.physicsBody = borderBody
    physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)

    self.addChild(balloon!)

}



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        let node : SKNode = self.atPoint(location)
        if node.name == "balloon" {
            print("touching balloon.")
            balloon?.physicsBody?.applyImpulse(CGVector(dx: 10.0, dy: 10.0), at: location)
        }
    }

}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {

}


 override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
    radius += 0.05
    self.balloon?.radius = radius

    let physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(radius))
    physicsBody.affectedByGravity = false
    balloon?.physicsBody = physicsBody
    balloon?.physicsBody?.isDynamic = true

  }
}

Upvotes: 1

Views: 82

Answers (2)

Knight0fDragon
Knight0fDragon

Reputation: 16827

You are creating a new body every update. If you want to inflate your balloon, use scale:

var scale = 1.0
override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
    scale += 0.05
    self.balloon?.setScale(scale)
}

Then your physics body will be able to have the impulse applied to it because you won't be creating a new body each update.

Upvotes: 1

Tob
Tob

Reputation: 1025

The following line:

let location = touch.location(in: self)

finds the location of the touch in the scene. However, in the function call applyImpulse, it is relative to the node. Instead of

balloon?.physicsBody?.applyImpulse(CGVector(dx: 10.0, dy: 10.0), at: location)

use:

balloon?.physicsBody?.applyImpulse(CGVector(dx: 10.0, dy: 10.0), at: touch.location(in: balloon))

Upvotes: 0

Related Questions