Search code examples
swiftsprite-kitcollision-detectioncollision

Swift/SpriteKit Collision Detection


I have created two objects, a wall and a player which can collide. If they do collide the player should not be able to move in or over the wall. If I do set massWall >> massPlayer the player can sometimes move over the wall. If I set no mass the player and the wall get moved in a direction. I want to achieve that the wall is standing still and the player can't get over/through the wall. My code:

    func addWall(xPos: CGFloat, yPos: CGFloat){
    let wallNode = SKSpriteNode(imageNamed: "wall")

    wallNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
    wallNode.physicsBody!.affectedByGravity = false
    wallNode.physicsBody!.categoryBitMask = ColliderType.Wall.rawValue
    wallNode.physicsBody!.contactTestBitMask = ColliderType.Player.rawValue
    wallNode.physicsBody!.collisionBitMask = ColliderType.Player.rawValue
    wallNode.physicsBody!.mass = 1000000

    let wall = Wall(node: wallNode)
    Walls.append(wall)
    wallNode.position.x = xPos
    wallNode.position.y = yPos
    wallNode.size = CGSize(width: width, height: width)
    addChild(wallNode)
}

func addPlayer(xPos: CGFloat, yPos: CGFloat){
    playerNode = SKSpriteNode(imageNamed: "player")

    playerNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
    playerNode.physicsBody!.affectedByGravity = false
    playerNode.physicsBody!.categoryBitMask = ColliderType.Player.rawValue
    playerNode.physicsBody!.contactTestBitMask = ColliderType.Wall.rawValue
    playerNode.physicsBody!.collisionBitMask = ColliderType.Wall.rawValue
    playerNode.physicsBody!.mass = 1


    let player = Player(node: playerNode, healthPoints: 100, attack: 10)
    playerNode.position.x = xPos
    playerNode.position.y = yPos
    playerNode.size = CGSize(width: width, height: width)
    addChild(playerNode)
}

In the func didBeginContact(){} I have nothing codes in it, because I don't now what to do with it. I can't undo the movement because I don't keep track of the last move.


Solution

  • There are two things that you need to change. The first one is to solve the player going through the wall. This is fixed by enabling precise collision detection on the playerNode as such (just put this up with the rest of the physicsBody configuration):

    playerNode.physicsBody!.usesPreciseCollisionDetection = true
    

    Next you need to make your wall not have dynamic physics, this will stop it from reacting when your playerNode bumps into it. You don't need to set the mass of the wallNode, you won't need it. So something like this should be added (just put this up with the rest of the physicsBody configuration):

    wallNode.physicsBody!.dynamic = false