1

I made a game which essentially has a ball and a couple of targets and paddles. However I needed to make it so depending on what target the ball collides with the speed is either tripled, doubled or halved as long as it doesn't drop below a minimum speed or goes above a maximum speed.

To do this I used the didBegin(contact) function together and set the different velocities as it can be seen in the code below:

extension CGVector {
var speed: CGFloat {
    return hypot(dx, dy)
}

static func > (lhs: CGVector, rhs: CGVector) -> Bool {
    return lhs.speed > rhs.speed
}

static func < (lhs: CGVector, rhs: CGVector) -> Bool {
    return lhs.speed < rhs.speed
}

static func * (vector: CGVector, multiplier: CGFloat) -> CGVector {
    return CGVector(dx: vector.dx * multiplier, dy: vector.dy * multiplier)
}

static func / (vector:CGVector, divider:CGFloat) -> CGVector {
    return CGVector(dx: vector.dx / divider, dy: vector.dy / divider)
}
}

func didBegin(_ contact: SKPhysicsContact) {
    var firstBody = SKPhysicsBody()
    var secondBody = SKPhysicsBody()
    let ballNode = self.childNode(withName: ballName)
    let minSpeed = self.initialSpeed / 2
    let maxSpeed = self.initialSpeed * 3

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

    if firstBody.categoryBitMask == ballBitmask && secondBody.categoryBitMask == drainBitmask {
        endGame()
        Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.showLeaderboard), userInfo: nil, repeats: false)

    } else if firstBody.categoryBitMask == ballBitmask && secondBody.categoryBitMask == target1Bitmask {
        let currentSpeed = ballNode?.physicsBody?.velocity
        score += 20
        self.vc.scoreLabel.text = "Score: \(score)"

        if currentSpeed == maxSpeed {

            ballNode?.physicsBody?.velocity = currentSpeed!

        } else if (currentSpeed! * 2) > maxSpeed {

            ballNode?.physicsBody?.velocity = maxSpeed

        } else if (currentSpeed! * 2) < maxSpeed {

            ballNode?.physicsBody?.velocity = currentSpeed! * 2

        }

    } else if firstBody.categoryBitMask == ballBitmask && secondBody.categoryBitMask == target2Bitmask {
        let currentSpeed = ballNode?.physicsBody?.velocity
        score += 10
        self.vc.scoreLabel.text = "Score: \(score)"

        if currentSpeed == minSpeed {

            ballNode?.physicsBody?.velocity = currentSpeed!

        } else if (currentSpeed! / 2) > minSpeed {

            ballNode?.physicsBody?.velocity = currentSpeed! / 2

        } else if (currentSpeed! / 2) < minSpeed {

            ballNode?.physicsBody?.velocity = minSpeed

        }


    } else if firstBody.categoryBitMask == ballBitmask && secondBody.categoryBitMask == target3Bitmask {
        let currentSpeed = ballNode?.physicsBody?.velocity
        score += 30
        self.vc.scoreLabel.text = "Score: \(score)"

        if currentSpeed == maxSpeed {

            ballNode?.physicsBody?.velocity = currentSpeed!

        } else if (currentSpeed! * 3) > maxSpeed {

            ballNode?.physicsBody?.velocity = maxSpeed

        } else if (currentSpeed! * 3) < maxSpeed {

            ballNode?.physicsBody?.velocity = currentSpeed! * 3

        }


    }

My issue is sometimes when the ball collides with the targets it bounces off in a very weird and unrealistic way and sometimes just essentially glitches out (please check the link below for a short video clip which shows what I mean)

Note: At 2/3 seconds into the video is an example of the weird bounce happening

https://drive.google.com/open?id=0BxgQmn_JruJ_aUU2dVBoVlprV0k

Why is this happening and more importantly how can I fix it?

PS: One suggestion that I believe might be causing this is the fact the vector for velocity controls both the angle(direction) and speed (I think)of the ball therefore when I set the velocity the direction isn't taken in account. If this is the cause would it be possible to triple/double/halve the velocity whilst still making the bounce realistic?

  • here's an idea on how to do this a little easier, perhaps. Let the ball bounce, then get the vector of its movement the frame after it's bounced, and multiply that vector. Don't do it until that next frame, as the order in which things are processed might be giving you this problem. – Confused Oct 27 '16 at 12:43
  • any idea as to how I would do this? I kinda understand your though but not entirely –  Oct 28 '16 at 20:33

0 Answers0