Как: класс, который наследует SKSpriteNode с init, который может вызвать init (color:, size:)

Я прототип игр с использованием фигур, и spritekit был потрясающим для этого перед быстрым.

Теперь, когда я пытаюсь расширить SKSpriteNode и добавить свою функцию init, я не могу назвать super.init(цвет, размер).

У меня нет способа вызвать код, который создает текстуру формы.

Мне нужно знать, как вызвать эту функцию init или как создать текстуру формы, чтобы я мог переопределить назначенный init, а затем вызвать его, используя мою текстуру формы.

EDIT: Вот точный код, который я делаю, и я делаю почти то же самое в другом расширенном классе SKSprite node:

class TetrisCell : SKSpriteNode
{
    let length = 10;
    convenience init(color:UIColor) {
        var size = CGSize(width: length, height: length);

        //Not allowed to call a super convenience init, must call non-convenience init
        super.init(color: color, size: size);
    }
}

Я понимаю, почему это не позволит мне, поэтому я ищу другой способ. На данный момент у TetrisCell нет текстуры. Я бы хотел просто использовать фигуры для удобства.

Из того, что я могу сказать, мне нужно вызвать super.init(texture:, color:, size:) для инициализации моего SKSpriteNode. Если нет способа сделать вышеуказанный код, то я хотел бы знать, что они установили для SKTexture, поэтому я могу имитировать его. Что-то вроде super.init(текстура: SKTexture.blankTexture) или что-то в этом роде. Что бы они ни добавляли, поскольку текстура управляется атрибутом color:, в то время как мой пиксель 1x1, похоже, не зависит от атрибута color:.

Ответ 1

TL; DR: Параметр texture имеет тип SKTexture!. Поскольку он определен как неявно развернутый необязательный, вы можете просто пройти nil.


Во-первых, вы не можете просто вызвать super(texture:, color, size:) из своего convenience init, вам действительно нужно вызвать метод init на self. Итак, вам нужно добавить override init(texture: SKTexture!, color: SKColor!, size: CGSize) (который вы можете просто вызвать super).

Во-вторых, вы можете просто передать nil в качестве параметра texture; SpriteKit будет обрабатывать его соответствующим образом.

В-третьих (и только потому, что мне пришлось внести изменения, чтобы вещи могли компилироваться), вы не можете использовать свойство length при создании переменной size, потому что экземпляр класса еще не был инициализирован. Вместо этого я бы рекомендовал объявить length как var и передать его как параметр вашему convenience init.

Поместите все это вместе, и вы получите что-то вроде этого:

class TetrisCell : SKSpriteNode
{
    var length: CGFloat!

    override init(texture: SKTexture!, color: SKColor!, size: CGSize) {
        self.length = 10 // Some sort of sensible default
        super.init(texture: texture, color: color, size: size)
    }

    convenience init(color: SKColor, length: CGFloat = 10) {
        var size = CGSize(width: length, height: length);
        self.init(texture:nil, color: color, size: size)
        self.length = length
    }

    required init?(coder aDecoder: NSCoder) {
        // Decoding length here would be nice...
        super.init(coder: aDecoder)
    }
}

Ответ 2

Один из способов решения этой проблемы - просто создать новый метод init и установить в нем свойства цвета и размера:

class Sprite: SKSpriteNode {

    init(color:SKColor,size:CGSize) {
        super.init()
        self.size=size
        self.colorBlendFactor=1
        self.color=color
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

Ответ 3

Без просмотра кода или ошибки, я думаю, он жалуется, что вы не включаете требуемый инициализатор или что-то в этом роде. Это может решить вашу проблему:

override init(texture: SKTexture!, color: UIColor!, size: CGSize) {
    super.init(texture: texture, color: color, size: size)
    // Do custom stuff here
}

// Swift requires this initializer to exist if you're adding any other custom ones
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}