在GameOver展示插页式广告后,场景返回到WelcomeScene [英] After Showing Interstitial Ad when GameOver, scene return to WelcomeScene
问题描述
我有一个Sprite Kit游戏,我想在游戏结束时展示插页式广告。好了,我可以在游戏结束后使用 NotificationCenter
来显示广告,但问题是当我关闭广告时,它会返回到WelcomeScene。我想在关闭广告后返回GameOverScene,但如何?
GameViewController.swift
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 NotificationCenter
but 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
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
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)"
}
推荐答案
转到您的 GameViewController
并将所有代码从 ViewWillLayoutSubviews
移到 ViewDidLoad
。 ViewDidLoad
仅在加载 GameViewController
时调用一次。另一方面, ViewWillLayoutSubviews
可以多次调用,例如显示广告时,它将再次加载MenuScene。
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.
因此,添加
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)
您可以如果您想要一个更清洁,更可重用的解决方案,还可以在GitHub上查看我的帮助程序。
You can also check out my helper on GitHub if you want to have a cleaner more reusable solution.
https://github.com/crashoverride777/SwiftyAds
我还注意到您正在使用 .resizeFill
在您的 GameViewController
缩放模式下。您不应该这样做,因为游戏在每台设备上的外观都会有所不同,这将是一场噩梦。您应该使用默认的scaleMode .aspectFill
,通常是最佳设置。
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.
您还应该给场景设置一个固定的大小,而不是根据视图的边界(view.bounds.size)调整大小。
You should also give the scene a fixed size and not size it depending on the bounds of the view (view.bounds.size).
希望这会有所帮助
这篇关于在GameOver展示插页式广告后,场景返回到WelcomeScene的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!