UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Hi did someone manage to solve challenge 3 from Project 11? I'm trying to remove those boxes when a ball hits, but is just not working.

Forums > 100 Days of Swift

Coud someone help me pout with this please? I have used this on the box object as well to get those notifications "box.physicsBody!.contactTestBitMask = box.physicsBody!.collisionBitMask" and the same methods but the ball just bounces off the boxes.

3      

What does your collisionBetween(ball:object:) function look like?

3      

Hi and thank you for the reply, this is what I have so far, but I still don't get it why is not removing the node from the game when the ball hits.

func collisionBetween(ball: SKNode, object: SKNode) { if object.name == "good" { // green slot destroy(ball: ball) score += 1 usedBalls += 1 } else if object.name == "bad" { // red slot destroy(ball: ball) // the ball will be removed once drops into a green or red slot score -= 1

    }

}

func boxandballCollision(box: SKNode, ball: SKNode) {
    if ball.name == "ball" {
    destroyObject(box: box)

    }
}

func destroyObject(box: SKNode) {
    if let fireParticles = SKEmitterNode(fileNamed: "FireParticles") {
        fireParticles.position = box.position
        addChild(fireParticles)
    }

    box.removeFromParent() // box should be removed when a ball will hit it
}

func destroy(ball: SKNode) {
    if let fireParticles = SKEmitterNode(fileNamed: "FireParticles") {
        fireParticles.position = ball.position
        addChild(fireParticles)
    }

    ball.removeFromParent() // ball object is removed from scene when hits a slot

}

func didBegin(_ contact: SKPhysicsContact) {
    guard let nodeA = contact.bodyA.node else { return }
    guard let nodeB = contact.bodyB.node else { return }

    if nodeA.name == "ball" {
        collisionBetween(ball: nodeA, object: nodeB)
    } else if nodeB.name == "ball" {
        collisionBetween(ball: nodeB, object: nodeA)

        }
    }

func begin(_ contact: SKPhysicsContact) {
    guard let nodeA = contact.bodyA.node else { return }
    guard let nodeB = contact.bodyB.node else { return }

    if nodeA.name == "box" {
        boxandballCollision(box: nodeA, ball: nodeB)
    } else if nodeB.name == "box" {
        boxandballCollision(box: nodeB, ball: nodeA)
      }
   }

3      

I have declared another method for box and ball collision

3      

The problem is this function:

func begin(_ contact: SKPhysicsContact) {
    guard let nodeA = contact.bodyA.node else { return }
    guard let nodeB = contact.bodyB.node else { return }

    if nodeA.name == "box" {
        boxandballCollision(box: nodeA, ball: nodeB)
    } else if nodeB.name == "box" {
        boxandballCollision(box: nodeB, ball: nodeA)
      }
   }

It never gets called. You are probably thinking it should be called just like didBegin(_:) is, but that function is part of the SKPhysicsContactDelegate protocol and gets called by the system. The system has no way of knowing to call your new begin(_:) function.

You need to put your logic into didBegin(_:) and get rid of your begin(_:) function. You don't really need a separate function if one of the objects involved in the collision is a box.

Here, for instance, is the relevant code from my Project 11:

    func didBegin(_ contact: SKPhysicsContact) {
        guard let nodeA = contact.bodyA.node else { return }
        guard let nodeB = contact.bodyB.node else { return }

        if nodeA.name == "ball" {
            collisionBetween(ball: nodeA, object: nodeB)
        } else if contact.bodyB.node?.name == "ball" {
            collisionBetween(ball: nodeB, object: nodeA)
        }
    }

    func collisionBetween(ball: SKNode, object: SKNode) {
        if object.name == "good" {
            score += 1
            ballCount += 1
            destroy(ball: ball)
        } else if object.name == "bad" {
            score -= 1
            destroy(ball: ball)
        } else if object.name == "box" {
            //we have an obstacle object
            object.removeFromParent()
        }
    }

See how we already know that one of the objects involved is a ball, so all we really need to do in collisionBetween(ball:object:) is check what the other object is.

5      

And please, when posting code to these forums, place three backticks ``` on the line before your code and three backticks ``` on the line after your code so that it will be formatted properly. You can also highlight an entire codeblock and click the </> button on the toolbar to wrap the block for you.

This makes it far easier to read and also makes it easier for other posters to copy/paste the code in order to test solutions and such.

Doing this will ensure that you end up with something like this:

func printSomething(_ thing: String?) {
    if let thing = thing {
        print(thing)
    } else {
        print("nothing there")
    }
}

instead of this:

func printSomething(_ thing: String?) { if let thing = thing { print(thing) } else { print("nothing there") } }

4      

Okay thank you! That makes sense, I was thinking if I have the same parameter for that seperate method it might pick up that function, just tried your solution which works great, I just called that distructionObject(box:) method in "collisionBetween" method to apply that fire effect. I will put those backticks there, I was looking how to wrap my block of code. Thanks again!

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.