1

I am currently trying to implement in SpriteKit that previously generated SpriteNodes bounce off a line drawn by the user. For this I need to give them a physicsbody so that the objects can collide. Does anyone have an idea how to implement this? Thanks a lot!

Here is the code block:

-- Update: Problem is solved! Working code in this question. --

func createLine() {
        let path = CGMutablePath()
        path.move(to: pathArray[0])
        
        for point in pathArray {
            path.addLine(to: point)
        }
        
        let line = SKShapeNode()       
        line.path = path
        line.fillColor = .clear
        line.lineWidth = 1
        line.zPosition = 3
        line.strokeColor = .cyan
        line.lineCap = .round
        line.glowWidth = 20
        
        line.physicsBody = SKPhysicsBody(polygonFrom: path)
        line.physicsBody?.affectedByGravity = false
        line.physicsBody?.isDynamic = true
        line.physicsBody?.categoryBitMask = CollisionTypes.line.rawValue
        line.physicsBody?.contactTestBitMask = CollisionTypes.atom.rawValue
        
        self.addChild(line)
        
        let wait = SKAction .wait(forDuration: 1.5)
        
        let fade:SKAction = SKAction.fadeOut(withDuration: 1)
        fade.timingMode = .easeIn
        let remove: SKAction = SKAction.removeFromParent()
        
        line.run(SKAction.sequence([wait, fade, remove]))
        
    }

ContactDelegate:

let contactA:SKPhysicsBody = contact.bodyA
let contactB:SKPhysicsBody = contact.bodyB
        
let nodeA = contactA.node
let nodeB = contactB.node
        
        
if contactA.categoryBitMask == 2 || contactB.categoryBitMask == 2 {
      print("line hit")
}
chickenbox
  • 25
  • 6
  • 1
    You need to create a specific type of physics body, e.g., the constructor shouldn't be `SKPhysicsBody()` but `SKPhysicsBody(...)`, with the `...` something that specifies the type of shape. See https://developer.apple.com/documentation/spritekit/sknode/getting_started_with_physics_bodies – bg2b Apr 08 '21 at 09:12

2 Answers2

0

There are different types of physics body (circular, rectanglular, polygonal, alpha mask, edge based). For CGMutablePath, you want to create a chain from a path. To implement it, replace this line:

line.physicsBody? = SKPhysicsBody()

With this:

line.physicsBody = SKPhysicsBody(edgeChainFrom: path)
JohnL
  • 570
  • 1
  • 5
  • 10
  • Yes, that was very good. Unfortunately, the ContactDelegate still does not recognize the line... So in the func createLine() I inserted this line: line.physicsBody?.categoryBitMask = CollisionTypes.line.rawValue. In didBegin the line is still not detected... (of course i added the enum with uint32 and more stuff) – chickenbox Apr 09 '21 at 14:58
  • Ok. Use showsPhysics = true so you can see the physics bodies you are dealing with (it will reassure you they are there and right shape). Make sure then categoryBitMask and collisionBitMask are set up on the line shapenode and the spritenodes. Ideally you should update the question with these items in. – JohnL Apr 09 '21 at 16:57
  • Alright, I added some new information to my post. Adding showsPhysics was definitely good. – chickenbox Apr 10 '21 at 05:16
  • Ok thanks. So the physics body is still not created, even using "polygonFrom: path"? On first glance, in your original post, its missing the atoms categoryBitMask and setting of physicsbody, and the ContactDelegate doesn't seem right. Do the atoms show correctly after you added showPhysics = true? – JohnL Apr 10 '21 at 10:14
  • Yes, the atoms indicate a correct physicsbody. The problem with the Contact Delegate would be next, because I don't know how to detect if a SKSpriteNode and a SKShapeNode have collided into each other. But first I have to make it so that the line gets a physicsbody... – chickenbox Apr 10 '21 at 13:35
  • See updated answer, i removed the ? after physicsBody as that stopped the physics body being created. Also changed the physics body type, as you want a line rather than create a polygonal shape. – JohnL Apr 10 '21 at 14:46
  • No way, this little questionmark solved my problem :) now the question is how can I detect a collision? – chickenbox Apr 10 '21 at 16:27
  • I just solved it myself. I am so happy right now :)) Now I will correct the code which worked for me in the question. Thank you so much for your great help!! – chickenbox Apr 10 '21 at 16:34
  • Ok great. As an FYI, by default everything will collide with everything. If you need to fine tune which nodes collide with which, you need to start setting the collisionBitMasks on the physicsbodys. Good luck. – JohnL Apr 10 '21 at 16:50
0

The working code is above in the question.

chickenbox
  • 25
  • 6