2

I am building my first sprite kit game, and recently read an article that said to use SKTextureAtlas to improve performance.

So I migrated all my sprite images into organized .atlas folders and updated the code accordingly. However, now my sprites have weird physics bodies (mainly over-enlarged).

For instance, my player sprite has three states: Flying (flat), Flying Up and Flying Down. The three images are pretty similar, with slight variations (arms pointing flat, up, down).

Before migrating to texture atlases, the physics body was pretty spot on with the image. Now however, it is much larger than the image and slightly stretched on the y-axis.

Here is my player.atlas file structure:

player-flying-iphone.atlas:

  • player-flying-down@2x.png
  • player-flying-down@3x.png
  • player-flying-up@2x.png
  • player-flying-up@3x.png
  • player-flying@2x.png
  • player-flying@3x.png

Here is an example of my code: (Player is a subclassed SKSpriteNode)

let textureAtlas = SKTextureAtlas(named: "player-iphone")
let playerFlyingTexture = textureAtlas.textureNamed("player-flying")
let player = Player(texture: playerFlyingTexture, color: UIColor.clearColor(), size: CGSizeMake(100.0, 100.0))

let physicsBody = SKPhysicsBody(texture: playerFlyingTexture, size: CGSizeMake(100.0, 100.0))
physicsBody.dynamic = true
physicsBody.affectedByGravity = true
physicsBody.usesPreciseCollisionDetection = false
physicsBody.categoryBitMask = CollisionCategories.Player
physicsBody.contactTestBitMask = CollisionCategories.Enemy
physicsBody.collisionBitMask = CollisionCategories.EdgeBody
physicsBody.allowsRotation = false
player.physicsBody = physicsBody
JimmyJammed
  • 9,598
  • 19
  • 79
  • 146
  • Although you got an answer already I would suggest to use Xcode asset catalogue for SKtextures. As of Xcode 7 you can use the assets catalogue for texture images and Apple actually says it's the best way to do so. I therefore think these articles that talk about .atlas folders are outdated. – crashoverride777 Apr 16 '16 at 16:11

3 Answers3

4

(credit goes to @Whirlwind for the help)

So for me, the fix ended up being that I need to change this:

let physicsBody = SKPhysicsBody(texture: self.texture, size: self.size)

..to this..

let physicsBody = SKPhysicsBody(texture: self.texture, alphaThreshold: 0.3, size: self.size)

Apparently, the SKTextureAtlas cropping method used when generating a physics body has issues figuring out exactly what to crop, so setting the alphaThreshold explicitly seemed to fix it.

Obviously, that value will rely on your own image and what kind of transparency you have. But if you have hard edges like I did, you should be able to set that to some arbitrary value and be good to go.

JimmyJammed
  • 9,598
  • 19
  • 79
  • 146
1

You are setting your texture size like this:

CGSize(widht:100, height:100)

which are obviously not the right dimensions of your texture.

Instead use the real texture size:

yourTexture.size()

Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • I updated the code, and now I get this error when it tries to create the physics body: PhysicsBody: Could not create physics body. – JimmyJammed Apr 13 '16 at 20:46
  • @NitWitStudios Can you show what code do you use (the updated code which produces the error)? Also, that error is not so descriptive. Can you please copy the whole error. – Whirlwind Apr 13 '16 at 20:47
  • That is the whole error.. Here is the updated code: let flyingTextureAtlas = SKTextureAtlas(named: "player-flying-iphone") let texture = self.flyingTextureAtlas.textureNamed("player-flying") let player = Player(texture: texture, color: SKColor.clearColor(), size: texture.size()) let physicsBody = SKPhysicsBody(texture: texture, size: texture.size()) player.physicsBody = physicsBody – JimmyJammed Apr 13 '16 at 20:56
  • Also, the image shows up just fine, so I know its not an issue with loading the image. And like I said in the original post, before moving to texture atlases, everything worked pretty well, including the physics bodies for these same exact images. So I know its not because the image is too complex. – JimmyJammed Apr 13 '16 at 20:57
  • @NitWitStudios That is odd. What you get if you print texture.size() ? Also you should consider updating your original question when you adding the new code. Pasting it in the comments is not readable and it is not that useful for future readers. – Whirlwind Apr 13 '16 at 21:00
  • @NitWitStudios Try one more thing (actually two). Delete Simulator content and settings and try again. Also, try to re-add atlas to your game (delete atlas, clean the project, re-add atlas). By the way, are you using .atlas folder, or you are creating an atlas in a new way (using assets catalog) ? – Whirlwind Apr 13 '16 at 21:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109088/discussion-between-nitwit-studios-and-whirlwind). – JimmyJammed Apr 13 '16 at 21:04
0

This problem exists on iPad 3 (iOS 9.3.5 & xcode 8.1) and in my situation, alphaThreshold didn't solve the issue with incorrect PhysicsBody.

I had to switch to "New Sprite Atlas" instead of "Texture Atlas", which magically fixed the issue.

ZippyMind
  • 141
  • 2
  • 9