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

时间:2015-01-26 08:25:17

标签: ios objective-c swift sprite-kit 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 plus模拟器:

enter image description here

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

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

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

5 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:4)

如果您使用新方法创建地图集,它似乎现在正在运行。重要的是let sprite = SKSpriteNode(texture: SKTextureAtlas(named: "Sprites").textureNamed("test")) sprite.position = CGPoint(x: frame.midX, y: frame.midY) addChild(sprite) 应该是> = 9.0 ...

选择$(document).ready(function(){ var x; $("#btn1").click(function(){ x = $("p").detach(); }); $("#btn2").click(function(){ $("body").prepend(x); }); }); ,然后点击+号以创建新的精灵图集:

enter image description here

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

enter image description here

然后在代码中执行此操作:

$('#toggle').change(function () {
    if (!this.checked) 
    //  ^
    $('.content').fadeOut('slow');
        else 
    $('.content').fadeIn('slow');
});

<强>提示:

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

答案 2 :(得分:1)

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

答案 3 :(得分: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;
    }
}

答案 4 :(得分:0)

此错误仍未解决。通过仅使用@ 2x图像,应用程序的视觉效果会被破坏。而是通过查看屏幕比例选择正确的图像。

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