如何从GameScene中的ViewController调用方法

Jon*_* H. 8 uiviewcontroller ios sprite-kit skscene swift

我有一个方法,在我的viewController中有一个自定义segue,如下所示:

func gameOver() {
    performSegueWithIdentifier("GameOver", sender: nil)
}
Run Code Online (Sandbox Code Playgroud)

我在GameScene.swift中调用了这样的方法:

 GameViewController().gameOver()
Run Code Online (Sandbox Code Playgroud)

我仔细检查了segue的名字,这是正确的.每当我在我的GameScene.swift文件中调用它时,我得到SIGABRT消息,我不知道为什么.我尝试只使用println()消息调用该函数,并且它有效.

关于为什么会发生这种情况以及如何在GameScene.swift文件中成功调用该方法的任何建议将不胜感激.

谢谢!

PS这里是崩溃日志:

2015-01-28 21:59:46.181 RunawaySquare[95616:3907041] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<RunawaySquare.GameViewController: 0x7fe4305c7890>) has no segue with identifier 'GameEnd''
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010d461f35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010f39ebb7 objc_exception_throw + 45
    2   UIKit                               0x000000010e20dd3b -[UIViewController shouldPerformSegueWithIdentifier:sender:] + 0
    3   RunawaySquare                       0x000000010d2683b2 _TFC13RunawaySquare18GameViewController8gameOverfS0_FT_T_ + 914
    4   RunawaySquare                       0x000000010d261af0 _TFC13RunawaySquare9GameScene12touchesBeganfS0_FTCSo5NSSet9withEventCSo7UIEvent_T_ + 1808
    5   RunawaySquare                       0x000000010d261c3f _TToFC13RunawaySquare9GameScene12touchesBeganfS0_FTCSo5NSSet9withEventCSo7UIEvent_T_ + 79
    6   SpriteKit                           0x000000010df4d7e1 -[SKView touchesBegan:withEvent:] + 946
    7   UIKit                               0x000000010e12d16e -[UIWindow _sendTouchesForEvent:] + 325
    8   UIKit                               0x000000010e12dc33 -[UIWindow sendEvent:] + 683
    9   UIKit                               0x000000010e0fa9b1 -[UIApplication sendEvent:] + 246
    10  UIKit                               0x000000010e107a7d _UIApplicationHandleEventFromQueueEvent + 17370
    11  UIKit                               0x000000010e0e3103 _UIApplicationHandleEventQueue + 1961
    12  CoreFoundation                      0x000000010d397551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    13  CoreFoundation                      0x000000010d38d41d __CFRunLoopDoSources0 + 269
    14  CoreFoundation                      0x000000010d38ca54 __CFRunLoopRun + 868
    15  CoreFoundation                      0x000000010d38c486 CFRunLoopRunSpecific + 470
    16  GraphicsServices                    0x000000011480e9f0 GSEventRunModal + 161
    17  UIKit                               0x000000010e0e6420 UIApplicationMain + 1282
    18  RunawaySquare                       0x000000010d26cbee top_level_code + 78
    19  RunawaySquare                       0x000000010d26cc2a main + 42
    20  libdyld.dylib                       0x000000010fb8a145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Run Code Online (Sandbox Code Playgroud)

它说没有segue id.使用"GameEnd",但有一个,如果在viewcontroller上使用它可以工作

ham*_*obi 26

这不起作用的原因是你正在创建一个新的实例GameViewController然后你正在调用gameOver它.你真正想要做的是参考你现有的GameViewController

有几种方法可以做到这一点,我举一个例子.

将viewController属性添加到GameScene类

class GameScene {

    // we need to make sure to set this when we create our GameScene
    var viewController: GameViewController!
Run Code Online (Sandbox Code Playgroud)

在你的GameViewController文件中

// after GameScene is instantiated
gameScene.viewController = self
Run Code Online (Sandbox Code Playgroud)

现在我们引用了viewController,让我们在GameScene类中使用它

// somewhere in GameScene
self.viewController.gameOver()
Run Code Online (Sandbox Code Playgroud)

  • 我知道两年前有人问过这个问题,但是Gould你能详细描述一下GameScene是用gameScene.viewController = self来实现的吗? (2认同)

小智 6

我通过创建协议完成,我有3个游戏场景(GameScene,GamePlayScene,GameEndScene)和一个游戏控制器(GameViewController)

首先创建gameProtocol

protocol GameDelegate {
 func gameOver()
}
Run Code Online (Sandbox Code Playgroud)

在GameViewController中实现协议

class GameViewController: UIViewController, GameDelegate {
override func viewDidLoad() {
 super.viewDidLoad()
 let scene = GameScene(size: skView.bounds.size)
        scene.scaleMode = .AspectFill
        scene.delegate = self
 }

 // MARK: Game Delegate
 func gameOver() {
    self.performSegueWithIdentifier("yoursegue", sender: self)
 }
}
Run Code Online (Sandbox Code Playgroud)

将委托属性放在GameScene类中

class GameScene: SKScene {
 var delegate: GameDelegate?

 // call GamePlayScene and put delegate property
 func redirectToPlay() {
        let transition = SKTransition.pushWithDirection(SKTransitionDirection.Left, duration: 1.0)
        let menuScene = GamePlayScene(size: size)
         menuScene.delegate = self.delegate
        self.view?.presentScene(menuScene, transition: transition)
   }
}
Run Code Online (Sandbox Code Playgroud)

并将协议放在GamePlayScene中

class GamePlayScene: SKScene {
     var delegate: GameDelegate?

     // call GameEndScene and put delegate property
     func gameScore() {
            let transition = SKTransition.pushWithDirection(SKTransitionDirection.Left, duration: 1.0)
            let menuScene = GameEndScene(size: size)
             menuScene.delegate = self.delegate
            self.view?.presentScene(menuScene, transition: transition)
       }
    }
Run Code Online (Sandbox Code Playgroud)

最后,放置委托属性并调用gameOver函数

class GameEndScene: SKScene {
     var delegate: GameDelegate?

     init(size: CGSize) {
      // call gameOver function
      self.delegate?.gameOver()
     }
   }
Run Code Online (Sandbox Code Playgroud)

希望工作能够帮到你

真诚的,唐尼