用Swift做个游戏Lecture08 —— Show Me 得分面板!

系列:用Swift作个游戏
作者:pmst(1345614869)
微博:PPPPPPMST

课时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,让我百思不得其解。希望找到问题的朋友可以告知我。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,010评论 4 62
  • 本文从 这里 翻译过来的。 2048这个游戏有一段时间特别火,Github上有其原始版本,游戏看起来很简单,但是...
    江枫阅读 1,433评论 2 7
  • 1. 《七月与安生》这部电影讲述了两个性格相悖的女孩的成长故事,听话乖巧的七月最后变成了流浪自由的安生,而不羁流浪...
    芽芽的初心阅读 774评论 3 1
  • 第三回 《鸣沙山》 D3022列车 上海-汉口 田菲慵懒的倚在座位上,用左手挡住嘴打了一个哈欠。乘火车旅行,让她有...
    沐杰阅读 588评论 0 1