将 GameViewController.swift 链接到 GameScene.swift [英] linking GameViewController.swift to GameScene.swift

查看:17
本文介绍了将 GameViewController.swift 链接到 GameScene.swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 main.storyboard 上创建了一个 UI 元素,我需要将其隐藏到游戏结束并且一旦玩家点击屏幕即可关闭.Main.storyboard 链接到 GameViewController,因此我所有的 IBOutlets 和 IBAction 都在其中,我所有的游戏代码都在 GameScene 中.我如何将视图控制器链接到场景,因为弹出图像和按钮仅在游戏结束时出现.非常感谢一些帮助,我已经坚持了很长一段时间了.

I have created a UI elements on main.storyboard which i require to be hidden until the game is over and the once the player tap the screen to dismiss. Main.storyboard is linked to GameViewController therefor all my IBOutlets and IBActions are in there and all my game code is in GameScene. How can i link the view controller to the scene for that the popup image and buttons only appear when it is game over. Would greatly appreciate some help, I have been stuck on this for quite some time now.

推荐答案

这似乎是人们在使用 SpriteKit 游戏时很常见的问题,所以让我们来看看 SpriteKit 游戏和 UIKit 应用程序之间的区别.

This seems to be quite a common problem people have with SpriteKit games so lets go through the difference between SpriteKit games and UIKit apps.

当你制作一个常规的 UIKit 应用程序时,例如YouTube、Facebook,您将为您看到的每个屏幕/菜单(主屏幕、频道屏幕、订阅频道屏幕等)使用 ViewControllers、CollectionViews、Views 等.因此,您可以为此使用 UIKit API,例如 UIButtons、UIImageViews、UILabels、UIViews、UICollectionViews 等.为了直观地做到这一点,我们将使用故事板.

When you make a regular UIKit app, e.g. YouTube, Facebook, you would use ViewControllers, CollectionViews, Views etc for each screen/menu that you see (Home screen, Channel screen, Subscription channel screen etc). So you would use UIKit APIs for this such as UIButtons, UIImageViews, UILabels, UIViews, UICollectionViews etc. To do this visually we would use storyboards.

另一方面,在 SpriteKit 游戏中,它的工作方式有所不同.您为您看到的每个屏幕(MenuScene、SettingsScene、GameScene、GameOverScene 等)使用 SKScene,并且只有 1 个 ViewController (GameViewController).包含 SKView 的 GameViewController 将呈现您的所有 SKScene.

In SpriteKit games on the other hand it works differently. You work with SKScenes for each screen that you see (MenuScene, SettingsScene, GameScene, GameOverScene etc) and only have 1 ViewController (GameViewController). That GameViewController, which has a SKView in it, will present all your SKScenes.

因此,我们应该使用 SpriteKit API(例如 SKLabelNodes、SKSpriteNodes、SKNodes 等)将我们的 UI 直接添加到相关的 SKScene 中.要直观地做到这一点,我们将使用 SpriteKit 场景关卡编辑器而不是情节提要.

So we should add our UI directly in the relevant SKScenes using SpriteKit APIs such as SKLabelNodes, SKSpriteNodes, SKNodes etc. To do this visually we would use the SpriteKit scene level editor and not storyboards.

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

So the general logic would be to load your 1st SKScene as usual from the GameViewController and than do the rest from within the relevant SKScenes. Your GameViewController should basically have next to no code in it beyond the default code. You can also transition from 1 scene to another scene very easily (GameScene -> GameOverScene).

如果您将 GameViewController 用于您的 UI,如果您有多个 SKScene,它会很快变得混乱,因为 UI 将被添加到 GameViewController 并因此添加到所有 SKScene.因此,当您在场景之间转换时,您将不得不删除/显示 UI,这将是疯狂的.

If you use GameViewController for your UI it will get messy really quickly if you have multiple SKScenes because UI will be added to GameViewController and therefore all SKScenes. So you would have to remove/show UI when you transition between scenes and it would be madness.

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

To add a label in SpriteKit it would be something like this

 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 以获取动画和一些代码.

To make buttons you essentially create a SKSpriteNode and give it a name and then look for it in touchesBegan or touchesEnded and run an SKAction on it for animation and some code after.

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/

To make this even easier I would create a button helper class, for a simple example have a look at this https://nathandemick.com/2014/09/buttons-sprite-kit-using-swift/

您还可以查看 Apple 的示例游戏 DemoBots,了解功能更丰富的示例.

You can also check out Apple's sample game DemoBots for a more feature rich example.

这样您就可以在帮助类中包含动画等内容,而不必为每个按钮重复代码.

This way you can have things such as animations etc in the helper class and don't have to repeat code for each button.

为了分享,我实际上会使用 UIActivityController 而不是那些可能很快就会被弃用的旧社交 API.这也允许您通过 1 个 UI 共享到多个服务,并且您的应用中也只需要 1 个共享按钮.在您调用它的 SKScene 中,它可能是一个像这样的简单函数.

For sharing, I would actually use UIActivityController instead of those older Social APIs which might become deprecated soon. This also allows you to share to multiple services via 1 UI and you will also only need 1 share button in your app. It could be a simple function like this in the SKScene you are calling it from.

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)
}

然后在按下正确的按钮时调用它(参见上面的示例)

and then call it like so when the correct button was pressed (see above example)

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

希望对你有帮助

这篇关于将 GameViewController.swift 链接到 GameScene.swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆