SpriteKit physics in Swift - Ball slides against wall instead of reflecting

后端 未结 6 570
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-01 12:36

I have been creating my own very simple test game based on Breakout while learning SpriteKit (using iOS Games by Tutorials by Ray Wenderlich et al.) to see if I can apply co

6条回答
  •  悲&欢浪女
    2020-12-01 13:20

    I came up with a temporary solution that is working surprisingly well. Simply apply a very small impulse opposite of the border. You may need to change the strength based on the masses in your system.

    func didBeginContact(contact: SKPhysicsContact) {
    
        let otherNode = contact.bodyA.node == ball.sprite ? contact.bodyB.node : contact.bodyA.node
    
        if let obstacle = otherNode as? Obstacle {
            ball.onCollision(obstacle)
        }
        else if let border = otherNode as? SKSpriteNode {
    
            assert(border.name == "border", "Bad assumption")
    
            let strength = 1.0 * (ball.sprite.position.x < frame.width / 2 ? 1 : -1)
            let body = ball.sprite.physicsBody!
            body.applyImpulse(CGVector(dx: strength, dy: 0))
        }
    }
    

    In reality, this should not be necessary, since as described in the question, frictionless, fully elastic collision dictates that the ball should rebound by inverting the x velocity (assuming side borders) no matter how small the collision angle is.

    Instead, what is happening in the game is as if sprite kit ignores the X velocity if it is smaller than a certain value, making the ball slide against the wall without rebound.

    Final Note

    After reading this and this, it's obvious to me that the real answer is for any serious physics game you have, you should be using Box2D instead. You get way too many perks from the migration.

提交回复
热议问题