Search code examples
swift3collisionremovechild

Detecting collision and removing child with spritekit in swift 3


At the end, I'm trying to detect collision, and delete the marble as it touches the rectangle. How do I do that?

import CoreMotion
import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate{
    let marbleSprite = SKSpriteNode(imageNamed: "marble")
    let marbleSprite1 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite2 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite3 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite4 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite5 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite6 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite7 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite8 = SKSpriteNode(imageNamed: "marble")
    let marbleSprite9 = SKSpriteNode(imageNamed: "marble")
    let rectSprite = SKSpriteNode(imageNamed: "rect")
    let rectSprite1 = SKSpriteNode(imageNamed: "rect")
    let motionManager = CMMotionManager()

    let marbleCategory: UInt32 = 1 << 0
    let wallCategory: UInt32 = 2 << 0
    let rectCategory: UInt32 = 3 << 0
    var teal = SKColor(red: 0, green: 128, blue: 128, alpha: 1)

    override func didMove(to view: SKView) {
        backgroundColor = teal

        marbleSprite.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite.setScale(0.5)
        marbleSprite.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite.size.width / 2)
        marbleSprite.physicsBody?.allowsRotation = true
        marbleSprite.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite1.name = "Marble"

        marbleSprite1.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite1.setScale(0.5)
        marbleSprite1.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite1.size.width / 2)
        marbleSprite1.physicsBody?.allowsRotation = true
        marbleSprite1.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite1.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite1.name = "Marble"


        marbleSprite2.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite2.setScale(0.5)
        marbleSprite2.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite2.size.width / 2)
        marbleSprite2.physicsBody?.allowsRotation = true
        marbleSprite2.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite2.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite2.name = "Marble"

        marbleSprite3.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite3.setScale(0.5)
        marbleSprite3.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite3.size.width / 2)
        marbleSprite3.physicsBody?.allowsRotation = true
        marbleSprite3.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite3.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite3.name = "Marble"

        marbleSprite4.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite4.setScale(0.5)
        marbleSprite4.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite4.size.width / 2)
        marbleSprite4.physicsBody?.allowsRotation = true
        marbleSprite4.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite4.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite4.name = "Marble"

        marbleSprite5.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite5.setScale(0.5)
        marbleSprite5.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite5.size.width / 2)
        marbleSprite5.physicsBody?.allowsRotation = true
        marbleSprite5.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite5.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite5.name = "Marble"

        marbleSprite6.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite6.setScale(0.5)
        marbleSprite6.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite6.size.width / 2)
        marbleSprite6.physicsBody?.allowsRotation = true
        marbleSprite6.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite6.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite6.name = "Marble"

        marbleSprite7.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite7.setScale(0.5)
        marbleSprite7.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite7.size.width / 2)
        marbleSprite7.physicsBody?.allowsRotation = true
        marbleSprite7.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite7.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite7.name = "Marble"

        marbleSprite8.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite8.setScale(0.5)
        marbleSprite8.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite8.size.width / 2)
        marbleSprite8.physicsBody?.allowsRotation = true
        marbleSprite8.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite8.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite8.name = "Marble"

        marbleSprite9.position = CGPoint(x: self.frame.width / 15, y: self.frame.height / 15)
        marbleSprite9.setScale(0.5)
        marbleSprite9.physicsBody = SKPhysicsBody(circleOfRadius: marbleSprite9.size.width / 2)
        marbleSprite9.physicsBody?.allowsRotation = true
        marbleSprite9.physicsBody?.categoryBitMask = marbleCategory
        marbleSprite9.physicsBody?.collisionBitMask = wallCategory | marbleCategory
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        self.physicsBody?.isDynamic = false
        self.physicsBody?.categoryBitMask = wallCategory
        marbleSprite9.name = "Marble"

        rectSprite.position = CGPoint(x: 0, y: self.frame.height / 2)
        rectSprite.setScale(3.0)
        rectSprite.physicsBody = SKPhysicsBody(rectangleOf: rectSprite.size)
        rectSprite.physicsBody?.allowsRotation = false
        rectSprite.physicsBody?.categoryBitMask = rectCategory
        rectSprite.physicsBody?.collisionBitMask = marbleCategory
        rectSprite.physicsBody?.affectedByGravity = false
        rectSprite.physicsBody?.isDynamic = false
        rectSprite.name = "Rect"

        rectSprite1.position = CGPoint(x: 410, y: self.frame.height / 2)
        rectSprite1.setScale(3.0)
        rectSprite1.physicsBody = SKPhysicsBody(rectangleOf: rectSprite1.size)
        rectSprite1.physicsBody?.allowsRotation = false
        rectSprite1.physicsBody?.categoryBitMask = rectCategory
        rectSprite1.physicsBody?.collisionBitMask = marbleCategory
        rectSprite1.physicsBody?.affectedByGravity = false
        rectSprite1.physicsBody?.isDynamic = false
        rectSprite1.name = "Rect"



        physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        addChild(marbleSprite)
        addChild(marbleSprite1)
        addChild(marbleSprite2)
        addChild(marbleSprite3)
        addChild(marbleSprite4)
        addChild(marbleSprite5)
        addChild(marbleSprite6)
        addChild(marbleSprite7)
        addChild(marbleSprite8)
        addChild(marbleSprite9)
        addChild(rectSprite)
        addChild(rectSprite1)
        motionManager.startAccelerometerUpdates()






    }
    override func update(_ currentTime: TimeInterval) {
        if let accelerometerData = motionManager.accelerometerData {
            print(accelerometerData)
            physicsWorld.gravity = CGVector(dx: accelerometerData.acceleration.x * 10, dy: accelerometerData.acceleration.y * 10)
        }
    }

    func didBegin(_ contact: SKPhysicsContact) {
        var firstBody = SKPhysicsBody()
        var secondBody = SKPhysicsBody()

        if contact.bodyA.node?.name == "Marble" {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }
        if firstBody.node?.name == "Marble" && secondBody.node?.name == "Rect" {
            secondBody.node?.removeFromParent()
        }
    }

}

What I thought that would happen was that once the marble touches the rectangle, the marble would disappear, and be gone. What actually happens is when the marble hits the rectangle, nothing happens. Am I doing something wrong?


Solution

  • Try making these changes and set the contact delegate.

    let marbleCategory: UInt32 = 0x1 << 0
    let wallCategory: UInt32 = 0x1 << 1
    let rectCategory: UInt32 = 0x1 << 2
    
    override func didMove(to view: SKView) {
        physicsWorld.contactDelegate = self
    }
    
    func didBegin(_ contact: SKPhysicsContact) {
        let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
        if collision == marbleCategory | rectCatagory {
            rectSprite.removeFromParent()
        }
    }