Spritekit - 不从SKTextureAtlas加载@ 3x图像

问题描述 投票:12回答:5

由于我的示例项目被删除(我认为这将更容易测试),我将发布一些代码和图像来说明我的观点。

这是样本图像

我的地图册设置:

我的启动图像设置:

我将这些精灵添加到场景中的代码

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模拟器:

iPhone 6 plus模拟器:

我已经尝试更改启动图像以使用资产目录。然后iPhone 6 plus似乎升级了2倍的屏幕。它仍在加载2x图像,但会将其放大。

我需要它来加载我的3x图像并使用我的2x图像进行缩放。

Gabuh在下面的回答指出了我正确的方向。适用于新项目。但是,如果我将他的解决方案用于我真正的SpriteKit项目,我的3x图像不会缩小。它们比它们应该大3倍。

ios objective-c swift sprite-kit sktextureatlas
5个回答
4
投票

当Xcode生成编译的地图集时,这似乎是一个错误。如果您在已编译应用程序的包中检查,您将看到Xcode没有为@ 3x图像创建正确的地图集名称。

我通过使用@ 3x名称创建地图集来获得@ 3x资产,并保留没有后缀的图像。

您可以检查UIScreen.mainscreen().scale以确定要使用的地图集名称。检查附加图像中的atlas名称,以及getTextureAtlas中的代码


4
投票

如果你正在使用一种新方法创建地图集,它似乎现在正在工作。重要的是Deployment target应该> = 9.0 ...

选择Assets.xcassets并单击以+符号以创建新的精灵图集:

enter image description here

选择“New Sprite Atlas”选项并添加@ 2x和@ 3x资产:

enter image description here

然后在代码中执行以下操作:

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

暗示:

如果您在Simulator上进行测试,请在尝试之前重置Simulator的内容和设置以清除缓存。


1
投票

Xcode 6.2现在从一张图集中加载@ 3x和@ 2x图像。如果你没有在图像名称的末尾加上@ 2x / @ 3x,它会加载1x大小(并且似乎自己调整图像大小)。


1
投票

不确定为什么这从未完成,但这是一个实际上正确的解决方法的开始,但不幸的是有点慢。也许有人可以看到一些东西让它加快处理速度

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;
    }
}

0
投票

这个bug仍然没有解决。通过仅使用@ 2x图像,应用程序的视觉效果会被破坏。而是通过查看屏幕比例选择正确的图像。

textureName = [UIScreen mainScreen].scale > 2.9 ? @"awesome@3x" : @"awesome";
© www.soinside.com 2019 - 2024. All rights reserved.