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

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

问题描述

我在main.storyboard上创建了一个UI元素,我需要将其隐藏起来,直到游戏结束,玩家点击屏幕才能解散。 Main.storyboard链接到GameViewController,因为我所有的IBOutlets和IBActions都在那里,我所有的游戏代码都在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游戏中另一方面它的工作方式不同您可以使用SKScenes查看您看到的每个屏幕(MenuScene,SettingsScene,GameScene,GameOverScene等),并且只有1个ViewController(GameViewController)。 GameViewController中有一个SKView,它将显示你所有的SKScenes。

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直接在相关的SKScenes中添加我们的UI,例如SKLabelNodes,SKSpriteNodes ,SKNodes等。为了做到这一点,我们将使用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,而不是从相关的SKScenes中加载其余的。除了默认代码之外,你的GameViewController基本上应该没有代码。你也可以很容易地从1个场景转换到另一个场景(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).

如果你的UI使用GameViewController它会很快变得混乱如果你有多个SKScenes,因为UI将添加到GameViewController,因此所有SKScenes。所以你必须在场景之间转换时删除/显示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:// nathan demick.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天全站免登陆