Search code examples
swiftsprite-kitskphysicsbody

Physics issue: ball is bouncing too high


I am working on game where a ball bounces and hits a platform and then bounces right back. Ideally the ball should bounce to exactly the height that it started at. However, in my game the ball slowly keeps bouncing higher and higher. I've looked at the documentation and tried to change all of the physics properties but nothing seems to work.

Any suggestions?

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    let ballCategory:UInt32 = 0x1 << 0;
    let circleCategory:UInt32 = 0x1 << 1;
    let platformCategory:UInt32 = 0x1 << 2;

    var ball = SKShapeNode(circleOfRadius: 20.0)
    var circle = SKShapeNode(circleOfRadius: 200.0)
    var platform = SKShapeNode(rectOfSize: CGSizeMake(10, 1))

    var circleColor = 2
    var ballColor = 3

    var scoreLabel: SKLabelNode!
    var score = 0

    override func didMoveToView(view: SKView) {

        setUpLabels()

        self.physicsWorld.contactDelegate = self

        backgroundColor = (UIColor.whiteColor())
        ball.fillColor = SKColor.redColor()
        ball.strokeColor = SKColor.clearColor()
        ball.position = CGPoint(x: self.size.width/2, y: self.size.height/2+60)

        ball.physicsBody = SKPhysicsBody(circleOfRadius: 20)
        ball.physicsBody?.categoryBitMask = ballCategory
        ball.physicsBody?.collisionBitMask = platformCategory
        ball.physicsBody?.contactTestBitMask = platformCategory
        ball.physicsBody?.dynamic = true
        ball.physicsBody?.restitution = 1.0
        ball.physicsBody?.affectedByGravity = true
        ball.physicsBody?.linearDamping = 0.0
        ball.physicsBody?.friction = 0.0


        self.addChild(ball)


        circle.fillColor = SKColor.clearColor()
        circle.strokeColor = SKColor.redColor()
        circle.lineWidth = 5.0
        circle.position = CGPoint(x: self.size.width/2, y: self.size.height/2)

        circle.physicsBody = SKPhysicsBody(edgeLoopFromPath: circle.path)
        circle.physicsBody?.categoryBitMask = circleCategory

        self.addChild(circle)


        platform.fillColor = SKColor.clearColor()
        platform.strokeColor = SKColor.clearColor()
        platform.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(10, 1))
        platform.position = CGPoint(x: self.size.width/2, y: circle.position.y/2)
        platform.physicsBody?.categoryBitMask = platformCategory
        platform.physicsBody?.dynamic = false
        platform.physicsBody?.friction = 0.0


        self.addChild(platform)
    }

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {


        circleColor += 1

        if circleColor%3  == 1 {

            circle.strokeColor = UIColor.redColor()
        }

        if circleColor%3  == 2 {

            circle.strokeColor = UIColor.greenColor()
        }

        if circleColor%3  == 3 {

            circle.strokeColor = UIColor.yellowColor()
        }

        if circleColor%3  == 4 {

            circle.strokeColor = UIColor.greenColor()
        }

        if circleColor%3  == 5 {

            circle.strokeColor = UIColor.blueColor()
        }
        if circleColor%3  == 0 {

            circle.strokeColor = UIColor.yellowColor()
        }


    }


    func didBeginContact(contact: SKPhysicsContact) {

        if ball.fillColor == circle.strokeColor {
            score += 1
            scoreLabel.text = String("Score \(score)")
        }


        if ball.fillColor != circle.strokeColor {
            let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)

            let scene = SecondScene(size: self.scene!.size)
            scene.scaleMode = SKSceneScaleMode.AspectFill


            self.scene!.view!.presentScene(scene, transition: transition)
        }



        ballColor = Int(arc4random_uniform(10))


        if ballColor%3  == 1 {

            ball.fillColor = UIColor.redColor()
        }

        if ballColor%3  == 2 {

            ball.fillColor  = UIColor.greenColor()
        }

        if ballColor%3  == 3 {

            ball.fillColor  = UIColor.yellowColor()
        }

        if ballColor%3  == 4 {

            ball.fillColor  = UIColor.greenColor()
        }

        if ballColor%3  == 5 {

            ball.fillColor  = UIColor.blueColor()
        }
        if ballColor%3  == 0 {

            ball.fillColor  = UIColor.yellowColor()
        }


    }

    func setUpLabels () {

        scoreLabel = SKLabelNode(fontNamed: "Arial")
        scoreLabel.position = CGPoint(x: 60, y: self.size.height-30)
        scoreLabel.text = String("Score \(score)")
        scoreLabel.fontColor = UIColor.blackColor()
        scoreLabel.fontSize = 25
        self.addChild(scoreLabel)


    }

    override func update(currentTime: CFTimeInterval) {

    }
}

Solution

  • Reduce restitution a little which take control of the bounciness of the physics body. Like this:

    ball.physicsBody?.restitution = 0.9