1

In my original build, my sprites were static, so to make the collision physics as accurate as I could rather than use rectangleOfSize for SKPhysicsBody passing in the node, I used this tool to define a path SpriteKit's SKPhysicsBody with polygon helper tool.

However now I'm animating the sprites so that they move back and forth during gameplay (obviously my physics path remains static given the above) so my physicsbody no longer matches what the player sees on screen.

The helper tool seemed like a bit of hack that Apple would eventually fix in the API, has there been anything recent in SpriteKit that would help me out here so that I can pass in the node and define a precise physicsbody rather than the hard-coded approach? If not, any other alternatives?

Community
  • 1
  • 1
GarySabo
  • 5,806
  • 5
  • 49
  • 124
  • Just use the texture to make what you need, I am almost positive you can extract the path from the body after it is generated. SKPhysicsBody(texture:.... – Knight0fDragon Oct 05 '16 at 17:32
  • Can you elaborate? Other than hard coding in the path for each frame of the animation, how can I create an SKPhysicsBody that matches the shape of the asset? – GarySabo Oct 05 '16 at 20:01
  • you have to hard code in the path for each animation, there is no way around that, SKPhysicsBody does not care about what a texture looks like, so you need to tell it the body something has changed when the texture changed. – Knight0fDragon Oct 05 '16 at 20:03
  • Ok, yeah that's really my question how do I get around hard coding the path for each texture, just seems like programmatically this should be achievable? Maybe eventually – GarySabo Oct 05 '16 at 20:06

1 Answers1

2

Not sure how performant this is but you can pre-generate the physics bodies for each texture then animate the sprite along with its physicsBody using a custom action.

Here is an example:

func testAnimation() {

    var frameTextures = [SKTexture]()
    var physicsBodies = [SKPhysicsBody]()

    for index in 1...8 {
        // The animation has 8 frames
        let texture = SKTexture(imageNamed: "guy\(index)")
        frameTextures.append(texture)
        let physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
        physicsBody.affectedByGravity = false
        physicsBodies.append(physicsBody)
    }

    let sprite = SKSpriteNode(texture: frameTextures[0])
    let framesPerSecond = 16.0
    let animation = SKAction.customAction(withDuration: 1.0, actionBlock: { node, time in
        let index = Int((framesPerSecond * Double(time))) % frameTextures.count
        if let spriteNode = node as? SKSpriteNode {
            spriteNode.texture = frameTextures[index]
            spriteNode.physicsBody = physicsBodies[index]
        }
    })

    sprite.run(SKAction.repeatForever(animation));
    sprite.position = CGPoint(x: 0, y: 0)

    addChild(sprite)

}
mikeytdan
  • 254
  • 2
  • 8
  • Thanks but my question wasn't how to update the physics body, it was how to get around hard coding a path for every frame of every asset's animation in my game...from @KnightOfDragon 's comment it sounds like there isn't another way... – GarySabo Oct 05 '16 at 20:07
  • The bottom of my post mentions that you can use the `SKPhysicsBody(texture: texture!, size: texture!.size)` method to generate the physicsbody for each frame – mikeytdan Oct 05 '16 at 20:39
  • Thanks @mikeytdan I misunderstood originally, I will give a try! – GarySabo Oct 05 '16 at 20:46
  • @GarySabo this is what I was trying referring to, I thought it was SKPhysicsBody you could get the path from, but it was shape – Knight0fDragon Oct 06 '16 at 04:08