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

标签 swift sprite-kit game-center xcode7

我使用 SpriteKit 和 Xcode 7 beta 制作了一款游戏。我尝试放置 GameCenter 和 Leaderboard,但问题是排行榜中的分数不会改变它一直保持 0(游戏的高分不会保存在 Leaderboard 中)而且我不知道如何解决它。我使用了 3 个不同的文件:GameScene.swiftGameViewController.swiftPointsLabel.swift

GameScene.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")
            }
        })
    }
}

希望日志中打印出或不打印出的内容加上实际保存您的默认设置会有所帮助。祝你好运。

编辑

所以问题的根源似乎是您的 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()

}

希望这能解决所有问题 =)

关于swift - 如何使用 Swift 将游戏的高分保存在排行榜上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32145090/

相关文章:

swift - 为什么可以不实现 UIGestureRecognizerDelegate 协议(protocol)的所有方法?

iOS将tableview单元格信息获取到按钮功能中

objective-c - 明确回答 playerToInvite 的用途

iphone - iOS GameCenter 匹配器不工作

xcode - 更新至5.1,现在Game Center推送通知不起作用。

swift - 在 Swift 中通过 URL 启动 Safari(不是默认浏览器)?

arrays - 如何尽可能简单地在没有 .shuffle 的情况下随机播放一组图像 - 没什么复杂的

ios - 我如何引用 GameScene.swift 文件作为其余游戏关卡的基础?

ios - swift : Background Color fading animation (SpriteKit)

swift - 有没有办法测试 skspritenode 的位置字段的 if ?