当前位置: 首页 > 面试题库 >

将GameViewController.swift链接到GameScene.swift

葛季萌
2023-03-14
问题内容

我在main.storyboard上创建了一个UIhtml" target="_blank">元素,需要隐藏该元素,直到游戏结束,并且一旦玩家点击屏幕将其关闭即可。Main.storyboard链接到GameViewController,因此我所有的IBOutlet和IBActions都在其中,而我所有的游戏代码都在GameScene中。我如何将视图控制器链接到场景,以便弹出图像和按钮仅在游戏结束时出现。非常感谢您的帮助,我已经坚持了很长时间。


问题答案:

这似乎是SpriteKit游戏存在的一个普遍问题,因此让我们来了解一下SpriteKit游戏和UIKit应用之间的区别。

当您制作常规的UIKit应用程序(例如YouTube,Facebook)时,将对每个看到的屏幕/菜单(主屏幕,频道屏幕,订阅频道屏幕等)使用ViewControllers,CollectionViews,Views等。因此,您将为此使用UIKit
API,例如UIButtons,UIImageViews,UILabels,UIViews,UICollectionViews等。为实现此目的,我们将使用情节提要。

另一方面,在SpriteKit游戏中,它的工作方式有所不同。您可以为看到的每个屏幕使用SKScenes(MenuScene,SettingScene,GameScene,GameOverScene等),并且只有1个ViewController(GameViewController)。带有SKView的GameViewController将显示您的所有SKScenes。

因此,我们应该使用SpriteKit
API(例如SKLabelNodes,SKSpriteNodes,SKNodes等)将UI直接添加到相关的SKScenes中。要在视觉上做到这一点,我们将使用SpriteKit场景级编辑器,而不是故事板。

因此,一般的逻辑是像往常一样从GameViewController加载您的第一个SKScene,然后从相关的SKScenes中加载其余的。除了默认代码外,您的GameViewController基本上应该没有代码。您还可以非常轻松地从一个场景过渡到另一个场景(GameScene->
GameOverScene)。

如果您将GameViewController用于您的UI,那么如果您有多个SKScenes,它将很快变得混乱,因为UI将被添加到GameViewController中,因此将被添加到所有SKScenes中。因此,当您在场景之间切换时,必须删除/显示UI,这很疯狂。

要在SpriteKit中添加标签,应该是这样的

 class GameScene: SKScene {

  lazy var scoreLabel: SKLabelNode = {
      let label = SKLabelNode(fontNamed: "HelveticaNeue")
      label.text = "SomeText"
      label.fontSize = 22
      label.fontColor = .yellow
      label.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
      return label
  }()

  override func didMove(to view: SKView) {

      addChild(scoreLabel)
  }
}

要制作按钮,您实质上是创建一个SKSpriteNode并为其命名,然后在touchesBegan或touchesEnded中寻找它,然后在其上运行SKAction以获得动画和一些代码。

enum ButtonName: String {
     case play
     case share
}

class GameScene: SKScene {

       lazy var shareButton: SKSpriteNode = {
            let button = SKSpriteNode(imageNamed: "ShareButton")
            button.name = ButtonName.share.rawValue
            button.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
            return button
        }()

       override func didMove(to view: SKView) {

             addChild(shareButton)
       }

       /// Touches began
       override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

             for touch in touches {
                 let location = touch.location(in: self)
                 let node = atPoint(location)

                 if let nodeName = node.name {
                      switch nodeName {
                      case ButtonName.play.rawValue:
                          // run some SKAction animation and some code
                      case ButtonName.share.rawValue:

                          let action1 = SKAction.scale(to: 0.9, duration: 0.2)
                          let action2 = SKAction.scale(to: 1, duration: 0.2)
                          let action3 = SKAction.run { [weak self] in
                             self?.openShareMenu(value: "\(self!.score)", image: nil) // image is nil in this example, if you use a image just create a UIImage and pass it into the method
                          }
                          let sequence = SKAction.sequence([action1, action2, action3])
                          node.run(sequence)

                      default: 
                          break
                    }
               }
          }
     }
}

为了使此操作变得更加容易,我将创建一个按钮帮助器类,作为一个简单的示例,请查看此 https://nathandemick.com/2014/09/buttons-sprite-
kit-using-swift/

您还可以查看Apple的示例游戏DemoBots,以获得更多功能丰富的示例。

这样,您可以在助手类中添加动画等内容,而不必为每个按钮重复执行代码。

为了进行共享,我实际上将使用UIActivityController而不是那些可能很快就会弃用的较旧的Social
API。这还允许您通过1个UI共享到多个服务,并且您的应用程序中也只需要1个共享按钮。在您调用它的SKScene中,它可能是一个简单的函数。

func openShareMenu(value: String, image: UIImage?) {
    guard let view = view else { return }

    // Activity items
    var activityItems = [AnyObject]()

    // Text
    let text = "Can you beat my score " + value
    activityItems.append(text as AnyObject)

    // Add image if valid
    if let image = image {
        activityItems.append(image)
    }

    // Activity controller
    let activityController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)

    // iPad settings
    if Device.isPad {
        activityController.popoverPresentationController?.sourceView = view
        activityController.popoverPresentationController?.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
        activityController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.init(rawValue: 0)
    }

    // Excluded activity types
    activityController.excludedActivityTypes = [
        UIActivityType.airDrop,
        UIActivityType.print,
        UIActivityType.assignToContact,
        UIActivityType.addToReadingList,
    ]

    // Present
    view.window?.rootViewController?.present(activityController, animated: true)
}

然后按正确的按钮,这样调用它(请参见上面的示例)

openShareMenu(value: "\(self.score)", image: SOMEUIIMAGE)

希望这可以帮助



 类似资料:
  • 问题内容: 我在运行64位Ubuntu 12.04的桌面上下载并构建了gcc 4.8.1。我像文档建议一样使用命令从源代码中构建它 它似乎通过了所有测试,我将所有内容都安装到了带有后缀-4.8的主目录中,以区别于版本4.6.3的系统gcc。 不幸的是,当我使用g -4.8编译c 程序时,它链接到系统libc和libstdc ,而不是从gcc-4.8.1编译的较新的程序。我下载并构建了gcc 4.8

  • 我正在尝试使用Swing发出文件传输通知。这个想法是,当我的应用程序通过网络提供文件时,用户会收到一个,询问他或她是否想接受所述文件报价,如果他们的答案是是,我想打开一个,以便他们可以浏览到他们想要保存文件的位置。 我遇到的问题是两者单独工作都很好,但是当我设置它们以便打开我的应用程序死锁时。 有人知道这里出了什么问题吗?我尝试了调试,但没有发现任何奇怪的行为来表明它为什么会死锁。 编辑:下面的示

  • 问题内容: 我已经从源代码构建了OpenSSL(一个有意的旧版本;使用来构建),并且更愿意使用我所构建的内容,而不用链接到我的程序。 失败的命令是: 并且我收到一系列类似于以下的错误: 这使我认为我的OpenSSL有点时髦。如果我从命令中省略,则错误变为无法执行以下操作: 我是否编译不正确的OpenSSL?还是我应该如何最好地解决这个问题? 问题答案: 愚蠢的“ Linux-isms”再次罢工!很

  • 嗨,我在创建一个新项目时遇到了麻烦。我无法将JDK链接到IDE。 这里有一个与java相关的my env变量: JAVA主页:/usr/lib64/jvm/jre-1.8.0-openjdk 我该用什么?

  • Attaching models to data sources(将model 链接到数据源) 简介 添加一个数据源 添加数据源凭据 制作模型使用的数据源 简介 数据源让 model 得以在后端系统的访问和修改数据,例如关系型数据库。 数据源封装了 model 到 各种后端系统(数据库) 之间的交换数据逻辑。(ORM) 数据来源一般提供创建,检索,更新和删除(CRUD)功能。 Model 通过 c

  • 问题内容: 因此,如果我进入QtDesigner并构建UI,它将被另存为.ui文件。如何将其作为python文件或在python中使用? 问题答案: 在代码中使用.ui的另一种方法是: 两种方法都很好。不要忘记,如果您将Qt资源文件(极其有用)用于图标等,则也必须对其进行编译: 注意,在编译接口时,它将在.py文件的末尾添加“ import images_rc”,因此您必须使用此名称将资源编译到文