Spritekit – ne pas charger les images @ 3x de SKTextureAtlas

Puisque mon projet d'échantillon a été supprimé (je pensais que ce serait beaucoup plus facile à tester), je vais postr du code et des images pour illustrer mon propos.

Voici des exemples d'images

2x image

mon image 3x

Mon installation de l'atlas:

entrez la description de l'image ici

Ma configuration de l'image de lancement:

entrez la description de l'image ici

Le code où j'ajoute ces sprites à ma scène

override func didMoveToView(view: SKView) { let texture = SKTextureAtlas(named: "scenery") let test = SKSpriteNode(texture: texture.textureNamed("test")) test.position = CGPoint(x: self.size.width/2, y: self.size.height/2) self.addChild(test) } 

Ce sont mes résultats:

Simulateur iPhone 5:

entrez la description de l'image ici

iPhone 6 plus simulateur:

entrez la description de l'image ici

J'ai essayé de changer l'image de lancement pour utiliser le catalogue d'actifs. Alors l'iPhone 6 plus semble upscale un écran 2x. Il charge toujours l'image 2x, mais l'agrandit.

J'en ai besoin pour charger mon image 3x et être à l'échelle avec mon image 2x.

La réponse de Gabuh ci-dessous m'a indiqué la bonne direction. Fonctionne sur un nouveau projet. Cependant, si j'utilise sa solution pour mon vrai projet SpriteKit, mes images 3x ne sont pas mises à l'échelle. Ils sont 3 fois plus gros qu'ils ne devraient l'être.

Cela semble être un bug quand Xcode génère l'atlas compilé. Si vous vérifiez dans le package de votre application compilée, vous verrez que Xcode ne crée pas les noms d'atlas corrects pour les images @ 3x.

J'ai réussi à get les assets @ 3x en créant des atlas avec le nom @ 3x, et en laissant l'image sans le suffixe.

Et vous pouvez vérifier l' UIScreen.mainscreen().scale Pour déterminer le nom de l'atlas à utiliser. Vérifiez le nom de l'atlas dans l'image attachée, et le code dans getTextureAtlas entrez la description de l'image ici

Cela semble fonctionner maintenant si vous utilisez une nouvelle façon de créer un atlas. La chose importante est que Deployment target devrait être> = 9.0 …

Sélectionnez Assets.xcassets et click le signe + pour créer un nouvel atlas d'image-object:

entrez la description de l'image ici

Choisissez l'option "New Sprite Atlas" et ajoutez les actifs @ 2x et @ 3x:

entrez la description de l'image ici

Ensuite, dans un code, faites ceci:

 let sprite = SKSpriteNode(texture: SKTextureAtlas(named: "Sprites").textureNamed("test")) sprite.position = CGPoint(x: frame.midX, y: frame.midY) addChild(sprite) 

Allusion:

Si vous testez sur Simulator, réinitialisez le contenu et les parameters de Simulator pour vider le cache avant d'essayer.

Xcode 6.2 charge maintenant des images @ 3x et @ 2x sur un atlas. Il charge une taille 1x (et semble resize l'image par lui-même) si vous ne placez pas @ 2x / @ 3x à la fin du nom de l'image.

Je ne sais pas pourquoi cela n'a jamais été fait, mais voici le début d'une solution de contournement qui est en fait correcte, mais malheureusement un peu plus lent. Peut-être que quelqu'un peut voir certaines choses pour le faire traiter plus rapidement

 import Foundation import SpriteKit public class Atlas: SKTextureAtlas { var textures = [Ssortingng:(texture:SKTexture,image:UIImage)](); public convenience init(named name: Ssortingng) { self.init() let scale = CGFloat(UIScreen().scale); let path = "\(name).atlasc/\(name)"; let atlasContent = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource(path, ofType: "plist")!); let content = atlasContent!["images"] as! [[Ssortingng:AnyObject]]; let info = content[Int(scale) - 1] ; let imagepath = "\(name).atlasc/\((info["path"] as! Ssortingng!).ssortingngByReplacingOccurrencesOfSsortingng(".png", withSsortingng: ""))"; let imgDataProvider = CGDataProviderCreateWithCFData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource(imagepath, ofType: "png")!)); let cgimage = CGImageCreateWithPNGDataProvider(imgDataProvider, nil, true, .RenderingIntentDefault); let subimages = info["subimages"] as! [[Ssortingng:AnyObject]]; for subimage in subimages { let spriteSourceSize = CGSizeFromSsortingng(subimage["spriteSourceSize"] as! Ssortingng); let size = CGSizeApplyAffineTransform(spriteSourceSize, CGAffineTransformMakeScale(1/scale,1/scale)); let isFullyOpaque = subimage["isFullyOpaque"] as! Bool; let spriteOffset = CGPointFromSsortingng((subimage["spriteOffset"] as! Ssortingng)); let textureRect = CGRectFromSsortingng((subimage["textureRect"] as! Ssortingng)); let textureRectSize = CGSizeApplyAffineTransform(textureRect.size, CGAffineTransformMakeScale(1/scale,1/scale)); let name = (subimage["name"] as! Ssortingng).ssortingngByReplacingOccurrencesOfSsortingng("@3x.png", withSsortingng: ""); let textureRotated = subimage["textureRotated"] as! Bool; let smallImage = CGImageCreateWithImageInRect(cgimage, textureRect); UIGraphicsBeginImageContextWithOptions(size, isFullyOpaque, scale); let context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); CGContextSetShouldAntialias(context,false); CGContextSetAllowsAntialiasing( context ,false); CGContextSetInterpolationQuality(context , CGInterpolationQuality.None) if(textureRotated) { CGContextTranslateCTM(context, (size.width)/2, (size.height)/2); CGContextScaleCTM(context, 1, -1); CGContextRotateCTM(context,CGFloat(M_PI_2)); CGContextTranslateCTM(context, 0, ((size.height - textureRectSize.height))); CGContextTranslateCTM(context, -((size.height)/2), -((size.width)/2)); CGContextTranslateCTM(context, spriteOffset.y/scale, -spriteOffset.x/scale); } else { //Set to center of image to flip correctly CGContextTranslateCTM(context, (size.width)/2, (size.height)/2); CGContextScaleCTM(context, 1, -1); CGContextTranslateCTM(context, -((size.width)/2), -((size.height)/2)); CGContextTranslateCTM(context, spriteOffset.x/scale, spriteOffset.y/scale); } CGContextDrawImage(context,CGRect(origin: CGPoint.zero,size: textureRectSize), smallImage); let image = UIGraphicsGetImageFromCurrentImageContext(); let texture = SKTexture(image: image); textures[name] = (texture:texture,image:image); CGContextRestoreGState(context); UIGraphicsEndImageContext(); } } override public func textureNamed(name: Ssortingng) -> SKTexture { return textures[name]!.texture; } public func imageNamed(name: Ssortingng) -> UIImage { return textures[name]!.image; } } 

Ce bug n'est toujours pas résolu. En utilisant juste @ 2x images le visuel de l'application est brisé. Au lieu de choisir la bonne image en regardant l'échelle de l'écran.

 textureName = [UIScreen mainScreen].scale > 2.9 ? @"awesome@3x" : @"awesome";