Sprite kit 创建\(使用)SKView作为\(在工厂中)\(静态类)

Sprite kit 创建\(使用)SKView作为\(在工厂中)\(静态类),sprite-kit,skshapenode,sktexture,skview,Sprite Kit,Skshapenode,Sktexture,Skview,我想制作一个SKView,我可以用它作为工厂来制作SKShapeNodes,并将它们“渲染”成纹理 但是我找不到我如何初始化这样一件事,我一点运气都没有 为此,如何创建独立的SKView 还是有更好的方法避免使用游戏场景 这是我在制造工厂方面徒劳的努力,这抱怨纹理(来自:)模棱两可。我不知道那是什么意思 import SpriteKit class Make: SKView{ static func circle() -> SKSpriteNode { let myShapeN

我想制作一个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")
    }   
}
更新 在谷歌上度过了更多徒劳的时间后,我尝试搜索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")
    }
}

不太清楚你所说的“我将如何初始化这样一件事”是什么意思。如何取决于技术以及工厂的总体工作。一些工厂不需要外部输入进行初始化,而另一些工厂则需要外部输入。这里有几个非常粗糙的例子。这些可能过于简单化,根本没有经过测试

一个使用静态类的概念,而另一个使用单例。所有这些都不是“这比那好”。也不是要打开潘多拉的盒子,哪个更好,等等。还有其他的线索在讨论这些细节。相反,它们只是让你行动起来的几种方法

这是一个静态类版本

// 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()
(代表OP发布)

问题解决了! 对于那些比我更了解编码的人来说,下面的评论不适合你们。这是给所有像我这样的傻瓜和有抱负的工具的

多亏了惊人的耐心和我的知识,我能够完全按照自己的意愿去做,即在项目中的任何地方创建一个工厂,通过一个没有类型的静态类中的SKView实例来创建SKShapeNodes,这个工厂的唯一目的就是创建这个工厂

  • 在Swift中,类不能有超类或继承。这意味着可以创建完全隔离的类文件,这些类文件除了在项目中存储通用访问的功能和属性之外没有其他用途

  • 在OOP编程中,这有点被认为是“错误的”,但从概念和使用角度来看,以及将事情干净利落、易于查找和阅读的紧迫性,我天真地认为,这是非常宝贵的

  • 尽管SKView在UIKit世界中是一个令人望而生畏的高级类,但为了利用其功能,可以在静态类中创建一个未使用且无法识别的SKView实例

  • 由于以下原因,最终的用法优雅而简单:

  • 一个工厂,命名时使用的大写字母完全不正确,因此我可以立即在代码中看到它:

    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)
    

    您不需要传入视图,只需创建一个SKView()就足以创建纹理。这对于在视图中创建场景之前创建精灵非常有用。几天前,我在某处看到,但现在找不到,有人将SKView子类化,并将其用作制作SKShapeNodes的工厂,这就是我正在尝试的。但我不知道如何对SKView进行子类化。你的方法似乎在做一些让我更加困惑的事情,因为我甚至不知道他们在做什么。我想,我似乎承认游戏的SKView的存在,但我的概念化技能就像护鼻带一样磨练。是的,@Knight0fDragon,我想我看到的就是这样。如何初始化该视图?我已经尝试了我能想到的一切,虽然不多,但没有什么是接近的。更多的红色迷雾,大部分。@Knight0fDragon,谢谢你的信息。我不知道。由于某种依赖性,我错误地认为苹果把它放在了
    SKView
    上作为一个实例方法。我读了文件,他们在那里澄清了这一点。我已经更新了代码,只在内部创建视图,这实际上简化了事情@困惑的是,我已经根据KnightOfDragon的话更新了代码。它简化了代码,并且可能更容易理解。您不应该试图为工厂的
    SKView
    子类化。我举的例子没有继承任何东西。你正面临学习发展的挑战之一,那就是有很多细节需要理解。通常,获得一种新技术只会让事情变得混乱。请注意,如果您不想,也不一定需要工厂。你可以把这个方法放在现场(如果这样更容易理解的话)。我认为从SKView推导出来是没有意义的。如果你的游戏场景有一个基类,那么把它作为一个方法就更合适了。