課時7中實現了得分機制,當你越戰越勇,得分也蹭蹭地往上加,不過馬有失蹄,人有失足,總會不小心失敗,這時候就要結算你的勞動成果了:通常都是告知遊戲結束,得分幾何,最好成績等等信息。咱們遊戲是這麼設計的:
本文任務:
- 當遊戲結束時呈現上圖的內容。
思路:
- 簡單來說就是實例化幾個特定紋理(你可以理解爲照片image)的精靈,然後按照特定佈局放置到屏幕中,是不是灰常簡單呢?
01.使用NSUserDefaults來保存數據
使用NSUserDefaults用於持久性的保存得分記錄是一個明智的決定,我們不可能爲了存一個數據而使用諸如Core Data
或者Sqlite
等數據庫。
1-1 從NSUserDefault中讀取分數
請在GameScene類中添加一個新方法,用於讀取遊戲記錄得分:
func bestScore()->Int{
return NSUserDefaults.standardUserDefaults().integerForKey("BestScore")
}
可以看到方法中爲最高得分設置了名爲”BestScore”的鍵。
1-2 在NSUserDefault中設置分數
有讀取自然有寫,請在bestScore()方法下方添加一個新方法:
func setBestScore(bestScore:Int){
NSUserDefaults.standardUserDefaults().setInteger(bestScore, forKey: "BestScore")
NSUserDefaults.standardUserDefaults().synchronize()
}
02.構建得分面板
得分面板如文中給出圖片佈局,工程量還是蠻大的,不過我會一步一步講解,無需擔心一口吃撐的情況。
首先請找到setupLabel方法,在它下方聲明咱們的設置得分面板的函數,取名爲setupScorecard()
:
func setupScorecard() {
//1
if score > bestScore() {
setBestScore(score)
}
//...等下添加其他內容
}
- 首先調用
bestScore()
取到歷史最高得分,與本回合得分比較,倘若這次“走狗屎運”得了高分,咱們就要更新歷史最高紀錄,也就是調用setBestScore(score)
方法。
接着,着手添加得分面板的精靈,內容有點多,請注意別碼錯:
func setupScorecard() {
if score > bestScore() {
setBestScore(score)
}
// 1 得分面板背景
let scorecard = SKSpriteNode(imageNamed: "ScoreCard")
scorecard.position = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
scorecard.name = "Tutorial"
scorecard.zPosition = Layer.UI.rawValue
worldNode.addChild(scorecard)
// 2 本次得分
let lastScore = SKLabelNode(fontNamed: kFontName)
lastScore.fontColor = SKColor(red: 101.0/255.0, green: 71.0/255.0, blue: 73.0/255.0, alpha: 1.0)
lastScore.position = CGPoint(x: -scorecard.size.width * 0.25, y: -scorecard.size.height * 0.2)
lastScore.text = "\(score)"
scorecard.addChild(lastScore)
// 3 最好成績
let bestScoreLabel = SKLabelNode(fontNamed: kFontName)
bestScoreLabel.fontColor = SKColor(red: 101.0/255.0, green: 71.0/255.0, blue: 73.0/255.0, alpha: 1.0)
bestScoreLabel.position = CGPoint(x: scorecard.size.width * 0.25, y: -scorecard.size.height * 0.2)
bestScoreLabel.text = "\(self.bestScore())"
scorecard.addChild(bestScoreLabel)
// 4 遊戲結束
let gameOver = SKSpriteNode(imageNamed: "GameOver")
gameOver.position = CGPoint(x: size.width/2, y: size.height/2 + scorecard.size.height/2 + kMargin + gameOver.size.height/2)
gameOver.zPosition = Layer.UI.rawValue
worldNode.addChild(gameOver)
// 5 ok按鈕背景以及ok標籤
let okButton = SKSpriteNode(imageNamed: "Button")
okButton.position = CGPoint(x: size.width * 0.25, y: size.height/2 - scorecard.size.height/2 - kMargin - okButton.size.height/2)
okButton.zPosition = Layer.UI.rawValue
worldNode.addChild(okButton)
let ok = SKSpriteNode(imageNamed: "OK")
ok.position = CGPoint.zeroPoint
ok.zPosition = Layer.UI.rawValue
okButton.addChild(ok)
// 6 share按鈕背景以及share標籤
let shareButton = SKSpriteNode(imageNamed: "Button")
shareButton.position = CGPoint(x: size.width * 0.75, y: size.height/2 - scorecard.size.height/2 - kMargin - shareButton.size.height/2)
shareButton.zPosition = Layer.UI.rawValue
worldNode.addChild(shareButton)
let share = SKSpriteNode(imageNamed: "Share")
share.position = CGPoint.zeroPoint
share.zPosition = Layer.UI.rawValue
shareButton.addChild(share)
}
當你碼完了這一段超長代碼之後,你會鬆一口氣,現在還有一步就能享受勝利的果實了!!
想想我們時候什麼需要顯示這個得分面板。Player掉落失敗的時候,對嗎?請找到switchToShowScore()
方法,在最下方調用setupScorecard()
,點擊運行,過幾個障礙物,然後自由落體,看看是否良好地顯示了得分面板。
Good Job!顯示本次得分,歷史最高紀錄以及選項按鈕——不過此時並沒有什麼卵用。
你有木有發現得分面板“毫無徵兆”地就出現在了場景中央,來加個動畫吧!!!
03.爲得分面板添加動畫
請回到原先的setupScorecard()
方法,繼續再下方添加動畫代碼:
//=== 添加一個常量 用於定義動畫時間 ====
let kAnimDelay = 0.3
func setupScorecard() {
//。。。。。。
//==== 以下是新添加的內容 =====
gameOver.setScale(0)
gameOver.alpha = 0
let group = SKAction.group([
SKAction.fadeInWithDuration(kAnimDelay),
SKAction.scaleTo(1.0, duration: kAnimDelay)
])
group.timingMode = .EaseInEaseOut
gameOver.runAction(SKAction.sequence([
SKAction.waitForDuration(kAnimDelay),
group
]))
scorecard.position = CGPoint(x: size.width * 0.5, y: -scorecard.size.height/2)
let moveTo = SKAction.moveTo(CGPoint(x: size.width/2, y: size.height/2), duration: kAnimDelay)
moveTo.timingMode = .EaseInEaseOut
scorecard.runAction(SKAction.sequence([
SKAction.waitForDuration(kAnimDelay * 2),
moveTo
]))
okButton.alpha = 0
shareButton.alpha = 0
let fadeIn = SKAction.sequence([
SKAction.waitForDuration(kAnimDelay * 3),
SKAction.fadeInWithDuration(kAnimDelay)
])
okButton.runAction(fadeIn)
shareButton.runAction(fadeIn)
let pops = SKAction.sequence([
SKAction.waitForDuration(kAnimDelay),
popAction,
SKAction.waitForDuration(kAnimDelay),
popAction,
SKAction.waitForDuration(kAnimDelay),
popAction,
SKAction.runBlock(switchToGameOver)
])
runAction(pops)
}
點擊運行,玩耍吧!
注意: 我發現了一個BUG,倘若遊戲一開始就使得它下落觸碰地面,彈出的得分面板share標籤放置位置是錯誤的,因爲它的背景以
let shareButton = SKSpriteNode(imageNamed: "Button")
返回的是一個精靈size=0
,讓我百思不得其解。希望找到問題的朋友可以告知我。