是否可以将 SKSpriteNode 添加到另一个类的场景中?

Posted

技术标签:

【中文标题】是否可以将 SKSpriteNode 添加到另一个类的场景中?【英文标题】:Is it possible to add a SKSpriteNode to a scene from another class? 【发布时间】:2016-09-14 22:42:14 【问题描述】:

*这些是例子

所以我有一个带有自定义类的 SKScene ..

class MainMenu: SKScene 

   code...


还有另一个带有自定义类的 SKScene ..

class GameOver: SKScene 

   code...


我还有另一个类叫 PopupMenu ...

class PopupMenu: SKScene 

    func addSprite() 

    theSprite = SKSpriteNode.init(imageNamed: "theImage")
    theSprite.position = CGPointMake(self.frame.width/2, self.frame.height/2)
    theSprite.zPosition = 2

    self.addChild(theSprite)


所以我想要实现的是能够单击 MainMenu 场景和 GameOver 场景上的显示菜单按钮,并能够从 PopupMenu 调用函数以将该节点添加到相应的场景中。

我可以通过为每个场景类中的弹出窗口编写代码来实现这一点,但我觉得这不是实现可重用性的最佳方式。

有没有更好的方法来做到这一点?

【问题讨论】:

【参考方案1】:

查看SKReferenceNodes,您可以通过 SpriteKit Scene Builder 创建弹出菜单,然后将其保存为 sks 文件。到了使用的时候,只要拉出弹出菜单的文件,添加到场景中即可。

来源:https://developer.apple.com/reference/spritekit/skreferencenode

如果您打算不使用 SKS Builder(我推荐使用它,因为它非常棒并且可以节省大量时间),您可以做的另一件事是将弹出菜单子类化为 SKSpriteNode,而不是场景

class PopupMenu: SKSpriteNode 

    required init?(coder: aDecoder:NScoder) 
        super.init(coder:aDecoder)    
        

    override init(texture: SKTexture!, color: SKColor!, size: CGSize) 
        super.init(texture: texture, color: color, size: size) 
    

    convenience init() 
        self.init(imageNamed: "theImage")
        self.zPosition = 2    
    



然后在你的场景代码中,调用

let popup = PopupMenu()
popup.position = CGPointMake(self.frame.width/2, self.frame.height/2)
self.addChild(popup)

【讨论】:

这很有趣,我从来没有这样做过,但如果我要这样做,那么它会如何工作呢?如果只是一个 sks 文件,那菜单运行的代码又是从哪里来的呢? ... 后面的任何其他代码都在同一个地方,您在 SKS builder 的场景中设置自定义类字段 我不知道,因为我只通过代码使用过 SpriteKit 游戏。我不使用 SKS 构建器,因为它在 Xcode 7 上非常有问题。尽管我保存了它,但它会清除我的节点,有时还会删除所有内容。 这没有意义,这允许您在任何您想要的场景上使用相同的节点,您是否反对编写 addChild(SKReferenceNode(...)) 或其他什么,因为这是您要编写的唯一代码 为了使您的弹出菜单代码与场景一起工作,您在弹出菜单类代码中调用祖父级(祖父级,因为父级是参考节点)【参考方案2】:

如果您希望您的游戏运行良好,首先要做的是确保在您传递到新场景时,前一个场景被释放。 我认为您可以为自定义类构建一个通用菜单或通用菜单按钮,然后在任何您想要的地方调用它:

class MenuButton : SKSpriteNode

    var length: CGFloat!

    override init(texture: SKTexture!, color: SKColor!, size: CGSize) 
        self.length = 50 // default lenght
        super.init(texture: texture, color: color, size: size)
    

    convenience init(color: SKColor, length: CGFloat = 50) 
        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)
    

【讨论】:

我的意思是你可以为继承 SKSpriteNode 方法的 MenuButton 创建一个自定义类(一个新文件),所以下次你想要自定义按钮时只需调用 let myBtn = MenuButton.init( ...) @AlessandroOrnano,我不确定这是否能回答问题。您只是在谈论如何检查代码以确保释放,并显示有关如何制作子类的代码 @Knight0fDragon 你在开玩笑吗?这是进行自定义的自然方式,有多种方式,这是其中之一。我不是来做佣金工作,而是提供建议和说明找到正确方法的方法。您的回答是我不喜欢的另一种方法,因为我认为像裸代码那样深入定制并不容易,但它可以工作。 问题是“如何将 SKSpriteNode 添加到另一个类的场景中?”你什么时候回答这个问题 @AlessandroOrnano,SKReferenceNodes 提供了您可以想象的尽可能多的自定义,所以不知道您从哪里得到这个想法。尝试使用它们,你会爱上它们。

以上是关于是否可以将 SKSpriteNode 添加到另一个类的场景中?的主要内容,如果未能解决你的问题,请参考以下文章

在触摸时将动画添加到 SKSpriteNode (Swift)

无法将孩子添加到 GameScene,只能添加到 SKSpriteNode

SKSpriteNode 动画渐变

是否可以将一个 cocoapod 包含到另一个 cocoapod 中?

无法将 PhysicsBody 添加到 SKSpriteNode(游戏崩溃)

在屏幕上移动 SKSpriteNode