Search code examples
swiftsprite-kitskphysicsbody

Specific Head On Collision in Swift 4


I am new to iOS development and I made an infinite runner game. As you can see in the function below, the player dies when it collides with an obstacle. However, the player dies whenever it collides with any side of the obstacle. How can I limit this collision detection to a specific side of the frame of the obstacle?

func didBegin(_ contact: SKPhysicsContact) { //so the player can't jump while in the air
    var firstBody = SKPhysicsBody()
    var secondBody = SKPhysicsBody()

    if contact.bodyA.node?.name == "Player" {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if firstBody.node?.name == "Player" && secondBody.node?.name == "Ground" { //if colliding with ground
        canJump = true //can jump when on ground
    }

    if firstBody.node?.name == "Player" && secondBody.node?.name == "Bus" || firstBody.node?.name == "Player" && secondBody.node?.name == "Obstacle" {
        // kill player and prompt buttons
        playerDied()
    }
}

Solution

  • You may try to calculate the intersection between two colliding nodes, then just checking width and height of the resulting frame should be enough to detect the collision side, a rough explanation:

    1. collision left/right

    enter image description here

    1. collision top/down

    enter image description here

    for a infinite runner game this check should be enough:

    if firstBody.node?.name == "Player" && secondBody.node?.name == "Obstacle" {
        let intersection = firstBody.node!.frame.intersection(secondBody.node!.frame)
        if intersection.height > intersection.width { // collision left/right
            playerDied()
        } else { // collision top/down
           //...//
        }
    }