物理多次检测碰撞
Physics detecting collision multiple times
当球与杯子碰撞时,分数应该增加 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
}
这在检测碰撞的意义上是有效的,但是它发生了多次,而它应该只发生一次。
你可以设置一个BOOL值来检查是否允许接触处理(一开始设置YES)。更新分数后,您可以将该变量设置为 NO,然后 运行 moveBall() 再次开始,并在 moveBall() 方法结束时将 BOOL 值设置为 YES。我认为类似的东西应该有用。
其他方法是从父节点中删除 ball/or 杯节点并将其设置为 nil(然后重新创建它们)。我也不知道这种方式有多少 SpriteKit "likes"(在完成物理模拟之前删除节点)。
第三种方法是让 Ball class 和一些 BOOL 属性 指示球是否应该移动到起始位置。根据该值,您应该更新分数 variable/handle 接触和碰撞。因此,在更新分数后,您将 BOOL 值设置为 YES,然后 运行 moveBall() 然后将 BOOL 值设置为 NO 等...与我描述的第一种方法类似。
这件事发生在我身上,要做的很简单,只需像这样定义每个节点都需要一个:
首先为节点做这个,无论是屏幕边框还是它碰到的任何节点,这样说:
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
}
就是这样!就这样一直做到想要的效果!
当球与杯子碰撞时,分数应该增加 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
}
这在检测碰撞的意义上是有效的,但是它发生了多次,而它应该只发生一次。
你可以设置一个BOOL值来检查是否允许接触处理(一开始设置YES)。更新分数后,您可以将该变量设置为 NO,然后 运行 moveBall() 再次开始,并在 moveBall() 方法结束时将 BOOL 值设置为 YES。我认为类似的东西应该有用。
其他方法是从父节点中删除 ball/or 杯节点并将其设置为 nil(然后重新创建它们)。我也不知道这种方式有多少 SpriteKit "likes"(在完成物理模拟之前删除节点)。
第三种方法是让 Ball class 和一些 BOOL 属性 指示球是否应该移动到起始位置。根据该值,您应该更新分数 variable/handle 接触和碰撞。因此,在更新分数后,您将 BOOL 值设置为 YES,然后 运行 moveBall() 然后将 BOOL 值设置为 NO 等...与我描述的第一种方法类似。
这件事发生在我身上,要做的很简单,只需像这样定义每个节点都需要一个: 首先为节点做这个,无论是屏幕边框还是它碰到的任何节点,这样说:
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
}
就是这样!就这样一直做到想要的效果!