13

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

这是示例图像

2x 图像

我的 3x 图像

我的地图集设置:

在此处输入图像描述

我的启动图像设置:

在此处输入图像描述

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

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 倍。

4

5 回答 5

5

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

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

在此处输入图像描述

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

在此处输入图像描述

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

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

暗示:

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

于 2016-02-15T13:15:50.673 回答
4

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

我通过创建带有@3x 名称的图集并让图像不带后缀来设法获取@3x 资产。

您可以检查UIScreen.mainscreen().scale以决定要使用的图集名称。检查附图中的图集名称,以及里面的代码getTextureAtlas 在此处输入图像描述

于 2015-01-26T09:02:58.230 回答
1

Xcode 6.2 现在从一个图集中加载@3x 和@2x 图像。如果您不将 @2x/@3x 放在图像名称的末尾,它会加载 1x 大小(并且似乎会自行调整图像大小)。

于 2015-03-13T04:14:39.070 回答
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;
    }
}
于 2016-03-04T09:16:49.990 回答
0

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

textureName = [UIScreen mainScreen].scale > 2.9 ? @"awesome@3x" : @"awesome";
于 2015-11-16T17:09:21.027 回答