How to create a physics body for an SKSpriteNode with an interior in Sprite Kit (Swift)

I am currently making an iOS game in which a ball must bounce within a frame defined by the below image:

enter image description here

The game relies on the below method to automatically create and assign a physics body to the frame surrounding the game.

frame.physicsBody = SKPhysicsBody(texture: frameTexture, size: frame.size)

This code, however, assigns a body that encompasses the outside of the image, rather than the interior, and thus treats the blank interior as a solid object. This, in turn, means that the ball cannot be inside the frame and is forced off the screen immediately after being spawned.

Is there any way to give a physics body an interior?

Another post here: SpriteKit SKPhysicsBody with Inner Edges aims to do something similar, but does not involve automatic wrapping around a texture (hence the new question)

1 answer

  • answered 2018-01-13 19:59 Imrul Kayes

    You can use init(edgeLoopFrom:) initializer to achieve inner edge friction. you can use this code below:

     override func didMove(to view: SKView) {
        //Setup scene's physics body (setup the walls)
        physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
        let back = SKSpriteNode(imageNamed: "1")
        back.position = CGPoint(x: frame.midX, y: frame.midY)
        back.size = CGSize(width: 500, height: 600)
        back.zPosition = -3
        let rect = CGRect(origin: CGPoint(x: -back.size.width/2, y: -back.size.height/2), size: back.size)
        back.physicsBody = SKPhysicsBody(edgeLoopFrom: rect)
        //Add Red ball "inside" the back sprite
        let red = SKShapeNode(circleOfRadius: 20)
        red.fillColor = .red
        red.strokeColor = .clear
        red.position = back.position
        red.physicsBody = SKPhysicsBody(circleOfRadius: 20)
        red.physicsBody?.restitution = 1
        red.physicsBody?.friction = 0
        red.zPosition = 1
        red.physicsBody?.affectedByGravity = false
        red.physicsBody?.applyImpulse(CGVector(dx: 20, dy: 15))

    please follow this Question and have a look to the answer given below.

    i am providing a screenshot of my project here