GodelEscher
GodelEscher

Reputation: 539

SpriteKit not detecting physics bodies when using alpha mask but does when using bounding circle

I am pretty new to SpriteKit so I may be missing something quite obvious.

I am attempting to create an interactive map of the US. I have loaded PNG images for each state and placed a couple of them into the main SKScene using the scene editor.

Screenshot of the scene editor

My goal is wanting to detect when each state is tapped by the user. I initially wrote some code that would find the nodes within a touch location however, this meant that the user could tap the frame and it would be counted as a valid tap. I only want to register touches that happen within the state texture and not the frame. Reading online it was suggested to use SKPhysicsBody to register when a tap takes place. So I changed my code to the following.

class GameScene: SKScene {
    override func didMove(to view: SKView) {}
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let location: CGPoint = self.convertPoint(fromView: touch.location(in: self.view))
        let body = self.physicsWorld.body(at: location)

        if let state = body?.node, let name = state.name {
            state.run(SKAction.run({
                var sprite = self.childNode(withName: name) as! SKSpriteNode
                sprite.color = UIColor.random()
                sprite.colorBlendFactor = 1
            }))
        }
    }
    
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

Now, if I choose the Bounding circle body type everything works as expected (shown above in the screenshot). When I click within the boudning circle it runs the SKAction otherwise it does nothing. However, when I change the body type to Alpha mask (the body type I want) it suddenly stops detecting the state. In fact, it returns the SKPhysicsBody for the MainScene entity.

Any advice on how to fix this would be greatly appreciated.

Thanks.

Upvotes: 1

Views: 125

Answers (1)

Fault
Fault

Reputation: 1329

i can reproduce this behavior (bug?) when using the scene editor. however it goes away if you skip the sks file and initialize your sprites in code. (i acknowledge that setting locations for 50 states is more tedious this way.)

class GameScene: SKScene {

    let ok = SKSpriteNode(imageNamed: "ok")
    let nm = SKSpriteNode(imageNamed: "nm")
    let tx = SKSpriteNode(imageNamed: "tx")
    
    override func didMove(to view: SKView) {
        tx.name = "Texas"
        nm.name = "New Mexico"
        ok.name = "Oklahoma"

        //set up physics bodies w/ alpha mask
        tx.physicsBody = SKPhysicsBody(texture: tx.texture!, size: tx.texture!.size())
        tx.physicsBody?.affectedByGravity = false
        nm.physicsBody = SKPhysicsBody(texture: nm.texture!, size: nm.texture!.size())
        nm.physicsBody?.affectedByGravity = false
        ok.physicsBody = SKPhysicsBody(texture: ok.texture!, size: ok.texture!.size())
        ok.physicsBody?.affectedByGravity = false

        //then position your sprites and add them as children
    }
}

Upvotes: 1

Related Questions