-1

I have a bomb spawner in GameScene.swift that adds SKShapeNodes to the Scene. Each SKShapeNode is a physics object that falls and has the name set to "bomb". I want to detect when the user touches these nodes (mid-fall using touchesBegan), but it doesn't work. What am I doing wrong?

// Bomb Spawner Function
func spawnBomb() {
    let bombHeight = 80
    let bomgWidth = 40
    // Define Bomb
    let bomb = SKShapeNode(rectOf: CGSize(width: bomgWidth,
                                          height: bombHeight))
    bomb.name = "bomb"
    bomb.zPosition = 10
    bomb.isUserInteractionEnabled = true
    bomb.position = CGPoint(x: size.width / 2, y:  size.height / 2)
    bomb.fillColor = SKColor.blue
    // Add Physics Body
    bomb.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: bomgWidth,
                                                         height: bombHeight))
    // Determine Random Position
    let randomPosition = abs(CGFloat(random.nextInt()).truncatingRemainder(dividingBy: size.width))
    bomb.position = CGPoint(x: randomPosition, y: size.height)
    // Add Category BitMask
    bomb.physicsBody?.categoryBitMask = BombCategory
    bomb.physicsBody?.contactTestBitMask = WorldFrameCategory
    // Add to the scene
    addChild(bomb)

}

Touch Detection

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let touch:UITouch = touches.first!
    let positionInScene = touch.location(in: self)
    let touchedNode = self.atPoint(positionInScene)

    if let name = touchedNode.name
    {
        if name == "bomb"
        {
            print("bomb Touched")
        }
    }
}
  • I'm no game expert and I've never done this. But I think you want to add a touch gesture recognizer to each bomb object as it's instantiated. – Jake Jun 23 '18 at 21:10
  • I think that [This RayWenderlich Tutorial](https://www.raywenderlich.com/96822/sprite-kit-tutorial-drag-drop-sprites) should help you figure it out. – Jake Jun 23 '18 at 21:11

1 Answers1

1

My suspicion is that your problem stems from the fact that atPoint returns an SKNode. You have two ways of getting the topmost node:

if atPoint(touch.location(in: self)) == childNode(withName: "bomb"){
//run your code
}

That's fine for individual nodes. Personally, I like using a subclass, so I would use

class Bomb: SKShapeNode

and simply see whether the topmost node under my touch can be cast to Bomb.

if let bomb = atPoint(touch.location(in: self)) as? Bomb {
//...
}

This lets you move your bomb-typical settings into the subclass and makes for more readable code overall.

green_knight
  • 1,319
  • 14
  • 26
  • I rewrote the whole thing and used this scheme. I have no idea why it wasn't working before though. https://stackoverflow.com/a/41324936/3903960 – user3903960 Jun 24 '18 at 18:23