Search code examples
iosswiftsprite-kitcollision-detection

Sprite Kit Collision without dynamic


I want to move my players node by tapping on either each half on the screen.

As soon as the tap stopped, the node should stop too. As I have it now, as soon as the screen is touched, the players node is dynamic = true, and if the touch ended it is set to dynamic = false, to avoid the players ongoing movement. With this method, the Collision Detectiondoesn't work.

Is there maybe another method to get the result?

Code:

func addPlayer(){

    let Player1 = SKTexture(imageNamed: "Player1.png")
    Player1.filteringMode = .Nearest
    let Player2 = SKTexture(imageNamed: "Player2.png")
    Player2.filteringMode = .Nearest

    let Run = SKAction.animateWithTextures([Player1, Player2], timePerFrame: 0.5)
    let RunAnimation = SKAction.repeatActionForever(Run)

    Player = SKSpriteNode(texture: Player1)
    Player.size = CGSize(width: self.frame.size.width / 6.5, height: self.frame.size.height / 12)
    Player.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 1.2)
    Player.zPosition = 4
    Player.runAction(RunAnimation)

    Player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 40, height: 60))
    Player.physicsBody?.allowsRotation = false
    Player.physicsBody?.usesPreciseCollisionDetection = true
    Player.physicsBody?.restitution = 0
    Player.physicsBody?.dynamic = true
    Player.physicsBody?.velocity = CGVectorMake(0, 0)

    Player.physicsBody?.categoryBitMask = PlayerCategory
    Player.physicsBody?.collisionBitMask = WallCategory
    Player.physicsBody?.contactTestBitMask = WallCategory

    self.addChild(Player)
}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    let touch:UITouch = touches.anyObject() as UITouch
    let touchLocation = touch.locationInNode(self)

    if touchLocation.x < self.frame.size.width / 2 {

        Player.physicsBody?.dynamic = true
        Player.physicsBody?.applyImpulse(CGVectorMake(-35, 0))

    } else {

        Player.physicsBody?.dynamic = true
        Player.physicsBody?.applyImpulse(CGVectorMake(35, 0))
    }
}

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {

    let touch:UITouch = touches.anyObject() as UITouch
    let touchLocation = touch.locationInNode(self)

    if touchLocation.x < self.frame.size.width / 2 {

        Player.physicsBody?.dynamic = false

    } else {

        Player.physicsBody?.dynamic = false
    }
}

Solution

  • Just set the velocity of the body to 0 if you want the body to stop from any movement which happens because of physics:

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    
        let touch:UITouch = touches.anyObject() as UITouch
        let touchLocation = touch.locationInNode(self)
    
        if touchLocation.x < self.frame.size.width / 2 {      
            Player.physicsBody?.velocity = CGVectorMake(0, 0)
        } else {  
            Player.physicsBody?.velocity = CGVectorMake(0, 0)
        }
    }