物理多次检测碰撞 [英] Physics detecting collision multiple times

查看:14
本文介绍了物理多次检测碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When the ball collides with the cup, the score should increase by 1. However it currently increases by 1, 3 or sometimes 4 which means the collision is being detected multiple times.

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

I think I must be checking for collisions incorrectly:

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
}

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

This works in the sense that it is detecting the collision, however it is happening multiple times whereas it should only happen once.

推荐答案

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

You can set one BOOL value to check if is allowed contact handling(set YES at the beginning). After updating score, you can set that variable to NO, then run moveBall() to start again and at the end of moveBall() method set BOOL value to YES. I think something like that should work.

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

Other way would be to remove ball/or cup nodes from parent and set it to nil (and then re-recreate them). Also I don't know how much SpriteKit "likes" this way(removing nodes before physics simulation is done).

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

Third way would be to have Ball class with some BOOL property that indicating whether the ball should be moved to start position. Based on that value you should update the score variable/handle contacts and collisions. So after updating the score, you set BOOL value to YES and then run moveBall() and then set BOOL value to NO etc...Similar as first method I described.

这篇关于物理多次检测碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆