SpriteKit: didBeginContact being called non-stop o

2019-09-01 18:19发布

问题:

I have a very simple project using SpriteKit where a monster is dropped and walks across a platform. On the iPhone, didBeginContact gets called once when the monster hits the platform. However, on the iPad, the method gets called several times a second as the monster slides across the platform. Why is it fine on the iPhone but buggy on the iPad? I've tested on both the simulator and an actual iPad.

Here is where I set up the Categories

static const uint32_t playerCategory        = 0x1 << 0;
static const uint32_t bulletCategory        = 0x1 << 1;
static const uint32_t monsterCategory       = 0x1 << 2;
static const uint32_t platformCategory      = 0x1 << 3;
static const uint32_t worldCategory         = 0x1 << 4;

Here are the settings for the monster

enemy.physicsBody.dynamic = YES;
enemy.physicsBody.affectedByGravity = YES;
enemy.physicsBody.allowsRotation = NO;
enemy.physicsBody.categoryBitMask = monsterCategory;
enemy.physicsBody.contactTestBitMask = worldCategory & platformCategory & bulletCategory;
enemy.physicsBody.collisionBitMask = platformCategory;

Here is how the monster gets moved

enemy.physicsBody.velocity = CGVectorMake(100, 0);

And here is how I know didBeginContact gets called constantly. I get a log 5 times every second saying monster hit platform. I need to fix this for when I implement new things later.

if (firstBody.categoryBitMask == monsterCategory && secondBody.categoryBitMask == platformCategory) {
    NSLog(@"Monster Hit Platform");
}

回答1:

enemy.physicsBody.restitution = 0;
platform.physicsBody.restitution = 0;

This is the "bounciness" property. This way, when the enemy and platform collide, there will not be little bounces triggering multiple contact events.

I have also seen that it is recommended to use applyImpulse instead of setting the velocity manually.



回答2:

Do this...

var gameOver: Bool = false
func didBeginContact(contact: SKPhysicsContact) {
    if(gameOver){
        return
    }
    gameOverScene()

}

func gameOverScene(){
    gameOver = true
        let GameSceneSet = GameOver(size: self.size)
        let reveal = SKTransition.crossFadeWithDuration(0.5)
        self.view?.presentScene(GameSceneSet, transition: reveal)
}