【问题标题】:How can I get pixelated textures in SpriteKit? [closed]如何在 SpriteKit 中获得像素化纹理? [关闭]
【发布时间】:2013-10-27 14:13:00
【问题描述】:

如何将SKTextureFilteringNearest 设置为我所有 SKTextures 的默认过滤模式?如果我没有将过滤设置为最近,我的精灵的所有边缘似乎都是模糊的。

【问题讨论】:

  • 为什么不直接加载纹理然后设置texture.filterindMode呢?如果这真的太麻烦了,你可以制作一个应用过滤模式的 SKTexture 类别方法。替换原来的方法是一种残酷的、过分的解决方案。
  • 不确定这是否会对您有所帮助,但这可以让您缩放并保持像素化效果。 stackoverflow.com/questions/19193005/…
  • @LearnCocos2D 为什么这么残酷而且太过分了?我想知道如果它在您自己的项目中,您为什么会反对这样的解决方案?如果你问我,这是一个简单而优雅的解决方案。 DRY(不要重复自己)将适用于此。
  • @Smick 这正是这个解决方案所做的,只是我不必为每个纹理都这样做。
  • 这个解决方案的问题在于它改变了内置 Sprite Kit 函数的行为。好的,如果这对你有用,很好。但是您可能需要在不更改过滤模式的情况下创建纹理,因此您只是在转移问题。更好的解决方案就是为此使用单独的初始化程序,例如“textureWithImageNamed:filteringMode:”,您可以在其中直接指定模式。甚至是“textureNearestFilteredWithImageNamed:”——它使意图更清晰,并且保​​持原始不变并且仍然可用。

标签: ios sprite-kit


【解决方案1】:

SpriteKit 使用SKTextureFilteringLinear 为所有纹理设置默认过滤模式,这会导致图像模糊(尤其是在缩放时)。要解决此问题,您可以为SKTextureSKTextureAtlas 创建一个类别并调用正确的方法。或者你可以使用方法调配textureWithImageNamed:

SKTexture+DefaultSwizzle.h

#import <SpriteKit/SpriteKit.h>

@interface SKTexture (DefaultSwizzle)
@end

SKTexture+DefaultSwizzle.m

#import "SKTexture+DefaultSwizzle.h"
#import <objc/runtime.h> // Include objc runtime for method swizzling methods

@implementation SKTexture (DefaultSwizzle)

+ (SKTexture *)swizzled_textureWithImageNamed:(NSString*)filename
{
    // This is the original. At this point the methods have already been switched
    // which means that `swizzled_texture*` is the original.
    SKTexture *texture = [SKTexture swizzled_textureWithImageNamed:filename];

    // Set 'nearest' as default mode
    texture.filteringMode = SKTextureFilteringNearest;

    return texture;
}

+ (void)load
{
    Method original, swizzled;

    original = class_getClassMethod(self, @selector(textureWithImageNamed:));
    swizzled = class_getClassMethod(self, @selector(swizzled_textureWithImageNamed:));
    // Swizzle methods
    method_exchangeImplementations(original, swizzled);
}

@end

【讨论】:

  • 为什么投反对票?这个方法不行吗?
【解决方案2】:

我提出了一个不同的解决方案,它可以在没有混乱的情况下工作,并且保持原始方法不变:

@interface SKTexture (FilteringModeCategory)
+(SKTexture*) textureWithImageNamed:(NSString*)file
                      filteringMode:(SKTextureFilteringMode)mode;
+(SKTexture*) textureNearestFilteredWithImageNamed:(NSString*)file;
@end

实现:

@implementation SKTexture (FilteringModeCategory)

+(SKTexture*) textureWithImageNamed:(NSString*)file 
                      filteringMode:(SKTextureFilteringMode)mode
{
    SKTexture* tex = [SKTexture textureWithImageNamed:file];
    tex.filteringMode = mode;
    return tex;
}

+(SKTexture*) textureNearestFilteredWithImageNamed:(NSString*)file
{
    SKTexture* tex = [SKTexture textureWithImageNamed:file];
    tex.filteringMode = SKTextureFilteringNearest;
    return tex;
}

@end

随意重命名第二种方法。怎么样:crispyTextureWithImageNamed? :)

PS:SKTextureAtlas 可能也需要对应的textureNamed:filteringMode:textureNearestFilteredNamed: 类别方法。

【讨论】:

  • 您的解决方案的“问题”是它不能以我想要的方式使用(正如我在描述中所说),您还必须覆盖 SKTextureAtlas 因为它使用textureWithImageNamed。如果你想得到你(我的)想要的行为,这个解决方案是“唯一”正确的(恕我直言)。但是,如果您反对该解决方案,我想这很好。我只是想我会分享它。在我的项目中,我永远不想使用线性过滤(@您对我的反对解决方案的评论)
  • SKTextureAtlas 在通过atlasNamed: 加载图集时在哪里使用textureWithImageNamed?添加一个 textureNearestFilteredNamed: 到 SKTextureAtlas 应该不是问题。同样,如果结果不同,最好使用不同的 API,而不是尝试将其硬塞到现有 API 上并更改其默认行为。如果您对此感到满意,那没关系,但作为对其他人的一般解决方案,我发现此类更改存在问题,因为通常在未完全理解的情况下应用此类代码。我不只是想你。 ;)
  • 不,当通过带有textureNamed 的图集加载纹理时。我知道您不只是在想我(;-)),而是看看这个“问题”的标题;它被称为“更改 Sprite Kit 默认纹理模式”,而不是“如何在 Sprite Kit 中获取像素化纹理”。现在我了解您的来源以及在某些(如果不是大多数)情况下更改默认行为可能是“错误的”,但就像我说我想更改默认行为一样,这就是我想出的,没有其他方法这样做(我认为!)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 2017-10-08
  • 1970-01-01
  • 2013-03-24
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多