Swift + Física: cálculo de ángulo incorrecto en colisión

Tengo un simpleSpriteKit Aplicación con paredes y una pelota. Ambos configurados con unSKPhysicsBody.

Cuando aplico una fuerza en una dirección, espero que la pelota se refleje en la pared con el mismo ángulo cuando choca pero en dirección opuesta.

Pero a veces veo que el ángulo es extraño. Jugué mucho con todos losphysicsBody propiedades, pero no pudo solucionarlo. A veces, las primeras reflexiones se ven bien, pero luego la tercera o sexta y, a veces, la primera reflexión está en ángulo incorrecto.

Leí en diferentes publicaciones, la gente está calculando un poco la "dirección correcta". Pero no puedo imaginarSpriteKits El motor físico no es capaz de hacerlo.

Comprueba mi imagen adjunta para entender a qué me refiero. ¿Alguien puede ayudar en esto? No quiero comenzar a jugar con Box2d para Swift, ya que parece que será demasiado difícil para mí integrarme en Swift.

Este es elphysicsWorld init en mi archivo GameScene.swift donde se agregan todos mis elementos a:

self.physicsWorld.gravity = CGVectorMake(0, 0)

Agregar todo mi código sería demasiado, así que agrego las piezas importantes. Espero que sea suficiente para analizar. Todos los elementos como la pelota, las paredes sonSKSpriteNode's

Este es elphysicsBody código para la pelota:

self.physicsBody = SKPhysicsBody(circleOfRadius: Constants.Config.playersize+self.node.lineWidth)
self.physicsBody?.restitution = 1
self.physicsBody?.friction = 0
self.physicsBody?.linearDamping = 1
self.physicsBody?.allowsRotation = false
self.physicsBody?.categoryBitMask = Constants.Config.PhysicsCategory.Player
self.physicsBody?.collisionBitMask = Constants.Config.PhysicsCategory.Wall | Constants.Config.PhysicsCategory.Enemy
self.physicsBody?.contactTestBitMask = Constants.Config.PhysicsCategory.Wall | Constants.Config.PhysicsCategory.Enemy

Este es el cuerpo físico para las paredes:

el = SKSpriteNode(color: UIColor.blueColor(), size: CGSize(width: Constants.Config.wallsize, height: Constants.Config.wallsize))
el.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: Constants.Config.wallsize, height: Constants.Config.wallsize))
el.physicsBody?.dynamic = false
el.physicsBody?.categoryBitMask = Constants.Config.PhysicsCategory.Wall
el.physicsBody?.collisionBitMask = Constants.Config.PhysicsCategory.Player
el.physicsBody?.contactTestBitMask = Constants.Config.PhysicsCategory.Player

Al final solo llamo a la función applyImpulse en las bolasphysicsBody para que se mueva en la simulación física.

También revise mi segunda imagen adjunta / gif. Muestra el problema de colisión de borde con una aplicación simple de skphysics sin ninguna parametrización especial. solo un rectángulo con una bola y un vector aplicado como impulso.

Aquí está mi completono funciona código usando la solución de appzYourLife.

class GameScene: SKScene {
private var ball:SKShapeNode!
override func didMoveToView(view: SKView) {
    let screen = UIScreen.mainScreen().bounds
    let p = UIBezierPath()
    p.moveToPoint(CGPointMake(0,0))
    p.addLineToPoint(CGPointMake(screen.width,0))
    p.addLineToPoint(CGPointMake(screen.width, screen.height))
    p.addLineToPoint(CGPointMake(0,screen.height))
    p.closePath()
    let shape = SKShapeNode(path: p.CGPath)
    shape.physicsBody = SKPhysicsBody(edgeLoopFromPath: p.CGPath)
    shape.physicsBody?.affectedByGravity = false
    shape.physicsBody?.dynamic = false
    shape.strokeColor = UIColor.blackColor()

    self.addChild(shape)

    ball = SKShapeNode(circleOfRadius: 17)
    ball.name = "player"
    ball.position = CGPoint(x: 20, y: 20)
    ball.fillColor = UIColor.yellowColor()
    ball.physicsBody = SKPhysicsBody(circleOfRadius: 17)
    ball.physicsBody?.angularDamping = 0
    ball.physicsBody?.linearDamping = 0
    ball.physicsBody?.restitution = 1
    ball.physicsBody?.friction = 0
    ball.physicsBody?.allowsRotation = false

    self.addChild(ball)
    self.ball.physicsBody?.applyImpulse(CGVector(dx: 2.4, dy: 9.7))
}

Me acabo de dar cuenta de que la masa y la densidad de mi sprite de bola es nula. ¿Por qué eso? Incluso configurarlo se mantiene en cero.

Respuestas a la pregunta(2)

Su respuesta a la pregunta