【问题标题】:Passing variable from UIViewController to SK Scene将变量从 UIViewController 传递到 SK 场景
【发布时间】:2015-09-19 19:47:32
【问题描述】:

我正在使用 Swift 2 在 XCode 7 中制作游戏。我有一个变量,我想将其从开始屏幕(即 UIViewController)传递到游戏场景(即 SKScene)。我希望玩家在 UIView 中选择一个角色并在 SKScene 中使用它。我还希望 SKScene 中的分数显示在 UIView 的游戏结束屏幕中。我已经看过在两个 UIViewController 之间和两个 SKScene 之间传递数据的教程,但它们都不适用于这种情况。

如何将变量从 UIViewController 传递到 SKScene(反之亦然)?

【问题讨论】:

  • 应该类似于从视图控制器设置游戏场景的变量(查看视图控制器的代码以了解创建游戏场景的位置)。要从游戏场景在视图控制器中设置变量,请将视图控制器的引用传递给游戏场景,然后使用视图控制器设置变量。
  • 你的 SKView 展示你的 SKScene 不是由 View Controller 控制吗?这就像使用 subViews... Gliderman 有正确的想法
  • @MaxKargin 不,我真正想做的是在 UIView 中选择一个角色,然后在由 SKScene 文件控制的实际游戏中显示该角色。
  • @Gabe12 然后照我说的做(我没有方便的 Swift 2 来提供正确的语法,这就是为什么将其写为注释的原因)。在SKScene 中创建一个方法或其他东西,它接受一个字符串并将其用作创建SKSpriteNode(或您正在使用的任何东西)的文件名。选择角色后,使用图像文件名调用方法,然后开始运行游戏。您可能需要从didMoveToView 移动一些代码,但您可能不需要太多。

标签: ios xcode swift uiview sprite-kit


【解决方案1】:

如果您还没有找到答案,我确实找到了解决方法。我正在做一些非常相似的事情。

在我的情况下,我有一个 UIView,它在我的场景中被称为暂停菜单。我已经使类和变量名称更加模糊,因此它们也可以适用于您的情况。

class MyView: UIView {
    var scene: MyScene!
    var button: UIButton!
    init(frame: CGRect, scene: MyScene){
        super.init(frame: frame)
        self.scene = scene
        //initialize the button
        button.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "buttonTapped"))
    }

    func buttonTapped(){
        self.removeFromSuperview() // this removes my menu from the scene
        scene.doTheThing() // this calls the method on my scene
}

这是我的场景的相关部分。

class MyScene: SKScene {

    func doTheThing(){
         //this is a function on the scene. You can pass any variable you want through the function. 
    }
}

在您的情况下,听起来第一个屏幕是 UIView,第二个屏幕是 SKScene。

您可能希望先制作 SKScene,暂停它,然后在场景前面添加 UIView。选择角色后,您可以移除 UIView 并将您的角色添加到场景中。

我希望这能回答您的问题。如果它不让我知道。

【讨论】:

    【解决方案2】:

    我昨天也遇到了同样的问题。

    Swift 5.2、xcode 12 和面向 iOS 14。搜索高低。最终找到了SKScene的userData属性。

    注意:该应用基于 SwiftUI,SKScene 位于 UIViewRepresentable 中:

    struct SpriteKitContainer: UIViewRepresentable {
        typealias UIViewType = SKView
        
        var skScene: SKScene!
        @Binding var timerData :  ModelProgressTimer
    

    并不是我将绑定传递给视图 - 它包含许多我想提供给场景的数据项。

    我在两个地方放置了代码来填充 skScene.userData:

    func makeUIView(context: Context) -> SKView {
        self.skScene.scaleMode = .resizeFill
        self.skScene.backgroundColor = .green
        debugPrint("setting user data")
    
        self.skScene.userData = [:]
        self.skScene.userData!["color"] = UIColor(timerData.flatColorTwo!)
        self.skScene.userData!["running"] = timerData.isRunning
        self.skScene.userData!["percent"] = timerData.percentComplete
    
        let view = SKView(frame: .zero)
        view.preferredFramesPerSecond = 60
       // view.showsFPS = true
       // view.showsNodeCount = true
        view.backgroundColor = .clear
        view.allowsTransparency = true
        
        return view
    }
    
    func updateUIView(_ view: SKView, context: Context) {
        self.skScene.userData = [:]
        
        self.skScene.userData!["running"] = timerData.isRunning
        self.skScene.userData!["color"] = UIColor(timerData.flatColorTwo!)
        self.skScene.userData!["percent"] = timerData.percentComplete
        view.presentScene(context.coordinator.scene)
    }
    

    然后,在 skScene 对象中,我可以检索 userData 值:

       var item: SKShapeNode! = nil
    
       override func sceneDidLoad() {
           let scaleUp = SKAction.scale(by: 2.0, duration: 1.0)
           let scaleDown = SKAction.scale(by: 0.5, duration: 1.0)
            
           scaleUp.timingMode = .easeInEaseOut
           scaleDown.timingMode = .easeInEaseOut
           let sequence = SKAction.sequence([scaleUp,scaleDown])
    
           actionRepeat = SKAction.repeatForever(sequence)
    
           item = SKShapeNode(circleOfRadius: radius)
           addChild(item)
        }
    
    override func didChangeSize(_ oldSize: CGSize) {
    
       item.fillColor = self.userData!["color"] as! UIColor
       item.strokeColor = .clear
                    
       let meRunning = self.userData!["running"] as! Bool
                    
       if meRunning {
             item.run(actionRepeat)        
       } else {
            item.removeAllActions()  
       }
    }
    

    如果在用户数据中设置了“运行”布尔值(一个布尔值),则会绘制一个“脉冲”的圆圈。

    【讨论】:

      猜你喜欢
      • 2014-03-27
      • 1970-01-01
      • 2013-10-06
      • 2021-01-31
      • 2019-10-31
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多