【问题标题】:How do I get the screen dimensions before init()?如何在 init() 之前获取屏幕尺寸?
【发布时间】:2014-10-07 22:13:30
【问题描述】:

我正在快速制作一个小游戏,并且想让我的玩家在屏幕上的 3 个固定点上移动。 我创建了一个数组来存储我在 init 函数中计算的值,但编译器不同意我不在 super.init() 之前声明数组。这就是我所拥有的

//properties
var player:SKSpriteNode = SKSpriteNode()
var playerPos = 1
var legalPositions: [CGFloat]


override init(size:CGSize)
{
    super.init(size: size)


    legalPositions[0] = self.frame.width/4
    legalPositions[0] = self.frame.width/2
    legalPositions[0] = self.frame.width/0.5

}

当我尝试构建它时,我得到了错误

GameScene.swift:31:9:属性“self.legalPositions”未在 super.init 调用时初始化

有没有办法在调用init函数之前初始化属性?

【问题讨论】:

    标签: swift sprite-kit


    【解决方案1】:

    这实际上是Implicitly Unwrapped Optionals 的一个很好的用例。基本上你会将legalPositions 定义为[CGFloat]!,这将默认为nil。然后,您可以致电super.init(size: size) 之后设置它。

    由于它是隐式解包的,因此您不必担心每次使用时使用可选绑定或强制解包。而且,由于您总是在 init 方法中设置它,因此您不必担心它是 nil 并导致崩溃。

    //properties
    var player:SKSpriteNode = SKSpriteNode()
    var playerPos = 1
    var legalPositions: [CGFloat]!
    
    
    override init(size:CGSize)
    {
        super.init(size: size)
    
    
        legalPositions[0] = self.frame.width/4
        legalPositions[0] = self.frame.width/2
        legalPositions[0] = self.frame.width/0.5
    
    }
    

    【讨论】:

      【解决方案2】:

      是的,您可以使用在初始化程序中被覆盖的虚拟值:

      var legalPositions: [CGFloat] = [0]
      

      这样,legalPositions 数组会在您调用基类初始化程序之前进行初始化。 Swift 的两阶段初始化需要这个过程,以便能够保证在创建一个类的新实例后初始化所有属性。

      这种方法的好处是不需要隐式解包的选项。它们开启了设置 nil 值的可能性,这不是您想要的。

      请注意,您的 sn-p 中的前两个赋值是不必要的,因为第三个赋值无论如何都会覆盖 legalPositions 数组的第一项的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-13
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多