4

Here is a video of the issue I am having. As you can see in the video, I move a gray ball to try and collide with a red ball. When the two objects collide no bouncing occurs, the red ball just moves. I've tried playing around with the densities of the red balls, such as making the red ball densities 0.00001. There was no difference in the collision behavior.

How can I change the collision behavior so there is bouncing?

Here are the properties of the gray ball:

func propertiesGrayBall() {
    gray = SKShapeNode(circleOfRadius: frame.width / 10 )
    gray.physicsBody = SKPhysicsBody(circleOfRadius: frame.width / 10 )
    gray.physicsBody?.affectedByGravity = false
    gray.physicsBody?.dynamic = true
    gray.physicsBody?.allowsRotation = false
    gray.physicsBody?.restitution = 1
}

Here are the properties of the red ball:

func propertiesRedBall  {
    let redBall = SKShapeNode(circleOfRadius: self.size.width / 20
    redBall.physicsBody = SKPhysicsBody(self.size.width / 20)
    redBall.physicsBody?.affectedByGravity = false
    redBall.physicsBody?.dynamic = true
    redBall.physicsBody?.density = redBall.physicsBody!.density * 0.000001
    redBall.physicsBody?.allowsRotation = false
    redBall.physicsBody?.restitution = 1
}

Here is how I move the gray ball.

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if fingerIsOnGrayBall {
        let touch = touches.first
        var position = touch!.locationInView(self.view)
        position = self.convertPointFromView(position)
        grayBall.position = position
    }
}

Major Edits The ball originally had attachments. I deleted them to simplify the problem. That's why the comments might not add up with the code.

Sami
  • 579
  • 5
  • 25
  • 1
    Could you show us the code for the physics connection between the gray ball and the black one? There may be something in there that is not allowing it to respond to the physics collision. – Gliderman Oct 01 '15 at 01:53
  • @Gliderman I just updated the code! Thanks for your response. – Sami Oct 01 '15 at 02:15
  • 1
    It's interesting that you say that changing the restitution to 1 made no different. Have you tried to set restitution to true and then do blackBall.physicsBody?.usePreciseCollisionDetection = true ? You do move the ball quite quickly, so perhaps that could solve the issue. – theprole Oct 01 '15 at 09:49
  • @theprole Thanks for your response! Yeah I thought it was weird that changing the restitution to 1 did not make the difference. I just tried your suggestion and unfortunately setting `blackBall.physicsBody?.usePreciseCollisionDetection = true` did not solve the issue. Is there anything else that could be limiting my objects from responding properly? – Sami Oct 01 '15 at 13:37
  • I just rewrote the question and simplified it. Hope this helps! – Sami Oct 01 '15 at 20:21
  • 1
    @Sami Interesting, maybe you want to try using a `SKAction` to move the gray circle (a very quick action that moves almost instantly). This may allow the physics engine to properly work? Sometimes setting the position directly doesn't work. – Gliderman Oct 01 '15 at 22:16
  • @Gliderman I just tried moving the ball using `SKAction`, no luck. I'm mind blown why this won't work. Surely I'm not the first person trying to move an object with their finger and get it to collide and bounce with another object... – Sami Oct 02 '15 at 00:59

1 Answers1

3

If you move a node (with a physics body) by settings its position, directly or with an SKAction, the node will not be a part of the physics simulation. Instead, you should move the node by applying a force/impulse or by setting its velocity. Here's an example of how to do that:

First, define a variable to store the position of the touch

class GameScene: SKScene {
    var point:CGPoint?

Then, delete the following statement from your code

redBall.physicsBody?.density = redBall.physicsBody!.density * 0.000001

Lastly, add the following touch handlers

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    /* Called when a touch begins */

    for touch in touches {
        let location = touch.locationInNode(self)

        let node = nodeAtPoint(location)
        if (node.name == "RedBall") {
            point = location
        }
    }
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */

    for touch in touches {
        let location = touch.locationInNode(self)
        if point != nil {
            point = location
        }
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    point = nil
}

override func update(currentTime: CFTimeInterval) {
    if let location = point {
        let dx = location.x - redBall.position.x
        let dy = location.y - redBall.position.y
        let vector = CGVector(dx: dx*100, dy: dy*100)
        redBall.physicsBody?.velocity = vector
    }
}
0x141E
  • 12,613
  • 2
  • 41
  • 54