How to call method from ViewController in GameScene

后端 未结 4 839
遇见更好的自我
遇见更好的自我 2020-12-01 13:21

I have a method that has a custom segue in my viewController that looks like this:

func gameOver() {
    performSegueWithIdentifier(\"GameOver\", sender: nil         


        
相关标签:
4条回答
  • 2020-12-01 13:45

    I don't know if this is still relevant, but I would like to present you a solution to this problem.

    As you can see here Swift iOS: Perform a Segue from an Instance in a ViewController to another ViewController I had the exact same problem some time ago, which I managed to fix using Protocols.

    The problem is, that you can call the "performSegueWithIdentifier("GameOver", sender: nil)" only in your GameViewController Class, but you would like to execute it from your Gamescene.

    Therefor you create in your GameScene a protocol like this:

    @objc protocol GameOverDelegate {
      func gameOverDelegateFunc()
    }
    

    and a variable for the delegate in the Gamescene:

    var gamescene_delegate : GameOverDelegate?
    

    in your GameViewController Class you have to add the delegate in the class definition

    class GameViewController: UIViewController, GameOverDelegate {
    ...
    }
    

    and set the delegate of the scene in the viewDidLoad function of your GameViewController to self:

    scene.gamescene_delegate = self
    

    The last step is to implement the gameOverDelegateFunc() function in your GameViewController:

    func gameOverDelegateFunc() {
       self.performSegueWithIdentifier("GameOver", sender: nil)
    }
    

    This is all you have to do.

    Whenever you want to perform this Segue in your GameScene you just have to call the function through the delegate like this:

    gamescene_delegate?.gameOverDelegateFunc()
    

    I hope that everything is clear and I could help,

    Regards, Phil

    0 讨论(0)
  • 2020-12-01 14:02

    I have done by create protocol, I have 3 game scene (GameScene, GamePlayScene, GameEndScene) and one game controller (GameViewController)

    first create gameProtocol

    protocol GameDelegate {
     func gameOver()
    }
    

    implement protocol in 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)
     }
    }
    

    put delegate property in GameScene class

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

    and put protocol in GamePlayScene too

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

    and last, put delegate property and call gameOver function

    class GameEndScene: SKScene {
         var delegate: GameDelegate?
    
         init(size: CGSize) {
          // call gameOver function
          self.delegate?.gameOver()
         }
       }
    

    Hope that work and can help you

    Sincerely, Donny

    0 讨论(0)
  • 2020-12-01 14:04

    the reason this doesnt work is that you are creating a NEW instance of GameViewController and then you're calling gameOver on that. What you really want to do is reference your existing GameViewController

    theres a few ways to do this, I'll give you one example.

    add a viewController property to your GameScene class

    class GameScene {
    
        // we need to make sure to set this when we create our GameScene
        var viewController: GameViewController!
    

    in your GameViewController file

    // after GameScene is instantiated
    gameScene.viewController = self
    

    now we have a reference to viewController, lets use it in our GameScene class

    // somewhere in GameScene
    self.viewController.gameOver()
    
    0 讨论(0)
  • 2020-12-01 14:04

    I don't have enough rep to reply to your last comment, but if you're still getting that error, that's because you haven't given that segue a name (or identifier) yet in Interface Builder!

    When you click and drag to draw segues between view controllers in Interface Builder, you can select each transition by the circle icon that appears in the center of the segue lines and give it an 'identifier'. Then, when you call performSegueWithIdentifier, it should work!

    This is what the circular icon might look like, depending on the type of segue:

    Segue icon that lets you manage segue properties

    If you're a little unsure of segues, check out this tutorial or this one!

    0 讨论(0)
提交回复
热议问题