1

Creating a game in Swift and SprieKit.

I have 2 nodes, a BridgeNode and WaterNode. One on top of the other.

Both have physics bodies to detect when the player is either on the bridge on in the water. Both nodes are added independently as child nodes of the Scene.

When the player node jumps onto the Bridge, DidBegin detects contact with both the Water and Bridge nodes. I only want it to detect the Bridge node as the player is safely on the Bridge OR if the player is in the water.

func didBegin(_ contact: SKPhysicsContact) {
       // Did Begin Contact - Contact Testing and actions
       let player1 = (contact.bodyA.categoryBitMask == player1Mask) ? contact.bodyA : contact.bodyB
       let other = (player1 == contact.bodyA) ? contact.bodyB : contact.bodyA

    if other.categoryBitMask == bridgeMask {
        print("BRIDGE CONTACT")

    }
    else if other.categoryBitMask == waterMask {
        // Contacted Water
        print("WATER CONTACT")

    }
}

The console is printing both print statements always in a random order.

Hope someone can help me to just detect one or the other.

Leethal
  • 25
  • 4
  • A bit silly perhaps, but are you having the view's `showPhysics == true` ? And is it obvious to you that the player's `physicsBody` _only_ touches the bridge _or_ the water (not both)? – T. Benjamin Larsen Feb 27 '17 at 05:22
  • I haven't got showPhysics anywhere in the code for anything. So I assume it is probably set to the default value. Yeah I checked this by making the bridge longer than the water size-wise and still happens. – Leethal Feb 27 '17 at 06:15
  • didBegin is still printing out both BRIDGE CONACT and WATER CONTACT. So the player is in contact with them both. How can I layer this properly? – Leethal Apr 02 '17 at 00:47

1 Answers1

0

You mentioned that it is a top-down game, so when you have the bridge on top of the water the player will obviously contact both at the same time, there is no "blocking" of the physicsBody underneath the bridge. You need to do something like this in your SKPhysicsContactDelegate:

var playerIsOnBridge = false

func didBegin(_ contact: SKPhysicsContact) {
    let player1 = (contact.bodyA.categoryBitMask == player1Mask) ? contact.bodyA : contact.bodyB
    let other = (player1 == contact.bodyA) ? contact.bodyB : contact.bodyA

    if other.categoryBitMask == bridgeMask || playerIsOnBridge {
        playerIsOnBridge = true
        print("BRIDGE CONTACT")
    } else if other.categoryBitMask == waterMask {
        print("WATER CONTACT")
    }
}

func didEnd(_ contact: SKPhysicsContact) {
    let bitmaskA = contact.bodyA.categoryBitMask
    let bitmaskB = contact.bodyB.categoryBitMask

    if bitmaskA == bridgeMask || bitmaskB == bridgeMask {
        playerIsOnBridge = false
    }
}
T. Benjamin Larsen
  • 6,373
  • 4
  • 22
  • 32
  • Yeah I initially thought of putting in a bool to check this too. Unfortunately the above has not resolved the issue. Dual detection is still getting through which is no good because obviously if the player is on the bridge the player is meant to be safe and if contact with the water is made the player dies, at the moment both happens haha. What is now occurring randomly, not all the time though, is BRIDGE CONTACT printing twice. – Leethal Feb 27 '17 at 06:09
  • Tecnically the above should work provided the player hits the bridge prior to hitting the water. This might force you to make the physicsBody of the bridge slightly larger than its texture I can imagine... – T. Benjamin Larsen Feb 27 '17 at 06:13
  • Making the physicsBody slightly larger is a good idea, however I just tried that and it didn't seem to help the issue much. The detection of the water and bridge at the same time is still getting through, but not in every test. The player node is animating up and down to appear as if the player is jumping forward, although what is actually happening is the background is moving down one step. It feels like DidBegin contact is being called earlier than I'd like, possible, just a theory. – Leethal Feb 27 '17 at 06:28
  • Well, you now at least know why you receive contact with both. I suggest tuning the sizes/adding invisible nodes with bridge-category until you get the desired result. – T. Benjamin Larsen Feb 27 '17 at 06:32
  • I've slowed the animation durations right down to like a slow-mo so to be able to see the print statements print out at what point. Slightly increasing the size of the bridge appears to have stopped the unnecessary contact with water call. As you said above increasing the physics body likely have done the trick too, but I think covering up every slightest pixel between the ground and bridge so no water is getting through along with the code above might have solved this. – Leethal Feb 27 '17 at 06:39