inVINCEable
inVINCEable

Reputation: 2206

Change direction not velocity in SpriteKit (swift)

In my game I have 2 sprites, A ball and a paddle. I'm trying to restrict the angle of reflection so that way it doesn't hit and go horizontal. I'm using this code to check the angle of contact:

            var impactX = contact.contactNormal.dx
            var impactY = contact.contactNormal.dy

            var radiansCon: Double = Double(atan((contact.contactNormal.dy / contact.contactNormal.dx)))
            var angleCon = Double(radiansCon * 180) / M_PI
            //println("Bounce Angle:\(angleCon)")

            if(angleCon < 60 && angleCon > 0) {
                println("Adjust angle Positive")
            } else if (angleCon > -60 && angleCon < 0) {
                println("Adjust angle Negative")
            }

How do I change the angle when the ball bounces without changing the velocity?

(I'm new to sprite kit so let me know if i am missing any details)

Upvotes: 1

Views: 977

Answers (3)

squarehippo10
squarehippo10

Reputation: 1945

Ray Wenderlich's Breakout tutorial has some helpful ideas. First, realize that if the ball is going too horizontal, the dx velocity has already changed - it's too low. In that case, give it a nudge in the x direction. The same is true if the dy velocity is too low - now it's bouncing from side to side and not getting anywhere so give it a nudge in the y direction. Finally, check the overall speed of the ball - if it's too high, slow it down. This example is in the didBegin method to adjust the ball as it bounces off the paddle:

// Get the absolute value of dx and dy
let dxSpeed = fabs(CGFloat((ball.physicsBody?.velocity.dx)!))
let dySpeed = fabs(CGFloat((ball.physicsBody?.velocity.dy)!))

let speed = sqrt(dxSpeed + dySpeed)

if dxSpeed <= 250.0 {
    ball.physicsBody?.applyImpulse(CGVector(dx: -20.0, dy: 0.0))
}

if dySpeed <= 250.0 {
    ball.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 20.0))
}

if speed > maxSpeed {
    ball.physicsBody?.linearDamping = 0.1
} else {
    ball.physicsBody?.linearDamping = 0.0   
}

Of course, the numbers will have to be adjusted based on the characteristics of your ball.

Upvotes: 1

inVINCEable
inVINCEable

Reputation: 2206

Probably not the best way to do it but it works for now:

            var impactX = contact.contactNormal.dx
            var impactY = contact.contactNormal.dy

            var radiansCon: Double = Double(atan((contact.contactNormal.dy / contact.contactNormal.dx)))
            var angleCon = Double(radiansCon * 180) / M_PI
            if(angleCon < 60 && angleCon > 0) {
                var newX = CGFloat(0.5)
                var newY = CGFloat(0.85)
                self.ball.body.applyImpulse(CGVectorMake(newX, newY))
            } else if (angleCon > -60 && angleCon < 0) {
                var newX = CGFloat(-0.5)
                var newY = CGFloat(0.85)
                self.ball.body.applyImpulse(CGVectorMake(newX, newY))
            }

Upvotes: 1

Christian
Christian

Reputation: 22353

You can use the zRotation property of your sprite and set a new angle:

yourBody.zRotation = yournewAngle

Upvotes: 0

Related Questions