Создать \(использовать) SKView как \(в) фабрике \(статический класс)

Я хочу создать SKView, который я могу использовать как фабрику для создания SKShapeNodes и "рендеринга" их в текстуры.

Но я не могу найти, как бы я это инициализировал, и мне совсем не повезло.

Как мне сделать автономный SKView для этой цели?

Или есть лучший способ сделать это, чтобы избежать использования игровой сцены?

Вот мое FUTILE усилие при создании фабрики, это жалуется, что текстура (от:) неоднозначна. Я понятия не имею, что это значит.

import SpriteKit

class Make: SKView{

static func circle() -> SKSpriteNode {
    let myShapeNode = SKShapeNode(circleOfRadius: 100)
    myShapeNode.fillColor = SKColor.lightGray
    myShapeNode.strokeColor = SKColor.gray
    let tex = texture(from: myShapeNode)
    return SKSpriteNode(texture: tex)
    }

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

Обновить

После более тщательного изучения Google я попытался найти инициализацию UIView, нашел и добавил этот фрагмент кода, который инициализируется в кадре, который кажется мнимым... но это работает! Я не знаю почему... но я не могу использовать его как метод фабрики, только как метод экземпляра, вот так:

import Foundation
import SpriteKit

class Make: SKView{

    // added randomly found UIView initialisation "code"...
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    func circle() -> SKSpriteNode {
        let myShapeNode = SKShapeNode(circleOfRadius: 100)
        myShapeNode.fillColor = SKColor.lightGray
        myShapeNode.strokeColor = SKColor.gray
        let tex = texture(from: myShapeNode)
        return SKSpriteNode(texture: tex)
    }

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

2 ответа

Решение

Не совсем понятно, что вы подразумеваете под "как бы я инициализировал такую ​​вещь". Как зависит от техники и что делает фабрика в целом. Некоторые фабрики не нуждаются во внешнем вводе для инициализации, в то время как другие. Вот пара действительно грубых примеров. Возможно, они слишком упрощены и не были проверены вообще.

Один использует концепцию статического класса, а другой - синглтон. Ничто из этого не должно служить "это лучше, чем это". Также нельзя открывать ящик Пандоры, на котором лучше, и т. Д. Есть другие темы, которые касаются этих деталей. Скорее, это всего лишь пара подходов, которые помогут вам.

Вот статическая версия класса

// static class version
class SpriteFactory1 {
    private static let view:SKView = SKView()

    static func spriteFromShape(shape:SKShapeNode) -> SKSpriteNode? {
        guard let tex = view.texture(from:shape) else {
            return nil
        }

        return SKSpriteNode(texture:tex)
    }
}

Вот синглтон-версия. Добавление кода вашего круга сверху...

// singleton version
class SpriteFactory2 {
    static let sharedInstance = SpriteFactory2()

    private let view:SKView = SKView()

    func spriteFromShape(shape:SKShapeNode) -> SKSpriteNode? {
        guard let tex = view.texture(from:shape) else {
            return nil
        }

        return SKSpriteNode(texture:tex)
    }

    func circle() -> SKSpriteNode {
        let myShapeNode = SKShapeNode(circleOfRadius: 100)
        myShapeNode.fillColor = SKColor.lightGray
        myShapeNode.strokeColor = SKColor.gray
        let tex = texture(from: myShapeNode)
        return SKSpriteNode(texture: tex)
    }
}

Вы также заметите, что код более или менее одинаков. Однако в случае статических переменных класс также должен быть статическим.

Использование будет выглядеть примерно так:

// Test shape
let shape = SKShapeNode()
// Pretend shape is constructed as desired

let sprite1 = SpriteFactory1.spriteFromShape(shape: shape)    
let sprite2 = SpriteFactory2.sharedInstance.spriteFromShape(shape: shape)
let circle = SpriteFactory2.sharedInstance.circle()

(Опубликовано от имени ОП).

Задача решена!

Для тех из вас, кто понимает кодирование лучше меня, следующий комментарий не для вас. Это для всех дураков и стремящихся инструментов, как я.

Благодаря поразительному терпению и моим знаниям Mobile Ben я могу делать именно так, как нужно, т.е. иметь фабрику для создания узлов SKShapeNode из любого места в проекте через экземпляр SKView в статическом классе любого типа, чей только цель - быть этой фабрикой.

  1. У класса не может быть суперкласса или наследования в Swift. Это означает, что можно создавать совершенно изолированные файлы Class, которые не имеют никакой другой цели, кроме хранения функциональных возможностей и свойств для универсального доступа в проекте.

  2. Это в некотором смысле считается "неправильным" в программировании ООП, но с точки зрения концепции и использования, а также необходимости делать вещи аккуратно и легко находить и читать, это бесценно, по моему наивному мнению.

  3. Несмотря на то, что SKView является пугающе высоким классом в мире UIKit, можно просто создать экземпляр неиспользованного и нераспознанного SKView в статическом классе с целью использования его функциональности.

  4. Получающееся в результате использование изящно и просто, благодаря Mobile Ben, вот так:

фабрика с совершенно неправильным использованием заглавных букв для именования, поэтому я могу сразу увидеть это в коде:

import SpriteKit

class MAKE {

private static let view:SKView = SKView()

static func circle(radius: CGFloat) -> SKSpriteNode {
    let myShapeNode = SKShapeNode(circleOfRadius: radius)
    myShapeNode.fillColor = SKColor.lightGray
    myShapeNode.strokeColor = SKColor.gray
    let tex = view.texture(from: myShapeNode)
    return SKSpriteNode(texture: tex)
    }
}

С этим в проекте, из любой другой части проекта, следующее создает круг и сохраняет его в myCircle:

let myCircle = MAKE.circle(radius: 50)
Другие вопросы по тегам