Swift SpriteKit edgeLoopFromRect Issue

610 views Asked by At

The following code recognizes the bottom and top edges of the scene and the ball bounces off as expected. However, the left and right edges of the scene are breached all the time. The ball goes off screen and then eventually returns back if enough force is applied. It is as if the edges of the scene are beyond the edges of the iphone simulator window.

import SpriteKit

class GameScene: SKScene {
    override func didMoveToView(view: SKView){
        self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        backgroundColor = UIColor.cyanColor()
        var ball = SKSpriteNode(imageNamed: "ball")
        ball.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
        self.addChild(ball)
        ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.size.height/2)
        let push = CGVectorMake(10, 10)
        ball.physicsBody.applyImpulse(push)

    }
}

I think it has something to do with the .sks file since dimensions are set there and if I change those dimensions it reflects on the game. Anyone know how to make it so this line of code takes precedence over the .sks file dimensions? This way it will be dynamic and could work on different devices.

self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)

I found the same question here but was never answered: Swift physicsbody edge recognition issue

Also, I am new to iOS app dev and swift so forgive me if the answer is obvious and I missed it.

1

There are 1 answers

2
Whirlwind On BEST ANSWER

You are probably on the right track about .sks file. When scene is loaded from the .sks file the default size is 1024x768. Now you can dynamically set that based on the view size. So, swap your viewDidLoad with viewWillLayoutSubviews like this:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    if let scene = GameScene(fileNamed:"GameScene") {
        // Configure the view.
        let skView = self.view as! SKView
        skView.showsFPS = true
        skView.showsNodeCount = true

        /* Sprite Kit applies additional optimizations to improve rendering performance */
        skView.ignoresSiblingOrder = true

        //Because viewWillLayoutSubviews might be called multiple times, check if scene is already initialized
         if(skView.scene == nil){

            /* Set the scale mode to scale to fit the window */
            scene.scaleMode = .AspectFill
            scene.size = skView.bounds.size

            skView.presentScene(scene)
        }
    }
}

There are many posts on SO about differences between viewDidLoad and viewWillLayoutSubviews, so I will skip that in my answer.

Hope this helps.