Доброго времени суток,
У меня проблема, которая появилась в игре, которую я написал для своих детей. После некоторого расследования я "обнаружил" следующую проблему:
В оригинальной игре спрайты загружаются через
let sprite = SKSpriteNode(texture: atlas!.textureNamed("something")
Используемый текстурный атлас содержит большое количество мелких текстур, «изображений». Это приводит к работающей и счастливой игре на старых устройствах, iPhone 7, iPad Air, iPad Pro 12,9 дюйма. Однако на iPhone X и т. д., А также на симуляторе iPhone X любые изображения, загруженные из атласа, отображаются либо в виде крошечных точек, либо вообще не отображаются. Нет ошибок компилятора и ошибок времени выполнения. Я предполагаю, что это как-то связано с разрешением экрана, но что? Если я загружаю изображения через init (imageNamed: "something"), вызываю себя, одни и те же изображения правильно масштабируются и отображаются. Я создал небольшую автономную программу, которая иллюстрирует эту проблему, код ниже: Я также включил два снимка экрана, показывающие тот же самый код, загруженный и работающий на iPad и iPhone Xsmax. Изображение iPad показывает две платформы и кроликов, в то время как изображение iPhone показывает их отсутствие.
Два файла атласа содержат платформу и изображения GEM и кролика, первый атлас также содержит в общей сложности около 90 небольших изображений. Как видите, первые изображения атласа загружены неправильно, однако, если я уменьшу количество изображений, содержащихся ниже, примерно на 30 изображений, все будет работать. Да, и компилятор тоже не жалуется и не разбивает файлы атласа. Итак, я полагаю, последний вопрос состоит из двух частей:
1 Что на самом деле происходит?
2 Как исправить?
Код выглядит следующим образом:
//
// GameScene.swift
// SpriteTest
//
//
import SpriteKit
class GameScene: SKScene {
let player = SKSpriteNode(imageNamed: "player")
var atlas :SKTextureAtlas?
var atlas2 :SKTextureAtlas?
var tile : SKNode?
var tile2 : SKNode?
override func didMove(to view: SKView) {
// White background for visibility
backgroundColor = SKColor.white
player.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
addChild(player)
// first platform "does not appear on iPhone X"
atlas = SKTextureAtlas(named: "Tiles")
tile = SKSpriteNode(texture: atlas!.textureNamed("platform"))
tile?.zPosition = 50
tile?.physicsBody?.isDynamic = true
tile?.physicsBody?.affectedByGravity = false
tile?.position = CGPoint(x: size.width * 0.1, y : size.height * 0.2)
addChild(tile!)
atlas2 = SKTextureAtlas(named: "Smallatlas")
// Second platform always appears
tile2 = SKSpriteNode(texture: atlas2!.textureNamed("platform"))
tile2?.zPosition = 50
tile2?.physicsBody?.isDynamic = true
tile2?.physicsBody?.affectedByGravity = false
tile2?.position = CGPoint(x: size.width * 0.6, y : size.height * 0.2)
addChild(tile2!)
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(addMonster),
SKAction.wait(forDuration: 1.0)
])
))
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
func addMonster() {
// First monster "bunny" does not appear on iPhone X
let monster = SKSpriteNode(texture: atlas!.textureNamed("chocolate-bunny150"))
// Determine where to spawn the monster along the Y axis
let actualY = random(min: monster.size.height/2, max: size.height - monster.size.height/2)
// Position the monster slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
monster.position = CGPoint(x: size.width + monster.size.width/2, y: actualY)
// Add the monster to the scene
addChild(monster)
// Determine speed of the monster
let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
// Create the actions
let actionMove = SKAction.move(to: CGPoint(x: -monster.size.width/2, y: actualY),
duration: TimeInterval(actualDuration))
let actionMoveDone = SKAction.removeFromParent()
monster.run(SKAction.sequence([actionMove, actionMoveDone]))
addMonster2()
}
func addMonster2() {
// Second monster always appears
let monster2 = SKSpriteNode(texture: atlas2!.textureNamed("gem"))
// Determine where to spawn the monster along the Y axis
let actualY = random(min: monster2.size.height/2, max: size.height - monster2.size.height/2)
// Position the monster slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
monster2.position = CGPoint(x: size.width + monster2.size.width/2, y: actualY)
// Add the monster to the scene
addChild(monster2)
// Determine speed of the monster
let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
// Create the actions
let actionMove = SKAction.move(to: CGPoint(x: -monster2.size.width/2, y: actualY),
duration: TimeInterval(actualDuration))
let actionMoveDone = SKAction.removeFromParent()
monster2.run(SKAction.sequence([actionMove, actionMoveDone]))
}
}
1. Вы создаете свои атласы, используя .atlas в пакете проекта или используя спрайтатлас в каталоге ресурсов. 2. Изображения в формате PNG или JPG? 3. Если в атласе менее 30 изображений, они правильно отображаются и масштабируются на iPhone X?
1. Я использую .atlas в комплекте (это более старый проект). 2 Все изображения в формате PNG. 3 Я не уверен, является ли ограничение на количество изображений или общий размер, я проведу несколько экспериментов и обновлю.
Хорошо, мне не удалось воссоздать вашу проблему с вашим кодом, поэтому я в тупике. Раньше я обнаруживал, что даже если атлас автоматически разделяется на два (с предупреждением), он все равно отображает анимацию нормально. Также я использовал 150 довольно больших изображений в атласе, и он обрабатывается без проблем.
Почему tile1 и tile2 используют одно и то же имя изображения, но из разных атласов? Полагаю, это не опечатка. Я почти уверен, что где-то читал, что в двух разных атласах не должно быть одного и того же имени изображения. Почему бы обеим платформам не ссылаться на одну и ту же текстуру из одного атласа?





Приходите туда к кому-нибудь, кто может помочь?