0

I'm trying to find the source of the following skspritenode strange behavior: sometimes it just doesn't execute .run(...) or executes incompletely . I couldn't find any regularity in it, so I'd like to know, if it is a known problem?

func didBegin(_ contact: SKPhysicsContact) {

    let firstBody = contact.bodyA
    let secondBody = contact.bodyB

 if firstBody.categoryBitMask == CollisionBitMask.birdCategory && secondBody.categoryBitMask == CollisionBitMask.BonusCategory {
        secondBody.node?.removeFromParent()
        print("contact began")
        firstBody.node?.run(SKAction.run {
            print("run works")
        })
    }
    else if firstBody.categoryBitMask == CollisionBitMask.BonusCategory && secondBody.categoryBitMask == CollisionBitMask.birdCategory {
        firstBody.node?.removeFromParent()
        print("contact began")
        secondBody.node?.run(SKAction.run {
            print("run works")
        })

    }
Anton
  • 155
  • 13
  • I have never had a problem using run on an SKSpriteNode that I could not track down to a fault in my code. Please post an example that you find does not work. – Ali Beadle Dec 16 '17 at 20:05
  • here is the code example, phrase "contact began" fires even if "run works" doesn't . – Anton Dec 16 '17 at 20:17
  • An SKAction will only run if the node is in a scene, have you checked this? E.g. If both nodes are configured to trigger didBegin(contact) then they will each remove the other from the scene and thus cause the actions to be frozen. – Ali Beadle Dec 16 '17 at 20:28
  • but only one of the nodes is removed, another should run the action . – Anton Dec 16 '17 at 20:31
  • The action is not executed immediately but by the scene and this may not happen until the next animation frame. Both nodes will make contact with each other and (if they are configured to - you have not shown that code, so I am not sure) *both* trigger the didBegin method before that, so they may be removing each other from the scene before the action gets to run. – Ali Beadle Dec 16 '17 at 20:36
  • My previous comment implies that didBegin will be called twice because there are two nodes in the contact - that is not true but it *can* be called multiple times per apparent contact and the order of the two bodies in the parameters is not guaranteed, so that may explain why you are getting inconsistent 'run' results. See [this SO question and answers](https://stackoverflow.com/questions/24228274/why-are-didbegincontact-called-multiple-times) for more info on this. – Ali Beadle Dec 16 '17 at 20:46
  • as I can see it is called only once, the only thing which can be changed is the order of nodes : bodyA has 1st category bodyB 2nd category and vice versa, but this is taken into account by checking categoryBitMaks values. The problem is, that if I remove removeFromParent the problem remains, which means, that it is not because some of the nodes is removed – Anton Dec 16 '17 at 20:51

1 Answers1

1

it is still not clear, why it caused the problems, but the skspritenode didn't execute .run after I tried to set its velocity somewhere in the code:

enumerateChildNodes(withName: "bird", using: ({
        (node, error) in
        let bg = node as! SKSpriteNode
        bg.physicsBody?.affectedByGravity = false
       bg.speed = 0 // <- after removing this, everything works fine
        }))
Anton
  • 155
  • 13
  • 1
    Ah ha, that is it, well done. The [speed parameter](https://developer.apple.com/documentation/spritekit/sknode/1483036-speed) is not the velocity of the node but the speed at which it will run its actions, so setting t to zero,will stop all actions. – Ali Beadle Dec 17 '17 at 06:46