0

I used the enumerateChildNodesWithName command to give all of my blocks physics, like so:

    func findBlock(theName:String){

        self.enumerateChildNodesWithName("//*"){
        node, stop in

            if node.name == theName{
                node.physicsBody?.categoryBitMask = physicsCategory.block
                node.physicsBody?.collisionBitMask = physicsCategory.laser
                node.physicsBody?.contactTestBitMask = physicsCategory.laser
            } 
        }
    }

And now I want only one of the blocks to disappear when it gets hit by a laser. However, I haven't been able to make that happen without making all of the other blocks disappear at the same time.
I tried to use this line of code in didBeginContact to find which block represents the first body and remove it:

if firstBody.categoryBitMask == physicsCategory.block && secondBody.categoryBitMask == physicsCategory.laser{

        let block = SKSpriteNode()
        block.physicsBody = firstBody
        block.alpha = 1
        let byeBlock = SKAction.fadeOutWithDuration(0.5)
        let gone = SKAction.removeFromParent()
        let run = SKAction.sequence([byeBlock, gone])
        block.runAction(run)
        self.removeChildrenInArray([laser])

    }

but that also ended up not working. Please help! Thanks in advance!

  • And what is the code when block got hit by the laser? I assume that you handle this in `didBeginContact`... – Whirlwind Apr 24 '16 at 09:14
  • @Whirlwind it is in `didBeginContact`. At first I tried to use the same `enumerateChildNodesWithName` command to delete the block, but obviously that removed every block on the screen. Most recently I tried this line of code: – Jason Gaffney Apr 24 '16 at 13:28
  • if firstBody.categoryBitMask == physicsCategory.block && secondBody.categoryBitMask == physicsCategory.laser{ let block = SKSpriteNode() block.physicsBody = firstBody block.alpha = 1 let byeBlock = SKAction.fadeOutWithDuration(0.5) let gone = SKAction.removeFromParent() let run = SKAction.sequence([byeBlock, gone]) block.runAction(run) self.removeChildrenInArray([laser]) } – Jason Gaffney Apr 24 '16 at 13:29
  • But that doesn't work either. – Jason Gaffney Apr 24 '16 at 13:29
  • Using this code (where you enumerate through all nodes) in `didBeginContact` is wrong (if you don't want to remove all blocks). The right way would be to check which body represents block and to remove it. There are really a lot of posts here on SO which describe how to handle `didBeginContact`. Just use search and let me know if you are having further troubles. Also, please avoid pasting a lot of code in comments. You should update your question with further changes. Code in comments is not readable. – Whirlwind Apr 24 '16 at 13:31
  • Here is a good explanation about bit masks. http://stackoverflow.com/q/34904564/3402095 And a good posts about how to implement `didBeginContact` method : http://stackoverflow.com/a/26723392/3402095 , http://stackoverflow.com/a/26443216/3402095 ( <- this one would be an easiest solution for you). – Whirlwind Apr 24 '16 at 13:42

1 Answers1

0

I assume that you handle contacts as it should, so that if block you provided works correctly. If so, this is what you want :

if firstBody.categoryBitMask == physicsCategory.block && secondBody.categoryBitMask == physicsCategory.laser{
{
    //Downcast it to SKSpriteNode or whatever your block is
    if let block = firstBody.node as? SKSpriteNode {

        //We don't want to run removing action twice on the same block
        if block.actionForKey("removing") == nil {

            block.alpha = 1
            let fadeOut = SKAction.fadeOutWithDuration(0.5)
            let remove = SKAction.removeFromParent()
            block.runAction(SKAction.sequence([fadeOut, remove]), withKey: "removing")
        }

    }
    //Downcast it to SKSpriteNode or whatever your laser is
    if let laser = secondBody.node as? SKSpriteNode {
        self.removeChildrenInArray([laser])
    }

}
Whirlwind
  • 14,286
  • 11
  • 68
  • 157