SpriteKit: использование SKTextureAtlas вызывает некорректное физическое тело

Я создаю свою первую игру для набора спрайтов и недавно прочитал статью, в которой говорится, что для повышения производительности используется SKTextureAtlas.

Поэтому я перенес все свои спрайт-изображения в .atlas папки и обновили код соответственно. Однако, теперь у моих спрайтов есть странные физические тела (в основном чрезмерно увеличенные).

Например, мой спрайт игрока имеет три состояния: Полет (плоский), Полет вверх и Полет вниз. Три изображения очень похожи, с небольшими вариациями (руки направлены вверх, вниз).

Прежде чем перейти к атласу текстур, физическое тело было на месте изображения. Однако теперь он намного больше, чем изображение, и немного растянут по оси Y.

Вот моя файловая структура player.atlas:

игрок-летно-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

Вот пример моего кода:(Player является подклассом 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

3 ответа

Решение

(кредит @Whirlwind за помощь)

Так что для меня исправление закончилось тем, что мне нужно изменить это:

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

..к этому..

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

По-видимому, метод обрезки SKTextureAtlas, используемый при создании физического тела, имеет проблемы с определением, что именно нужно обрезать, поэтому установка alphaThreshold явно исправила его.

Очевидно, что это значение будет зависеть от вашего собственного изображения и того, какая у вас прозрачность. Но если у вас есть острые грани, как у меня, вы должны быть в состоянии установить для этого произвольное значение и быть готовым к работе.

Вы устанавливаете свой размер текстуры следующим образом:

CGSize(widht:100, height:100)

которые явно не являются правильными размерами вашей текстуры.

Вместо этого используйте реальный размер текстуры:

yourTexture.size()

Эта проблема существует на iPad 3 (iOS 9.3.5 и xcode 8.1), и в моей ситуации alphaThreshold не решил проблему с неверной PhysicsBody.

Мне пришлось переключиться на "Новый атлас спрайтов" вместо "Атласа текстуры", что волшебным образом решило проблему.

Другие вопросы по тегам