SKSpriteKit maintaining constant velocity after collision

I am attempting to make my first iOS app and currently running into an issue.

In my game, when the ball bounces I want it to bounce back to the same height and with the same velocity. Currently it does that just fine. However, when I rotate the hexagon and it hits an angle, it ends up losing speed and not bouncing to the same height.

  • Required background modes iOS6 Xcode 4.5
  • What does Main.1 output file do in XCode?
  • Swift converting a byte array to integers
  • Share Extension to open containing app
  • AVAudioSessionCategoryPlayAndRecord with Airplay
  • _cmd in Swift language
  • So my question is: How do I force the ball to maintain the same velocity upon collision?

    Here is the code for my Ball node:

    func createBallNode(ballColor: String) -> SKSpriteNode {
        let ball = SKSpriteNode(imageNamed: ballColor)
        ball.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)+30)
        ball.zPosition = 1
    
        ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width/2)
        ball.physicsBody?.affectedByGravity = true
        ball.physicsBody?.restitution = 1
        ball.physicsBody?.linearDamping = 0
        ball.physicsBody?.friction = 0
    
        ball.physicsBody?.categoryBitMask = ColliderType.Ball.rawValue
        ball.physicsBody?.contactTestBitMask = ColliderType.Rect.rawValue
        ball.physicsBody?.collisionBitMask = ColliderType.Rect.rawValue
    
        let centerX = ball.position.x
        let range = SKRange(lowerLimit: centerX, upperLimit: centerX)
    
        let constraint = SKConstraint.positionX(range)
        ball.constraints = [constraint]
    
        return ball
    }
    

    Below is a GIF explaining the problem in a visual form:
    enter image description here

    Solutions Collect From Internet About “SKSpriteKit maintaining constant velocity after collision”

    The issue is that if the ball collides at an angle, its total velocity is split between the vertical and horizontal components of the new velocity vector. Because you constrained the motion of the ball’s horizontal position, the horizontal velocity is lost and the ball doesn’t bounce as high.

    One possible solution is to override didSimulatePhysics in your scene, and check if the ball’s velocity is not sufficient to make it reach the desired height. If it isn’t, increase its velocity so it will.

    let neededVelocity = sqrt(2 * physicsWorld.gravity.dy * (intendedHeight - ball.posiiton.y))
    if ball.physicsBody.velocity.dy < neededVelocity && ball.physicsBody.velocity.dy > 0 {
        ball.physicsBody.velocity = CGVector(dx: 0, dy: neededVelocity)
    }