Jimmy Lee - 1 year ago 103
Swift Question

SKSpriteNode losing velocity upon collision

I am making an iOS app and running into some problems with physics. As you can tell by the .GIF below, when I rotate the hexagon and the ball hits the rectangle at an angle, it loses some of its velocity and doesn't bounce as high. This is because of the reason shared here (basically because I am constraining the balls horizontal position, it's only using the vertical velocity when hitting an angle, thus losing speed).

I cannot for the life of me figure out a solution to fix this problem. Does anybody have any ideas??

Code for 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?.affectedByGravity = true
ball.physicsBody?.restitution = 1
ball.physicsBody?.linearDamping = 0
ball.physicsBody?.friction = 0

let centerX = ball.position.x
let range = SKRange(lowerLimit: centerX, upperLimit: centerX)

let constraint = SKConstraint.positionX(range)
ball.constraints = [constraint]

return ball
}
``````

Yes, the problem is probably causes by the ball hitting the hexagon when it is not perfectly "aligned". In this case the ball loses vertical speed in favour of the horizontal axis.

Since you want a "discrete logic" I believe in this scenario your should avoid physics (at least for the bouncing part). It would be much easier repeating an `SKAction` that moves the ball vertically.

Example

I prepared a simple example

``````class GameScene: SKScene {

override func didMove(to view: SKView) {
super.didMove(to: view)
let ball = createBallNode()
}

func createBallNode() -> SKSpriteNode {
let ball = SKSpriteNode(imageNamed: "ball")
ball.position = CGPoint(x: frame.midX, y: frame.minY + ball.frame.height / 2)

let goUp = SKAction.move(by: CGVector(dx: 0, dy: 600), duration: 1)
goUp.timingMode = .easeOut

let goDown = SKAction.move(by: CGVector(dx: 0, dy: -600), duration: 1)
goDown.timingMode = .easeIn

let goUpAndDown = SKAction.sequence([goUp, goDown])
let forever = SKAction.repeatForever(goUpAndDown)
ball.run(forever)
return ball
}
}
``````

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download