Swift 3 Sprite 节点接触/碰撞行为不正常
Posted
技术标签:
【中文标题】Swift 3 Sprite 节点接触/碰撞行为不正常【英文标题】:Swift 3 Sprite Node Contact / Collision not behaving properly 【发布时间】:2017-01-01 20:32:15 【问题描述】:我现在所拥有的:我当前的大多数 Sprite 节点碰撞都按应有的方式工作,除了 boxNode 与 floorNode 接触。我有 3 个精灵节点:一个 floorNode、playerNode 和 boxNode。当用户点击屏幕时,playerNode 在空中弹跳,boxNode(s)从天花板上生成并下落,直到与 floorNode 接触。
问题:我遇到的碰撞是boxNode与floorNode碰撞时。游戏当前在 boxNode 与 floorNode 接触时结束,此时应该发生的只是 boxNode 在与 floorNode 碰撞时消失。
playerNode 与 floorNode 冲突 = 游戏结束
boxNode 与 playerNode 冲突 = 游戏结束
boxNode 与 floorNode 碰撞 =(发生此碰撞时游戏结束)不应导致游戏结束。
这是我当前的代码:
import UIKit
import SpriteKit
import SceneKit
import Foundation
import CoreData
import GameplayKitstruct
ColliderType
static let blueBallCategory: UInt32 = 0x1 << 0
static let floorNode: UInt32 = 0x1 << 1
static let firstBody: UInt32 = 0x1 << 2
static let secondBody: UInt32 = 0x1 << 3
static let boxNodeCategory: UInt32 = 0x1 << 4
class GameScene: SKScene, SKPhysicsContactDelegate
floorNode.contactTestBitMask = 0
floorNode.categoryBitMask = ColliderType.floorNodeCategory
floorNode.collisionBitMask = ColliderType.playerNodeCategory | ColliderType.boxNodeCategory
self.physicsBody = floorNode
self.physicsBody?.friction = 0
playerNode.physicsBody?.categoryBitMask = ColliderType.playerNodeCategory
playerNode.physicsBody?.contactTestBitMask = 0
playerNode.physicsBody?.collisionBitMask = ColliderType.floorNodeCategory
boxNode.physicsBody?.categoryBitMask = ColliderType.boxNodeCategory
boxNode.physicsBody?.contactTestBitMask = ColliderType.playerNodeCategory | ColliderType.floorNodeCategory
boxNode.physicsBody?.collisionBitMask = 0
func didBegin(_ contact:SKPhysicsContact)
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == ColliderType.playerNodeCategory || secondBody.categoryBitMask == ColliderType.boxNodeCategory
self.boxNode.removeFromParent()
gameOver = true
self.speed = 0
timer.invalidate()
else if firstBody.categoryBitMask == ColliderType.floorNodeCategory || secondBody.categoryBitMask == ColliderType.floorNodeCategory
gameOver = true
self.speed = 0
timer.invalidate()
else if firstBody.categoryBitMask == ColliderType.boxNodeCategory || secondBody.categoryBitMask == ColliderType.floorNodeCategory
self.boxNode.removeFromParent()
else if contact.bodyA.categoryBitMask == ColliderType.boxNodeCategory
contact.bodyA.node!.removeFromParent()
else if contact.bodyB.categoryBitMask == ColliderType.boxNodeCategory
contact.bodyB.node!.removeFromParent()
gameOver = true
self.speed = 0
timer.invalidate()
【问题讨论】:
您的代码 sn-p 令人困惑,因为缩进被弄乱了(可能是当您复制它时),但它看起来也是不完整的。请发布您的完整联系人处理委托方法,即func didBegin(_ contact: SKPhysicsContact) ... 嗨@AliBeadle,我更新了我的代码并修复了缩进,所以希望现在它更容易阅读。感谢您的回复。 【参考方案1】:问题似乎是您没有正确考虑方法 didBegin(contact:) bodyA 和 bodyB 可以按任意顺序排列的事实。例如,如果物理体 X 与物理体 Y 碰撞,则可以使用 bodyA=X 和 bodyB=Y 或 bodyA=Y 和 bodyB=X 调用方法 didBegun(contact:)。您的代码需要考虑这一点,目前不需要。
特别是 bodyA 是地板而 bodyB 是盒子的情况:这将失败,除了你的最后一个条件 - 结束游戏。
【讨论】:
抱歉回复晚了,我工作比平时忙。是否可以创建更多的接触体?例如:让thirdBody = contact.bodyC。我还在快速学习,有没有办法专门为特定情况/条件分配 bodyA 和 bodyB? @p.dane 我不太确定我是否理解。请注意,Swift 只是一种语言。精灵、物理体等由 SpriteKit 提供,这是一个独立于 Swift 语言的 API。每个 Sprite 都可以有自己的物理体。您可以拥有任意数量的精灵(带有物理实体)。每个物理体都有一个类别 - 该类别是一个 32 位掩码,因此您最多可以有 32 个不同的类别。 对于我可能造成的任何混乱,我深表歉意。您曾提到 bodyA 和 bodyB 可以按任意顺序排列。但在这种情况下,bodyA 需要分配给 floorNode,bodyB 分配给 boxNode。有没有办法将主体分配给特定节点,而不是让主体按任何顺序排列? 我将编辑我的答案以澄清 - 我的意思是在方法 didBegin(contact:) 中 bodyA 和 bodyB 可以是任何一种方式。 很抱歉延迟回复,工作一直很忙。您更新的答案对我来说更有意义,但是当我将您的建议实施到我的代码中时,它并没有真正解决问题。无论出于何种原因,每当我在 didBegin(contact:) 方法中添加“ else-if ”语句或代码行时,我添加的代码似乎都不起作用。我会尽快更新我上面的原始代码。以上是关于Swift 3 Sprite 节点接触/碰撞行为不正常的主要内容,如果未能解决你的问题,请参考以下文章