Swift3 在Swift和SpriteKit中重写类的开放变量以用于XCode';s动作编辑器

Swift3 在Swift和SpriteKit中重写类的开放变量以用于XCode';s动作编辑器,swift3,sprite-kit,xcode8,Swift3,Sprite Kit,Xcode8,我正在尝试制作一个小平台游戏,只是为了学习。我曾尝试使用如下纹理数组设置角色动画: let animation: SKAction = SKAction.animate( with: frames.map { let texture : SKTexture = SKTexture(imageNamed: $0) texture.filteringMode = SKTextureFilteringMode.nearest return te

我正在尝试制作一个小平台游戏,只是为了学习。我曾尝试使用如下纹理数组设置角色动画:

let animation: SKAction = SKAction.animate(
    with: frames.map {
        let texture : SKTexture = SKTexture(imageNamed: $0)
        texture.filteringMode = SKTextureFilteringMode.nearest

        return texture
    },
    timePerFrame: 0.15
)
frames
变量是纹理数组。我已经使用
map
为每个纹理设置了过滤模式。这很好用,但是我发现我可以用AnimateWithTextures动作在XCode的ActionEditor中创建动画(动作)。这就是我的问题所在。这更有效,但我无法在ActionEditor中更改动画中纹理的过滤模式。我研究了SKTexture类并看到了以下内容:

open class SKTexture : NSObject, NSCopying, NSCoding {
    ...
    /**
    The filtering mode the texture should use when not drawn at native size. Defaults to SKTextureFilteringLinear.
    */
    open var filteringMode: SKTextureFilteringMode
    ...
}
若我并没有弄错,
open
意味着我可以重写变量,但我不知道如何重写。我想将
filteringMode
的默认值设置为
SKTextureFilteringMode。对于所有SKTextures,最近的
,因此ActionEditor将使用纹理过滤设置为最近邻居的纹理


另外,如果您知道如何在特定操作中为纹理设置过滤模式,我也想知道如何做到这一点。谢谢

您可以创建一个函数来为您设置动画,并使用自定义init创建对SKTexture的扩展,当您准备好时,只需将其调用到节点

extension SKTexture { // Declare this extension outside your class decleration
convenience init(customImageNamed: String) {
    self.init(imageNamed: customImageNamed)
    self.filteringMode = .nearest
}
}

func setupAnimationWithPrefix(_ prefix: String, start: Int, end: Int, timePerFrame: TimeInterval) -> SKAction{
    var textures = [SKTexture]()
    for i in start...end{
        textures.append(SKTexture(customImageNamed: "\(prefix)\(i)"))
    }
    return SKAction.animate(with: textures, timePerFrame: timePerFrame)
}
如果您有10个名为image1、image2、image3等的图像,那么这就是您使用此函数的方式

func runAction(){
    let action = setupAnimationWithPrefix("image", start: 1, end: 10, timePerFrame: 0.1) 
    yourNode.run(action)
} // you can change timePerFrame to your liking i find 0.1 sec per frame the best

不幸的是,如果不将变量子类化,就无法重写它,也就是说

class MyTexture: SKTexture {
从这里,您可以覆盖变量:

  override var filteringMode: SKTextureFilteringMode {
    get {
      return .nearest
    }
    set {
    }
  }
这应该行得通,但现在你永远都不能改变过滤模式(不经过一系列的胡闹)

因此,更合适的方法是通过初始值设定项设置默认值,但是
SKTexture
没有公共指定的初始值设定项,因此该选项不在窗口中

因此,您最好的选择是Arie的
便利init
扩展,或者只制作一个返回新纹理的普通函数:

func nearestTexture(imageNamed name: String) -> SKTexture {
   let newTex = SKTexture(imageNamed: name)
   newTex.filteringMode = .nearest
   return newTex
}

let texture: SKTexture = nearestTexture(imageNamed: "lol")

ActionEditor的功能仍然非常有限,您必须编写一些代码来支持纹理过滤。如果您不打算缩放精灵(注意,我说的是精灵,不是场景,这是两种不同的行为),那么我甚至不会担心纹理过滤,时间差可以忽略不计。

顺便说一句,您应该在类declaration之外声明扩展,我认为将所有纹理设置为最接近的过滤模式可能会消耗大量内存,因此我会小心,在手动创建动画时,以编程方式为每个纹理设置纹理过滤不是问题。将默认纹理过滤设置为所有SKTextures的原因是我可以使用ActionEditor。看到我的结果,哦,我现在明白了,这个问题有点让人困惑,无论如何我不确定是否有办法做到这一点,就我个人而言,我尽量不使用ActionEditor来处理这类东西,它仍然有点问题,而且选项有限。我稍微修正了这个问题。看起来我要做的就是手工完成这类工作,然后等到XCode得到更新。这是一段关于
SKTexture'
的文档引用:这个类不能被子类化。我还没有试过,也没有说明为什么它不能被子类化。@Whirlwind在我子类化时编译它。也许有一个rte?也许他们只是意味着你不能设置一个初始值设定项(因为它们不是公共的)@Fludity我想是的,我必须窥视一下
SKTexture
类才能说得更多。但是当涉及到子类化时,私有指定的init肯定是一个障碍。更准确地说,在这种情况下,子类化是不可能的:)但正如这里的另一个答案一样,我们可以使用扩展和便利初始化来解决这个问题。我的意思是,这可能就是我应该做的,而不是像我在评论中为第一个答案而伤心的那样重写filteringMode var.@Fludity,我需要设置纹理过滤,这样我就可以在XCode的ActionEditor中使用它。如果我能为资源中的图像集选择过滤就好了properties@kabukiman如果SKTexture是子类化的,那么这个想法可能更合理。。。但事实并非如此;(你可能只需要使用编辑器进行设计,然后从中硬编码。你应该更新你的问题,以反映你在这里真正想要的是什么……万一有人看到它,你就有办法了。(包括更改标题)