SKShapeNode seems to be missing touches

I need to detect touches on a circular skshapenode but the obvious code (below) fails. Identical code (but changing circle to triangle) works fine. It seems that there is a fundamental difference between SKShapeNodes of different shapes! Please could an expert advise?

Many thanks,

David C


import SpriteKit


class GameScene: SKScene {

var ball: SKShapeNode!

var triangle: SKShapeNode!

override func didMove(to view: SKView) {

backgroundColor = .white

ball = createBall()

ball.position = CGPoint.zero

addChild(ball)

triangle = createTriangle()

triangle.position = CGPoint(x: 0.0, y: 100.0)

addChild(triangle)

}

func createBall() -> SKShapeNode {

let Bpath = CGMutablePath()

Bpath.addArc(center: CGPoint.zero,

radius: 35,

startAngle: 0,

endAngle: CGFloat.pi * 2,

clockwise: true)

let ball = SKShapeNode(path: Bpath, centered: true)

ball.lineWidth = 1

ball.strokeColor = .black

ball.isUserInteractionEnabled = true

return ball

}

func createTriangle() -> SKShapeNode {

let Tpath = CGMutablePath()

Tpath.move(to: CGPoint(x: 0, y: 0))

Tpath.addLine(to: CGPoint(x: CGFloat(250), y: 0))

Tpath.addLine(to: CGPoint(x: CGFloat(125), y: CGFloat(125)))

Tpath.closeSubpath()

let triangle = SKShapeNode(path: Tpath, centered: true)

triangle.lineWidth = 1

triangle.strokeColor = .black

return(triangle)

}

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

for touch in touches {

let location = touch.location(in: self)

print("\(location)") // diagnostic - produces output whenever click is NOT within ball SKShapeNode

if ball.contains(location) {

print("ball contains \(location)") // diagnostic - never produces output!!

}

if triangle.contains(location) {

print("triangle contains \(location)") // diagnostic - produces output!!

}

}

}

}

Accepted Reply

Why do you set `isUserInteractionEnabled` to true only on your `ball`?


        ball.isUserInteractionEnabled = true


With removing the line, I could get this sort of output when touching the circle.

(-6.64251279830933, -2.41541862487793)

ball contains (-6.64251279830933, -2.41541862487793)

Replies

Does it work if you add:


Bpath.closeSubpath()


to the code that creates the ball?

Why do you set `isUserInteractionEnabled` to true only on your `ball`?


        ball.isUserInteractionEnabled = true


With removing the line, I could get this sort of output when touching the circle.

(-6.64251279830933, -2.41541862487793)

ball contains (-6.64251279830933, -2.41541862487793)

Thank you both very much! Closing the ball path turned out not to affect things but getting rid of the isUserInteractionEnabled certainly did.

Thanks again,

David C