【问题标题】:Objects colliding with each-other when they shouldn't (SpriteKit)不应该发生碰撞的对象(SpriteKit)
【发布时间】:2016-06-20 18:33:38
【问题描述】:

我正在使用 SpriteKitSwift 2。我知道有很多教程,但我觉得它们一定已经过时了,否则我会发疯,因为似乎每个人对不同的物理位掩码的作用都有不同的看法。

我只是想让两个物体相互碰撞。这就是我所做的:

var everythingElseCategory: UInt32  = 3
var object1Category: UInt32  = 2
var object2Category: UInt32  = 4

object1.physicsBody?.categoryBitMask = object1;
object1.physicsBody?.collisionBitMask = everythingElseCategory

object2.physicsBody?.categoryBitMask = object2;
object2.physicsBody?.collisionBitMask = everythingElseCategory

everythingElse.physicsBody?.categoryBitMask = everythingElseCategory;
everythingElse.physicsBody?.collisionBitMask = 0 //its a wall

我一定把位掩码的概念搞砸了,因为对我来说,碰撞位掩码就是它所碰撞的东西,但似乎我一定是错的,因为这个解决方案不起作用。 Object2 和 object1 发生碰撞,但是 object1 没有和 object2 发生碰撞!!!?!??!

关于我做错了什么有什么想法吗?

谢谢!

【问题讨论】:

  • 关键是 -> 这些是位掩码,以避免不必要的行为,最好以这种方式分配它们 UInt32 = 0x1
  • Apple's SpriteKit physics example 也可能感兴趣。您正在使用整数值,您需要使用二进制。转换这些,你的碰撞类别是0011,你的object2Category0100,这意味着它不会碰撞。最简单的方法是使用位移来创建位掩码。
  • 查看这篇维基百科文章以更好地了解位掩码的工作原理en.wikipedia.org/wiki/Mask_(computing)
  • @Gliderman 让您的评论成为答案,以便您获得一些代表。
  • @user3351949 修复了所有问题...非常感谢!是的,您应该将其发布为答案^^

标签: ios swift sprite-kit


【解决方案1】:

从我的评论中移出这个。

Apple's SpriteKit physics example 可能感兴趣。

您使用的是整数值,而不是二进制值。这是二进制值的样子:

everythingElseCategory = 0011b // I think you need the "b" somewhere to indicate binary
object1Category = 0010b
object2Category = 0100b

基本上,SK 物理会对两个对象使用&(二元与)运算符,如果值不是0,它们就会发生碰撞。以您的两个对象为例:

object1.physicsBody?.categoryBitMask = object1 (0010)
object1.physicsBody?.collisionBitMask = everythingElseCategory (0011)

object2.physicsBody?.categoryBitMask = object2 (0100)
object2.physicsBody?.collisionBitMask = everythingElseCategory (0011)

object1 的位掩码将与object2 的位掩码冲突,因为0010 & 0011 == 0010 或非零。 object2 的位掩码不会与 object1 的冲突,因为 0100 & 0011 == 0000 的冲突为零或没有冲突。

解决此问题的最简单方法是使用位移。语法如下:

value = bitValue << placesToShiftLeft

所以您的位掩码设置如下所示:

everythingElseCategory = 1 << 0 // I have this shifted by 0 just to show that you can do that
object1Category = 1 << 1
object2Category = 1 << 2

现在,当您为对象设置位掩码时,使用|(二进制或)运算符将它们组合起来。 001 | 010 == 011 是这样工作的。

object1.physicsBody?.categoryBitMask = object1Category
object1.physicsBody?.collisionBitMask = everythingElseCategory | object2Category

object2.physicsBody?.categoryBitMask = object2Category
object2.physicsBody?.collisionBitMask = everythingElseCategory | object1Category

everythingElse.physicsBody?.categoryBitMask = everythingElseCategory | object1Category | object2Category

这将防止多个object1 相互碰撞,但允许与其他一切碰撞。

【讨论】:

    【解决方案2】:

    另一种编码碰撞位掩码的方法是记住,默认情况下,它设置为 UInt32.max,即一切都与一切发生碰撞。如果你想让一个物体与除特定物体之外的所有物体发生碰撞,那么从它与所有物体碰撞开始,然后关闭代表你希望它碰撞的物体的位会更容易,例如

        // Assign the category
    object1.physicsBody?.categoryBitMask = object1Category  
        // Turn off collisions with object1 and object2
    object1.physicsBody?.collisionBitMask &= ~(object1Category | object2Category) 
    

    您可以打开和关闭特定类别的碰撞,而不影响任何其他碰撞,如下所示:

        // Turn on collisions with object3
    object1.physicsBody?.collisionBitMask |= object3Category 
    
        // Turn off collisions with object4
    object1.physicsBody?.collisionBitMask &= ~object4Category 
    
        // Turn on collisions with object 5  & 6
    object1.physicsBody?.collisionBitMask |= (object5Category | object6Category) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多