如何使Swift的高得分游戏保存在排行榜上? [英] How to make High Score of game to be saved on Leaderboard, with Swift?

查看:75
本文介绍了如何使Swift的高得分游戏保存在排行榜上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用SpriteKit和Xcode 7 Beta开发了一款游戏.我尝试放置GameCenter和排行榜,但问题是排行榜中的得分不会一直保持为0(游戏的高分不会保存在排行榜中),而且我不知道如何解决.我正在使用3个不同的文件: GameScene.swift GameViewController.swift PointsLabel.swift .

I made a game using SpriteKit and Xcode 7 beta. I tried to put GameCenter and Leaderboard but the problem is that the score in leaderboard won't change it stay all the time 0 (High Score of game won't save in Leaderboard) and I don't know how to fix it. I'm using 3 different files: GameScene.swift, GameViewController.swift, and PointsLabel.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文件中:

I think the problem is in file GameViewController.swift in code:

@IBAction func leaderboard(sender: UIButton) {

    saveHighscore(scoreManager.score)

    scoreManager.increment() //<-- Here

    showLeader()

}

也许我没有把它放在正确的位置

Maybe I didn't put it in right place

    scoreManager.increment()

推荐答案

好吧,我看到了一些可能导致此问题的原因.首先是这种方法...

Well I see a couple things that can contribute to the issue. First is this method...

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

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

我看不到您要设置的任何位置,因此将其拉出并不会有多大帮助.我在以下的saveHighscore:函数中将保存添加为默认值.

I don't see anywhere you are setting that so pulling it out won't help much. I added the saving to defaults in the saveHighscore: function bellow.

第二个是...

saveHighscore(scoreManager.score)

scoreManager.increment() //<-- Here

showLeader()

在保存分数之前,您应该先增加数字.

You should increment before you save your score.

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

I would try adding these logs to see if this helps...

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

希望在日志中打印出或不打印出什么内容,以及实际保存默认值将有所帮助.祝你好运.

Hopefully what does or don't print out in the logs plus actually saving your defaults will help. Good luck.

修改

因此,问题的根源似乎是您的VC中有scoreManager(这是一个PointsLabel),但您的Scene中也有一个.您正在场景中的那一位正在更新乐谱,生活是美好的.当您按下按钮时,实际上是从VC中未更新的标签中获得分数.因此,您真正需要的是在场景中找到该标签以拔出分数.

So it appears the root of the problem is that you have scoreManager (which is a PointsLabel) in your VC but you also have one that is in your Scene. The one in your scene you are updating the score and life is good. When you hit the button you are actually getting the score from the label in your VC that isn't getting updated. So what you really need is to get to that label in your scene to pull out the score.

因此,我想通过最少的代码更改就能使其正常工作的最简单方法是……

So the easiest way I can think of getting it to work properly with as little changes to your code is this…

完全删除此行...

var scoreManager = PointsLabel(num: 0)

然后将您的操作更改为此...

and change your action to this...

@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()

}

希望可以解决所有问题=)

Hopefully that fixes everything =)

这篇关于如何使Swift的高得分游戏保存在排行榜上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆