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

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

Но я не могу найти, как бы я инициализировал такую ​​​​вещь, и мне вообще не повезло.

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

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

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

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")
    }
}

person Confused    schedule 17.10.2016    source источник
comment
Я не думаю, что имеет смысл выводить это из SKView. Если у вас есть базовый класс для GameScene, было бы более уместно, если бы он был там методом.   -  person Mobile Ben    schedule 17.10.2016


Ответы (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()
person Mobile Ben    schedule 17.10.2016
comment
Вам не нужно передавать представление, просто создать SKView() более чем достаточно для создания текстур. Это полезно, когда вы хотите создать свои спрайты еще до того, как у вас появится сцена в представлении. - person Knight0fDragon; 17.10.2016
comment
Несколько дней назад я где-то видел и не могу найти сейчас, что кто-то создает подкласс SKView и использует его как фабрику для создания SKShapeNodes, и это то, что я пытаюсь сделать. Но я не могу понять, как создать подкласс SKView. Ваши подходы, похоже, делают что-то, что еще больше меня смущает, поскольку я даже не понимаю, что они делают. По-видимому, признавая существование SKView в игре, я полагаю, но мои навыки концептуализации примерно так же отточены, как ремень защиты носа. - person Confused; 17.10.2016
comment
Да, @Knight0fDragon, я думаю, что это то, что я видел. Как мне инициализировать этот SKView? Я пробовал все, что мог придумать, что немного, но ничего даже близко. Больше красного тумана, в основном. - person Confused; 17.10.2016
comment
@Knight0fDragon, спасибо за информацию. Я этого не знал. Я ошибочно предположил, что Apple поместила его в SKView как метод экземпляра из-за некоторой зависимости. Я читаю документы, и они разъясняют это там. Я обновил код, чтобы просто создать представление внутри, что на самом деле упрощает работу! - person Mobile Ben; 17.10.2016
comment
@Confused, я обновил код на основе того, что сказал KnightOfDragon. Это упрощает код и, вероятно, ему легче следовать. Вы не должны пытаться создать подкласс SKView для фабрики. Пример, который я привел, не наследовал ни от чего. Вы сталкиваетесь с одной из проблем развития обучения, которая заключается в том, что нужно понять множество деталей. И часто получение новой техники только запутывает дело. Обратите внимание, что вам также не обязательно нужна фабрика, если вы этого не хотите. Вы можете использовать этот метод на месте происшествия (если это облегчает понимание). - person Mobile Ben; 17.10.2016
comment
Я делаю МНОГО разных пуговиц. А ради здравомыслия и организованности захотеть иметь где-нибудь красивую захламленную фабрику и призывать ее делать из нее разные вещи, когда нужно и по желанию. Однако вы правы, огромное количество способов, которыми вещи могут быть связаны друг с другом, не дает мне покоя. - person Confused; 17.10.2016
comment
На самом деле у меня частично работает фабрика подклассов SKView. Я могу вызывать свои фабричные методы (в подклассе SKView) из gameScene, но предпочел бы иметь возможность вызывать его из подклассов SKSpriteNode, которые становятся кнопками (имеют функциональность touchesbegun и т. д.). Но пока не придумал, как это сделать. Что не так с подклассом SKView для рендеринга текстур? - person Confused; 18.10.2016
comment
Чего я не понимаю в вашем подходе, так это многого. Я не понимаю, что это за типы и что они делают, когда говорят: private static let view:SKView = SKView() или private let view:SKView = SKView() во втором. Я совершенно не понимаю, что вы на самом деле делаете, и как ваш способ позволяет использовать let tex = texture (от: myShapeNode) - person Confused; 18.10.2016
comment
Взгляните прямо сейчас, я добавил ваш код круга в фабрику синглтонов. Я предполагаю, что вы, возможно, понимаете использование singleton немного больше, чем статический класс, поэтому добавили его туда. RE: создание подкласса SKView. Простой тест на подклассы - это вопрос. Является ли фабрика SKView? Нет. На самом деле SKView по своей природе нужен для получения текстуры. - person Mobile Ben; 18.10.2016
comment
Игнорировать SpriteFactory1. Просто используйте SpriteFactory2 (который является синглтоном). И, кстати, вы можете просто реализовать это и пройти через отладчик. Так может быть легче понять. - person Mobile Ben; 18.10.2016
comment
Я должен извиниться, я не знаю, как пройти через отладчик. Но согласитесь, Синглтон имеет гораздо больше смысла, чем любой статический класс. Я пытался создавать статические классы, функции и свойства повсюду, и у меня не было конца проблемам с двусмысленностью и другими проблемами из-за предупреждений Xcode. - person Confused; 18.10.2016
comment
Что касается сравнения, то... по моему мнению, мне нужен SKView, чтобы получить доступ к мощности для рендеринга текстуры. Итак, на мой взгляд, это SKView с единственной целью создания спрайтов. Это нелогично? Неправильная голова? Тот факт, что вы, по-видимому, можете создать экземпляр SKView внутри класса без видимого типа, не дает мне покоя. - person Confused; 18.10.2016
comment
И, еще больше путаницы, мысленно я думаю, что предпочитаю конструкцию и концепцию Static (методы класса, свойства класса, а не свойства или методы экземпляра), но механика использования статики не дает мне покоя. Справедливо ли сказать, что использование Static означает ВСЕ внутри этого класса, которое нужно использовать, должно быть статическим? И что это несколько смягчает необходимость инициализации в более обычном смысле, потому что класс никогда не превращается в экземпляр, а используется только как хранилище методов и свойств для универсального использования? - person Confused; 18.10.2016
comment
1. Классы Swift не должны быть подклассами чего-либо. Я забыл об этом. Ментальный блокпост один - person Confused; 18.10.2016
comment
2. Я понятия не имел, что можно просто создать экземпляр SKView и хранить его внутри любого класса. Откровение. Я думал, что единственный способ использовать это — быть им. - person Confused; 18.10.2016
comment
3. Хранение этого SKView в статическом классе в качестве частного экземпляра означает, что он там... но должен быть ВЫЗВАН. - person Confused; 18.10.2016
comment
4. вот большое откровение... в вашем 1-м примере view.texture(from:shape) === Я не знаю, как выделить это жирным шрифтом в комментариях, но этот вызов текстуры ВКЛ/ВНУТРИ экземпляра представления. ... это самая большая точка умственного облегчения, она сняла всю путаницу и помогла мне увидеть все 3 из трех других пунктов выше. БЛАГОДАРЮ ВАС!!!! - person Confused; 18.10.2016
comment
Итак, теперь у меня есть скрытое место для хранения всех моих экспериментов по дизайну кнопок и сборке (очень беспорядочный код, тонны кода, множество итераций) и совершенно элегантный способ создания из этого статического класса фабрики, такого как этот, из любого места. в проекте: пусть кнопка = SpriteFactory1.circle() что абсолютно идеально как с точки зрения наглядности, так и с точки зрения концепции. БЛАГОДАРЮ ВАС!!! - person Confused; 18.10.2016
comment
В обоих случаях фактические методы работы идентичны. Разница заключается в инициализации/использовании статики для элементов данных. Проверьте это для немного больше чтения;). stackoverflow.com/questions/519520 / - person Mobile Ben; 18.10.2016

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

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

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

Благодаря чудесному терпению и моему знанию @MobileBen я могу сделать именно то, что хочу, т.е. иметь фабрику для создания SKShapeNodes из любого места проекта через экземпляр SKView в статическом классе без типа, единственной целью которого является эта фабрика.

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

  2. Это несколько считается «неправильным» в программировании ООП, но с точки зрения концепции и использования, а также срочности выполнения вещей аккуратно и легко найти и прочитать, это бесценно, по моему НАИВНОМУ мнению.

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

  4. Благодаря MobileBen использование получается элегантным и простым, например:

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

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)
person Community    schedule 18.10.2016