Как: класс, который наследует 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)
}