物理检测多次碰撞

时间:2015-02-15 13:45:01

标签: swift sprite-kit skphysicsbody

当球与杯子碰撞时,得分应增加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
}

这是因为它正在检测碰撞,但它发生了多次,而它应该只发生一次。

2 个答案:

答案 0 :(得分:2)

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

其他方法是从父节点移除球节点或杯节点并将其设置为nil(然后重新创建它们)。另外,我不知道SpriteKit&#34;喜欢&#34;这样(在物理模拟完成之前删除节点)。

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

答案 1 :(得分:0)

这件事发生在我身上,做什么很简单,只需定义每个节点需要的一切: 首先为节点做这个,如果它是一个屏幕边框或它所遇到的节点,请说:

let nodesCatergory : UInt32 = 0x1 << 1 

之后,将此nodesCatergory放入游戏中的每个节点,或者它与之碰撞的节点,然后像这样添加:

if firstBody.categoryBitMask == ballCategory &&       secondBody.categoryBitMask == nodesCatergory {
//score++
println("point scored, NOT!")
//moveBall() //Move ball back to start position
  }
那就是它!你可以做到这些,直到获得所需的效果!