我有一个 sprite kit 游戏,我想在游戏结束时展示插页式广告。好吧,我可以在游戏结束后使用 NotificationCenter
显示广告,但问题是当我关闭广告时,它会返回到 WelcomeScene。我想在关闭广告后返回到 GameOverScene,但如何?
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)
}
游戏场景.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)"
}
最佳答案
转到您的 GameViewController
并将所有代码从 ViewWillLayoutSubviews
移到 ViewDidLoad
中。 ViewDidLoad
仅在 GameViewController
加载时调用一次。另一方面,ViewWillLayoutSubviews
可以被调用多次,比如当您的广告显示时,它会再次加载您的 MenuScene。
作为一个提示,您应该将通知键放入扩展中以避免拼写错误,并且作为一种良好做法,请更具体地使用名称。
所以将它添加到任何类之上或在新的 swift 文件中
extension Notification.Name {
static let showAd = Notification.Name("ShowAdNotification")
}
比起你可以改变你的观察者
NotificationCenter.default.addObserver(self, selector: #selector(showAds), name: .showAd, object: nil)
NotificationCenter.default.post(name: .showAd, object: nil)
如果你想要一个更干净、更可重用的解决方案,你也可以在 GitHub 上查看我的助手。
https://github.com/crashoverride777/SwiftyAds
我还注意到您在 GameViewController
缩放模式中使用了 .resizeFill
。你不应该这样做,你的游戏在每台设备上看起来都不一样,这将是一场噩梦。您应该使用默认的 scaleMode .aspectFill
,这通常是最佳设置。
您还应该给场景一个固定的大小,而不是根据 View 的边界 (view.bounds.size) 调整它的大小。
How to make SKScene have fixed width?
How do I size sprites in a universal sprite kit game
希望对你有帮助
关于swift - GameOver Showing Interstitial Ad 后,场景回到 WelcomeScene,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43490200/