Подтвердить что ты не робот

Spritekit - не загрузка @3x изображений из SKTextureAtlas

Поскольку мой образец проекта был удален (я думал, что это будет намного легче протестировать), я отправлю код и изображения, чтобы проиллюстрировать мою точку.

Вот примеры изображений

2x image

my 3x image

Настройка моего атласа:

enter image description here

Моя настройка образа запуска:

enter image description here

Код, в который я добавляю эти спрайты в свою сцену

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)

}

Это мои результаты:

Симулятор iPhone 5:

enter image description here

iPhone 6 плюс симулятор:

enter image description here

Я попытался изменить образ запуска, чтобы использовать каталог активов. Тогда iPhone 6 plus, по-видимому, увеличивает масштаб экрана 2x. Он по-прежнему загружает изображение 2x, но масштабирует его.

Мне нужно, чтобы он загрузил мое 3-кратное изображение и масштабировался с моим 2x-изображением.

Ответ Габуха ниже указал мне в правильном направлении. Работает над новым проектом. Однако, если я использую его решение для моего реального проекта SpriteKit, мои 3х-изображения не будут уменьшаться. Они в 3 раза больше, чем они должны быть.

4b9b3361

Ответ 1

Кажется, ошибка, когда Xcode генерирует скомпилированный атлас. Если вы проверите внутри пакета скомпилированного приложения, вы увидите, что Xcode не создает правильные имена атласа для изображений @3x.

Мне удалось получить активы @3x, создав атласы с именем @3x и оставив изображение без суффикса.

И вы можете проверить UIScreen.mainscreen().scale, чтобы определить имя атласа для использования. Проверьте имя атласа в прикрепленном изображении, а код внутри getTextureAtlas enter image description here

Ответ 2

Кажется, сейчас работает, если вы используете новый способ создания атласа. Важно то, что Deployment target должно быть >= 9.0...

Выберите Assets.xcassets и нажмите + знак, чтобы создать новый атлас спрайта:

введите описание изображения здесь

Выберите опцию "Новый спрайт-атлас" и добавьте активы @2x и @3x:

введите описание изображения здесь

Затем в коде выполните следующее:

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

Подсказка:

Если вы тестируете на Simulator, reset содержание и настройки симулятора, чтобы очистить кеш, прежде чем пытаться это сделать.

Ответ 3

Xcode 6.2 теперь загружает @3x и @2x изображения из одного атласа. Он загружает размер 1x (и, по-видимому, сам изменяет размер изображения), если вы не ставите @2x/@3x в конце имени изображения.

Ответ 4

Не знаю, почему это никогда не было сделано, но вот начало обходного пути, которое действительно правильно, но, к сожалению, немного медленнее. Возможно, кто-то может увидеть некоторые вещи, чтобы ускорить процесс.

import Foundation
import SpriteKit

public class Atlas: SKTextureAtlas
{
    var textures = [String:(texture:SKTexture,image:UIImage)]();
    public convenience init(named name: String)
    {
        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! [[String:AnyObject]];
        let info = content[Int(scale) - 1] ;
        let imagepath = "\(name).atlasc/\((info["path"] as! String!).stringByReplacingOccurrencesOfString(".png", withString: ""))";
        let imgDataProvider = CGDataProviderCreateWithCFData(NSData(contentsOfFile:  NSBundle.mainBundle().pathForResource(imagepath, ofType: "png")!));
        let cgimage = CGImageCreateWithPNGDataProvider(imgDataProvider, nil, true, .RenderingIntentDefault);

        let subimages = info["subimages"] as! [[String:AnyObject]];
        for subimage in subimages
        {
            let spriteSourceSize = CGSizeFromString(subimage["spriteSourceSize"] as! String);
            let size = CGSizeApplyAffineTransform(spriteSourceSize, CGAffineTransformMakeScale(1/scale,1/scale));



            let isFullyOpaque = subimage["isFullyOpaque"] as! Bool;
            let spriteOffset = CGPointFromString((subimage["spriteOffset"] as! String));
            let textureRect = CGRectFromString((subimage["textureRect"] as! String));
            let textureRectSize = CGSizeApplyAffineTransform(textureRect.size, CGAffineTransformMakeScale(1/scale,1/scale));




            let name = (subimage["name"] as! String).stringByReplacingOccurrencesOfString("@3x.png", withString: "");
            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: String) -> SKTexture {
        return textures[name]!.texture;
    }
    public func imageNamed(name: String) -> UIImage {
        return textures[name]!.image;
    }
}

Ответ 5

Эта ошибка еще не решена. Используя только изображения @2x, изображение приложения нарушается. Вместо этого выберите правильное изображение, посмотрев масштаб экрана.

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