如何使用 Swift 将高分游戏保存在排行榜上?

2024-05-26

我使用 SpriteKit 和 Xcode 7 beta 制作了一个游戏。我尝试放置 GameCenter 和 Leaderboard,但问题是排行榜中的分数不会改变,它始终保持 0(游戏的高分不会保存在 Leaderboard 中),我不知道如何修复它。我使用 3 个不同的文件:游戏场景.swift, GameViewController.swift, and PointsLabel.swift.

游戏场景.swift

func addPointsLabels() {
    let pointsLabel = PointsLabel(num: 0)
    pointsLabel.position = CGPointMake(30.0, view!.frame.size.height - 40)
    pointsLabel.name = "pointsLabel"
    addChild(pointsLabel)


    //High Score
    let highscoreLabel = PointsLabel(num: 0)
    highscoreLabel.name = "highscoreLabel"
    highscoreLabel.position = CGPointMake(view!.frame.size.width - 35, view!.frame.size.height - 40)
    addChild(highscoreLabel)
}


func loadHighscore() {
    let defaults = NSUserDefaults.standardUserDefaults()

    let highscoreLabel = childNodeWithName("highscoreLabel") as! PointsLabel
    highscoreLabel.setTo(defaults.integerForKey("highscore"))
}

GameViewController.swift:

import GameKit

class GameViewController: UIViewController,UIGestureRecognizerDelegate, GKGameCenterControllerDelegate {

var scoreManager = PointsLabel(num: 0)

override func viewDidLoad() {
    super.viewDidLoad()

    //initiate gamecenter
func authenticateLocalPlayer(){

    let localPlayer = GKLocalPlayer.localPlayer()

    localPlayer.authenticateHandler = {(GameViewController, error) -> Void in

        if (GameViewController != nil) {
            self.presentViewController(GameViewController!, animated: true, completion: nil)
        }

        else {
            print((GKLocalPlayer.localPlayer().authenticated))
        }
     }
  }
}

@IBAction func leaderboard(sender: UIButton) {

    saveHighscore(scoreManager.score)

    scoreManager.increment()

    showLeader()

}



//send high score to leaderboard
func saveHighscore(score:Int) {

    //check if user is signed in
    if GKLocalPlayer.localPlayer().authenticated {

        let scoreReporter = GKScore(leaderboardIdentifier: "Leaderboard_01")

        scoreReporter.value = Int64(score)

        let scoreArray: [GKScore] = [scoreReporter]

        GKScore.reportScores(scoreArray, withCompletionHandler: {error -> Void in
            if error != nil {
                print("error")
            }
        })
    }
}


    //shows leaderboard screen
    func showLeader() {
        let vc = self.view?.window?.rootViewController
        let gc = GKGameCenterViewController()
        gc.gameCenterDelegate = self
        vc?.presentViewController(gc, animated: true, completion: nil)
    }
}

//hides leaderboard screen
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController)
{
    gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)

}

PointsLabel.swift:

import Foundation
import UIKit
import SpriteKit

class PointsLabel: SKLabelNode {

var score:Int = 0

init(num: Int) {
    super.init()

    fontColor = UIColor.blackColor()
    fontSize = 30.0

    score = num
    text = "\(num)"
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func increment() {
    score++
    text = "\(score)"
}

func setTo(num: Int) {
    self.score = num
    text = "\(self.score)"
 }
}

我认为问题出在文件 GameViewController.swift 的代码中:

@IBAction func leaderboard(sender: UIButton) {

    saveHighscore(scoreManager.score)

    scoreManager.increment() //<-- Here

    showLeader()

}

也许我没有把它放在正确的地方

    scoreManager.increment()

嗯,我发现有几件事可能会导致这个问题。首先是这个方法...

func loadHighscore() {
    let defaults = NSUserDefaults.standardUserDefaults()

    let highscoreLabel = childNodeWithName("highscoreLabel") as! PointsLabel
    highscoreLabel.setTo(defaults.integerForKey("highscore"))
}

我没有看到你在任何地方设置它,所以把它拉出来并没有多大帮助。我在 saveHighscore: 函数中将保存添加到默认值。

其次是...

saveHighscore(scoreManager.score)

scoreManager.increment() //<-- Here

showLeader()

您应该在保存分数之前递增。

我会尝试添加这些日志,看看这是否有帮助......

func saveHighscore(score:Int) {

    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setInteger(score, forKey: "highscore")
    defaults.synchronize()

    //check if user is signed in
    if GKLocalPlayer.localPlayer().authenticated {

        println("authenticated")

        let scoreReporter = GKScore(leaderboardIdentifier: "Leaderboard_01")
        println("ScoreReporter: \(scoreReporter)")

        scoreReporter.value = Int64(score)

        let scoreArray: [GKScore] = [scoreReporter]

        GKScore.reportScores(scoreArray, withCompletionHandler: {error -> Void in
            if error != nil {
                print("error")
            }
            else{
                println("reported correctly")
            }
        })
    }
}

希望日志中打印或不打印的内容以及实际保存默认值会有所帮助。祝你好运。

Edit

所以看来问题的根源在于你的 VC 中有 ScoreManager (这是一个 PointsLabel),但你的场景中也有一个。您正在更新乐谱的场景中的场景和生活都很好。当您点击按钮时,您实际上是从 VC 中的标签获得分数,但该分数并未更新。因此,您真正需要的是在场景中找到该标签来提取乐谱。

因此,我能想到的使其在对代码进行少量更改的情况下正常工作的最简单方法是......

完全删除此行...

var scoreManager = PointsLabel(num: 0)

并将你的行动改为这样......

@IBAction func leaderboard(sender: UIButton) {

    let skView = self.view as! SKView
    let scene = skView.scene
    let scoreManager = scene.childNodeWithName("pointsLabel") as! PointsLabel

    saveHighscore(scoreManager.score)

    showLeader()

}

希望这能解决一切=)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Swift 将高分游戏保存在排行榜上? 的相关文章

随机推荐