After Showing Interstitial Ad when GameOver, scene return to WelcomeScene

一曲冷凌霜 提交于 2019-12-12 02:32:52

问题


I have a sprite kit game and I want to show interstitial ad when the game is over. Well, I am able to show the ad after when the game over using NotificationCenterbut the problem is that when the I close the ad, it returns to the WelcomeScene. I want to return to the GameOverScene after closing the ad but how? GameViewController.swift

import UIKit
import SpriteKit
import GameplayKit
import GoogleMobileAds

class GameViewController: UIViewController , GADInterstitialDelegate {


var interstitialAds : GADInterstitial!


override func viewDidLoad() {
    super.viewDidLoad()



    createAndLoadAd()
    NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.showAds), name: NSNotification.Name("notification"), object: nil)


}


func createAndLoadAd(){
    let request = GADRequest()
    let interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
    request.testDevices = [kGADSimulatorID]
    interstitial.delegate = self
    interstitial.load(request)
    interstitialAds = interstitial
}

func showAds(){

    if interstitialAds.isReady {
        interstitialAds.present(fromRootViewController: self)
    }
}

func interstitialDidDismissScreen(_ ad: GADInterstitial) {
    createAndLoadAd()
}


override var shouldAutorotate: Bool {
    return true
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    if UIDevice.current.userInterfaceIdiom == .phone {
        return .allButUpsideDown
    } else {
        return .all
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Release any cached data, images, etc that aren't in use.
}

override var prefersStatusBarHidden: Bool {
    return true
}

override func viewWillLayoutSubviews() {

    super.viewWillLayoutSubviews()

    let menu = Menu()
    let skView = self.view as! SKView

    skView.ignoresSiblingOrder = true

    menu.size = view.bounds.size
    menu.scaleMode = SKSceneScaleMode.resizeFill
    skView.presentScene(menu)


}

}

GameScene.swift

    func gameOver(){

    NotificationCenter.default.post(name: NSNotification.Name("notification"), object: nil)

    //reset everything
    self.run(SKAction.playSoundFileNamed("Sound/die.wav", waitForCompletion: false))
    hud.updateScore(score: Int(score))


    player.die()
    hud.showScore()
    hud.showRestartMenu()



}   

HUD.swift

    import SpriteKit

    class HUD : SKNode {
    var scoreLabel = SKLabelNode(text: "0")
    let restartBut = SKSpriteNode()
    let menuBut = SKSpriteNode()
    let highScoreLabel = SKLabelNode()

    func createNode(screenSize : CGSize){

    scoreLabel.fontName = "AppleSDGothicNeo-SemiBold"
    scoreLabel.position = CGPoint(x: (screenSize.width / 2) - (screenSize.width / 4 * 2) , y: (screenSize.height / 2) - 50)
    scoreLabel.fontColor = UIColor.black
    scoreLabel.fontSize = 40
    scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
    scoreLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
    scoreLabel.zPosition = 50
    self.addChild(scoreLabel)

     //Restart and Menu button
    restartBut.texture = SKTexture(imageNamed: "restartButton")
    restartBut.name = "restartButton"
    restartBut.position = CGPoint(x: 0, y: 0)
    restartBut.zPosition = 50
    restartBut.size = CGSize(width: 400, height: 400)

    menuBut.texture = SKTexture(imageNamed: "menuButton")
    menuBut.name = "menuButton"
    menuBut.position = CGPoint(x: 0, y: -300)
    menuBut.zPosition = 50
    menuBut.size = CGSize(width: 150, height: 150)

    highScoreLabel.fontName = "AppleSDGothicNeo-SemiBold"
    highScoreLabel.position = CGPoint(x: 0, y: 450)
    highScoreLabel.fontColor = UIColor.black
    highScoreLabel.fontSize = 45
    highScoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
    highScoreLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
    highScoreLabel.zPosition = 50
    }

    func showRestartMenu(){

    restartBut.alpha = 0
    menuBut.alpha = 0
    highScoreLabel.alpha = 0

    self.addChild(restartBut)
    self.addChild(menuBut)
    self.addChild(highScoreLabel)

    restartBut.run(SKAction.fadeAlpha(to: 1, duration: 0.35))
    menuBut.run(SKAction.fadeAlpha(to: 1, duration: 0.35))
    highScoreLabel.run(SKAction.fadeAlpha(to: 1, duration: 0.35))





    }

    func updateScore(score : Int){
    var highScore = UserDefaults().integer(forKey: "highScore")
    let number = NSNumber(value: score)
    let formatter = NumberFormatter()

    if let scoreText = formatter.string(from: number){
        scoreLabel.text = scoreText
    }




    if Int(score) > highScore {
        highScore = Int(score)
        highScoreLabel.text = NSString.init(format: "Highscore : %i", highScore) as String

        let highScoreDefs = UserDefaults.standard
        highScoreDefs.set(highScore, forKey: "highScore")
        highScoreDefs.synchronize()

    }

    highScoreLabel.text = "Highscore : \(highScore)"

}

回答1:


Go to your GameViewController and move all the code from ViewWillLayoutSubviews into ViewDidLoad. ViewDidLoad is only called once when the GameViewController loads. ViewWillLayoutSubviews on the other hand can be called multiple times, like when your ad is shown, which will than load your MenuScene again.

As a tip you should put your notification keys into an extension to avoid typos and be more specific with the names as a matter of good practice.

So add this above any class or in a new swift file

extension Notification.Name {
    static let showAd = Notification.Name("ShowAdNotification")
}

Than you can change your observers to this

NotificationCenter.default.addObserver(self, selector: #selector(showAds), name: .showAd, object: nil)

NotificationCenter.default.post(name: .showAd, object: nil)

You can also check out my helper on GitHub if you want to have a cleaner more reusable solution.

https://github.com/crashoverride777/SwiftyAds

I also noticed that you are using .resizeFill in your GameViewController scale mode. You should not do this, your game will look different on each device and it will be a nightmare to manage. You should use the default scaleMode .aspectFill which is usually the best setting.

You should also give the scene a fixed size and not size it depending on the bounds of the view (view.bounds.size).

How to make SKScene have fixed width?

How do I size sprites in a universal sprite kit game

Hope this helps



来源:https://stackoverflow.com/questions/43490200/after-showing-interstitial-ad-when-gameover-scene-return-to-welcomescene

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!