简体   繁体   中英

Beginner collision detection in Swift question

I wanted to open with that I'm a novice programmer, so please bear with me.

I'm going through Paul Hudson's 100 Days of Swift course and I am stuck on a challenge he's given. I have created a game which a user taps to drop a ball and the ball collides with boxes and also drops into a pit (see screenshot).

The balls bounce off the boxes properly, however I'm trying to implement it where when a ball collides with a box, the box is destroyed. What is happening with my implementation is that the ball is being destroyed when colliding with the box.

Box definition

box.run(spinForever)
box.zRotation = CGFloat.random(in: 0...3)
box.position = location
box.name = "box"
box.physicsBody = SKPhysicsBody(rectangleOf: box.size)
box.physicsBody?.isDynamic = false
box.physicsBody?.contactTestBitMask = box.physicsBody?.collisionBitMask ?? 0
addChild(box)

I believe the issue lies below. I think it's either in the parameter I pass in (even though they're titled ball, I think they should still work with deleting the box since it's just the parameter name). My second guess is the didBegin method, which you can see my attempt at implementing a solution. I don't fully understand that method, and what nodeA and B refer to. I tried to define a nodeC, but received the error "Value of type 'SKPhysicsContact' has no member 'bodyC'"

    func collision(between ball: SKNode, object: SKNode) {
        // Did it collide with a good or a bad slot?
        if object.name == "good" {
            destroy(ball: ball)
            score += 1
            ballCount += 1
        } else if object.name == "bad" {
            destroy(ball: ball)
            score -= 1
            ballCount -= 1
        } else if object.name == "box" {
            destroy(ball: ball)
        }
    }
    
    func destroy(ball: SKNode) {
        if let fireParticles = SKEmitterNode(fileNamed: "MagicParticles") {
            fireParticles.position = ball.position
            addChild((fireParticles))
        }
        ball.removeFromParent()
    }
    

    func didBegin(_ contact: SKPhysicsContact) {
        
        // Small chance that a collision could occur twice, so we use guard let to make sure both nodes exist and just return if they don't
        guard let nodeA = contact.bodyA.node else { return }
        guard let nodeB = contact.bodyB.node else { return }
        
        
        if nodeA.name == "ball" {
            collision(between: nodeA, object: nodeB)
        } else if nodeB.name == "ball" {
            collision(between: nodeB, object: nodeA)
        } else if nodeA.name == "box" {
            collision(between: nodeA, object: nodeB)
        } else if nodeB.name == "box" {
            collision(between: nodeB, object: nodeA)
        }
    }

在此处输入图像描述

It looks like collission(between:object:) destroys the ball in all 3 paths.

 } else if object.name == "box" {
            destroy(ball: object)
 }

I would probably also rename the function to destroy(object:) since you can use it to destroy either a box or a ball.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM