DNC
DNC

Reputation: 443

Sticking Node to another Node when Colliding

I am making an iOS game(swift xcode).

there is a car that moves constantly(SKAction) and a player which you can move with swipe gestures.

All good, but now I want that if the player touches the car, it will move the same with the car(it gets sticked to the car)

Now how do I do this?

I tried many things but none of them worked Smoothly..

I tried to use

if (CGRectIntersectsRect(car.frame, player.frame)) {
car.position = player.position
}

this works, but the player gets kicked to the middle of the car, I do not want this. What I want is that if the player touches the bottom of the car, it gets sticked to the bottom of the car.

How do I do that??

for the collision detecion I also tried to use:

 func didBeginContact(contact: SKPhysicsContact!) {
    var firstBody:SKPhysicsBody
    var secondBody:SKPhysicsBody

    if(contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask){
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    }else{
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }


    if((firstBody.categoryBitMask & CarCategory) != 0 && (secondBody.categoryBitMask & playerCategory) != 0)
    {


    }

}

But I Do not know what to put between the brackets to make it function smoothly like I want.

Upvotes: 3

Views: 1172

Answers (4)

0x141E
0x141E

Reputation: 12773

You can connect the two nodes with a fixed physics joint. Physics joints, in general, connect two physics bodies that are in the scene. The fixed version, SKPhysicsJointFixed, joins two bodies such that they act as a single body.

Here's an example of how connects two physics bodies with a fixed joint:

First, add this to your SKScene subclass (e.g., GameScene.m)

func joinPhysicsBodies(bodyA:SKPhysicsBody, bodyB:SKPhysicsBody, point:CGPoint) {
    let joint = SKPhysicsJointFixed.jointWithBodyA(bodyA, bodyB: bodyB, anchor: point)
    self.physicsWorld.addJoint(joint)
}

and add this in the if statement in didBeginContact

self.joinPhysicsBodies(firstBody, bodyB:secondBody, point:contact.contactPoint)

where contact.contactPoint is the point of the contact.

Upvotes: 3

jonogilmour
jonogilmour

Reputation: 673

There are two ways to do this.

You can use joints, as detailed here How to create joints in Sprite Kit (Xcode)?

Or you can just remove the player node from the world and add it as a child of the vehicle node, in which case the vehicle node and player node will be linked and will move together. Do this with removeChildWithName() and addChild().

Upvotes: 0

user4233369
user4233369

Reputation:

A simpler way to do this without physics is to use constraints:

if (CGRectIntersectsRect(car.frame, player.frame)) {
    player.constraints=[SKConstraint.distance(SKRange(upperLimit: 100), toNode: car)]
}

This will ensure the player is at most 100 points away from the car (you can change this number to make it more realistic)

And when you want to detach the player:

player.constraints=[]

Upvotes: 2

Stefan
Stefan

Reputation: 5461

Implement the SKPhysicsContactDelegate protocol:

class GameScene: SKScene, SKPhysicsContactDelegate

Set the delegate at the end of didMoveToView

override func didMoveToView(view: SKView) {
  ...

  self.physicsWorld.contactDelegate = self
}

Create global variables to store the collision categories:

let collisionCar: UInt32  = 0x1 << 0
let collisionPlayer: UInt32    = 0x1 << 1

Create a physics body for car and player:

car.physicsBody = SKPhysicsBody(rectangleOfSize: car.size)
car.physicsBody?.affectedByGravity = false
car.physicsBody?.dynamic = false
car.physicsBody?.categoryBitMask = collisionCar
car.physicsBody?.contactTestBitMask = collisionPlayer
car.physicsBody?.collisionBitMask = 0x0;

player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size)
player.physicsBody?.affectedByGravity = false
player.physicsBody?.dynamic = false
player.physicsBody?.categoryBitMask = collisionPlayer
player.physicsBody?.contactTestBitMask = collisionCar
player.physicsBody?.collisionBitMask = 0x0;

Implement didBeginContact:

    func didBeginContact(contact: SKPhysicsContact) {
...
    }

Upvotes: 0

Related Questions