【问题标题】:Physics detecting collision multiple times物理多次检测碰撞
【发布时间】:2015-02-15 13:45:01
【问题描述】:

当球与杯子碰撞时,分数应该增加 1。但目前它会增加 1、3 或有时是 4,这意味着多次检测到碰撞。

我想我一定是错误地检查了碰撞:

let ballCategory   : UInt32 = 0x1 << 0 
let cupCategory : UInt32 = 0x1 << 1 

在我的didMoveToView:

//Set physicsBody of scene to a physics body that borders the screen

self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
physicsWorld.contactDelegate = self

//Ball
ballSprite.physicsBody = SKPhysicsBody(rectangleOfSize: ballSprite.size)
ballSprite.physicsBody!.categoryBitMask = ballCategory
ballSprite.physicsBody!.contactTestBitMask = cupCategory

//Cup
cupSprite.physicsBody = SKPhysicsBody(edgeLoopFromRect: cupSprite.size) 
cupSprite.physicsBody!.categoryBitMask = cupCategory
cupSprite.physicsBody!.contactTestBitMask = ballCategory

在我的didBeginContact:

var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody

//Assign the two physics bodies so that the one with the lower category is always stored in firstBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {

    firstBody = contact.bodyA
    secondBody = contact.bodyB
} 
else {

    firstBody = contact.bodyB
    secondBody = contact.bodyA
}

//contact between ball and cup
if firstBody.categoryBitMask == ballCategory && secondBody.categoryBitMask == cupCategory {

    score++
    println("point scored")
    moveBall() //Move ball back to start position
}

这在它正在检测碰撞的意义上是有效的,但是它会发生多次,而它应该只发生一次。

【问题讨论】:

  • 确保您拥有完全独立的对象类别。

标签: swift sprite-kit skphysicsbody


【解决方案1】:

您可以设置一个 BOOL 值来检查是否允许联系处理(在开头设置 YES)。更新分数后,您可以将该变量设置为 NO,然后运行 ​​moveBall() 重新开始,并在 moveBall() 方法结束时将 BOOL 值设置为 YES。我认为这样的事情应该可行。

其他方法是从父节点中删除球/或杯子节点并将其设置为 nil(然后重新创建它们)。另外我不知道 SpriteKit 有多少“喜欢”这种方式(在物理模拟完成之前删除节点)。

第三种方法是让 Ball 类具有一些 BOOL 属性,指示是否应将球移动到起始位置。根据该值,您应该更新分数变量/处理接触和碰撞。因此,在更新分数后,您将 BOOL 值设置为 YES,然后运行 ​​moveBall(),然后将 BOOL 值设置为 NO 等...与我描述的第一种方法类似。

【讨论】:

  • 因为同样的问题浪费了几个小时。我通过使我的“SkPhyiscsBody”变得“更大”来解决它。首先我用 ".physicsBody = SKPhysicsBody(rectangleOf: object.sizr" 对其进行了测试,它工作得很好。我调整了相似的大小,突然碰撞只检测到一次。
【解决方案2】:

这发生在我身上,要做的事情很简单,只需像这样定义每个节点需要的所有内容: 首先为节点制作这个,无论是屏幕边框还是它碰到的任何节点,都这样说:

let nodesCatergory : UInt32 = 0x1 << 1 

之后,把这个 nodesCategory 放到你在游戏中的每个节点,或者它碰撞的节点上,然后像这样添加它:

if firstBody.categoryBitMask == ballCategory &&       secondBody.categoryBitMask == nodesCatergory {
//score++
println("point scored, NOT!")
//moveBall() //Move ball back to start position
  }

就是这样!您可以这样做,直到获得所需的效果!

【讨论】:

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