创建 \(Use) SKView as \(in a) factory \(static class)

Posted

技术标签:

【中文标题】创建 \\(Use) SKView as \\(in a) factory \\(static class)【英文标题】:Create \(Use) SKView as \(in a) factory \(static class)创建 \(Use) SKView as \(in a) factory \(static class) 【发布时间】:2017-02-26 08:06:23 【问题描述】:

我想制作一个 SKView,我可以将其用作工厂来制作 SKShapeNode 并将它们“渲染”为纹理。

但我找不到如何初始化这样的东西,而且我一点运气都没有。

如何为此目的制作独立的 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")
    

【问题讨论】:

我认为从 SKView 派生这个是没有意义的。如果你的 GameScene 有一个基类,那么将它作为一个方法会更合适。 【参考方案1】:

您所说的“我将如何初始化这样的东西”并不是很清楚。如何取决于技术和工厂的整体工作。一些工厂不需要外部输入进行初始化,而另一些工厂则需要。这是几个非常粗略的例子。这些可能过于简单,根本没有经过测试。

一个使用静态类的概念,而另一个是单例。这些都不是“这比那更好”。也不是打开哪个更好的潘多拉魔盒等等。还有其他线程会讨论这些细节。相反,它们只是让您前进的几种方法。

这是一个静态类版本

// 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()

【讨论】:

您不需要传入视图,只需创建一个 SKView() 就足以创建纹理。当您想要在视图中有场景之前创建精灵时,这很有用。 我几天前在某个地方看到过,现在找不到,有人继承 SKView 并将其用作制造 SKShapeNodes 的工厂,这就是我想要做的。但我不知道如何子类化 SKView。你的方法似乎在做一些让我更困惑的事情,因为我什至不明白他们在做什么。我想,表面上承认游戏的 SKView 的存在,但我的概念化技巧就像鼻卫的腰带一样磨练。 是的,@Knight0fDragon,这就是我认为我看到的。如何初始化该 SKView?我已经尝试了我能想到的一切,虽然不多,但没有什么比这更接近了。主要是更多的红雾。 @Knight0fDragon,感谢您提供的信息。我不知道。由于某些依赖性,我错误地认为 Apple 将其作为实例方法放在 SKView 上。我阅读了文档,他们在那里澄清了这一点。我已经更新了代码,只在内部创建了视图,这实际上简化了事情! @Confused,我已经根据 KnightOfDragon 所说的更新了代码。它简化了代码并且可能更容易理解。您不应该尝试为工厂子类化 SKView。我给出的例子没有继承任何东西。你遇到了学习发展的挑战之一,那就是有很多细节需要理解。通常,获得一项新技术只会使事情变得混乱。请注意,如果您不想要,您也不一定需要工厂。您可以将方法放在现场(如果这样更容易理解的话)。【参考方案2】:

(代表 OP 发布).

问题解决了!

对于那些比我更了解编码的人,以下评论不适合你。它适合所有傻瓜和有抱负的工具,比如我。

感谢@MobileBen 的奇妙耐心和我的知识,我能够完全按照需要做,即有一个工厂可以从项目中的任何地方创建 SKShapeNodes,通过一个静态类中的 SKView 实例为 no类型,其唯一目的就是成为这个工厂。

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

    这在 OOP 编程中有点被认为是“错误的”,但从概念和使用的角度来看,以及将事情整齐而轻松地找到和阅读的紧迫性,在我看来,这是非常宝贵的。

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

    感谢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)

【讨论】:

以上是关于创建 \(Use) SKView as \(in a) factory \(static class)的主要内容,如果未能解决你的问题,请参考以下文章