我使用SpriteKit和Xcode 7 beta制作了游戏。我试图把GameCenter和排行榜放在一边,但问题是排行榜中的得分不会改变它一直保持0(游戏的高分赢得并排在排行榜中)并且我不知道如何解决它。我使用了3个不同的文件: GameScene.swift , GameViewController.swift 和 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文件中:
@IBAction func leaderboard(sender: UIButton) {
saveHighscore(scoreManager.score)
scoreManager.increment() //<-- Here
showLeader()
}
也许我没有把它放在正确的地方
scoreManager.increment()
答案 0 :(得分:4)
我看到一些可能导致问题的因素。首先是这种方法......
func loadHighscore() {
let defaults = NSUserDefaults.standardUserDefaults()
let highscoreLabel = childNodeWithName("highscoreLabel") as! PointsLabel
highscoreLabel.setTo(defaults.integerForKey("highscore"))
}
我没有看到你设置的任何地方,所以把它拉出来不会有多大帮助。我在saveHighscore:function bellow中将保存添加到默认值。
第二是......
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()
}
希望能解决所有问题=)
答案 1 :(得分:1)
在您的游戏中,您需要增加分数并在用户得分时将分数发送到游戏中心。我不确定你的游戏是如何运作的,但每当他们获得一个积分时你需要更新分数并将该分数发送到游戏中心并更新标签。点击排行榜按钮时,您无法更新分数。我不确定我是否清楚,所以问你是否需要澄清或帮助。
答案 2 :(得分:0)
听起来您需要使用核心数据,它是您用来在应用中保存数据的方法。我不太了解它,所以我只能指出一些可能有用的资源:
Core Data relationships (swift)
Swift - Core Data Seeding Class