【问题标题】:Beginner collision detection in Swift questionSwift 问题中的初学者碰撞检测
【发布时间】:2020-07-28 03:28:12
【问题描述】:

我想以我是新手程序员的身份开场,所以请多多包涵。

我正在学习 Paul Hudson 的 100 天 Swift 课程,但我遇到了他提出的挑战。我创建了一个游戏,用户点击以放下球,球与盒子碰撞并掉入坑中(见屏幕截图)。

球正确地从盒子反弹,但是我正在尝试实现它,当球与盒子碰撞时,盒子被破坏。我的实现发生的情况是球在与盒子碰撞时被破坏。

框定义

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)

我相信问题出在下面。我认为它要么在我传入的参数中(即使它们的标题是球,我认为它们仍然应该删除该框,因为它只是参数名称)。我的第二个猜测是 didBegin 方法,你可以看到我尝试实现一个解决方案。我不完全理解该方法,以及 nodeA 和 B 所指的内容。我试图定义一个nodeC,但收到错误“'SKPhysicsContact'类型的值没有成员'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)
        }
    }

【问题讨论】:

  • 如果你 addChild(box) 你可以再次把它拿走,所以在你的碰撞调用中提供一个 func destroy(box:) 而不是 object.name == "box"。简单吗?
  • 感谢@OlSen 的回复。我尝试添加一个在盒子中传递的新函数:func destroy(box: SKNode) { box.removeFromParent() },但这仍然会导致球被破坏而不是盒子。有任何想法吗?似乎我仍在将球传给这些破坏功能,我只是不知道为什么。

标签: ios swift iphone sprite-kit


【解决方案1】:

看起来collission(between:object:) 在所有 3 条路径中都摧毁了球。

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

我可能还会将该函数重命名为destroy(object:),因为您可以使用它来摧毁一个盒子或一个球。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多