用Swift做個(gè)游戲Lecture10 —— 優(yōu)化游戲(終結(jié)篇)

系列:用Swift作個(gè)游戲
作者:pmst(1345614869)
微博:PPPPPPMST

Flappy Bird整個(gè)項(xiàng)目臨近尾聲谓谦,要做的只是對游戲體驗(yàn)的優(yōu)化,本文先解決兩個(gè)贪婉,分別是:

  1. 實(shí)現(xiàn)Player 靜態(tài)時(shí)的動(dòng)畫反粥,修改早前掉落時(shí)直上直下的問題。
  2. Player撞擊障礙物時(shí)疲迂,給出一個(gè)shake搖晃動(dòng)畫才顿。

游戲最后實(shí)現(xiàn)的效果是這樣的:

Player動(dòng)畫實(shí)現(xiàn)

當(dāng)游戲狀態(tài)為.Tutorial的時(shí)候,Player是靜態(tài)呈現(xiàn)在教程界面上的尤蒿,為此我們想要實(shí)現(xiàn)一個(gè)動(dòng)畫郑气,讓其揮動(dòng)翅膀。而實(shí)現(xiàn)方法也很簡單腰池,動(dòng)畫由多張圖片組成尾组,指定一定時(shí)間播放完畢,具體用SKTexture實(shí)例化每一個(gè)圖片巩螃,然后放到數(shù)組中演怎;緊接著調(diào)用animateWithTextures(_:timePerFrame:)播放動(dòng)畫。

找到setupTutorial()方法避乏,再其下方新增一個(gè)方法:

func setupPlayerAnimation() {
    
    var textures: Array<SKTexture> = []
    // 我們有4張圖片
    for i in 0..<4 {
        textures.append(SKTexture(imageNamed: "Bird\(i)"))
    }
    // 4=3-1
    for i in 3.stride(through: 0, by: -1) {
        textures.append(SKTexture(imageNamed: "Bird\(i)"))
    }
    
    let playerAnimation = SKAction.animateWithTextures(textures, timePerFrame: 0.07)
    player.runAction(SKAction.repeatActionForever(playerAnimation))
    
}

正如前面所說爷耀,我們采用for-in循環(huán)實(shí)例化了4個(gè)SKTexture實(shí)例存儲于數(shù)組中,接著調(diào)用方法播放動(dòng)畫∨钠ぃ現(xiàn)在請將該方法添加到switchToMainMenu()以及switchToTutorial()方法中的最后歹叮,點(diǎn)擊運(yùn)行,看看Player是否揮動(dòng)翅膀了。

在玩游戲的時(shí)候我們會(huì)注意到Player掉落時(shí)是直上直下铆帽,有些呆板咆耿,這里需要替換掉,動(dòng)畫效果如圖:

在開始實(shí)現(xiàn)Player旋轉(zhuǎn)機(jī)制前爹橱,先定義幾個(gè)常量以及變量,請?jiān)?code>GameScene()類中添加如下屬性

// 新增常量
let kMinDegrees: CGFloat = -90          // 定義Player最小角度為-90
let kMaxDegrees: CGFloat = 25           // 定義Player最大角度為25
let kAngularVelocity: CGFloat = 1000.0  // 定義角速度

// 新增變量
var playerAngularVelocity: CGFloat = 0.0    // 實(shí)時(shí)更新player的角度
var lastTouchTime: NSTimeInterval = 0       // 用戶最后一次點(diǎn)擊時(shí)間
var lastTouchY: CGFloat = 0.0               // 用戶最后一次點(diǎn)擊坐標(biāo)

請找到flapPlayer方法萨螺,這個(gè)方法是在游戲狀態(tài)下,用戶點(diǎn)擊一次屏幕需要調(diào)用的方法(具體請?zhí)?code>touchesBegan方法)愧驱,為此我們將在這里進(jìn)行lastTouchTimelastTouchY變量的更新,替換后的內(nèi)容如下:

func flapPlayer(){
   // 發(fā)出一次煽動(dòng)翅膀的聲音
   runAction(flapAction)
   // 重新設(shè)定player的速度N考肌!
   playerVelocity  = CGPointMake(0, kImpulse)
   
   //===========新增內(nèi)容============
   playerAngularVelocity = kAngularVelocity.degreesToRadians()
   lastTouchTime = lastUpdateTime
   lastTouchY = player.position.y
   //==============================
   
   // 使得帽子下上跳動(dòng)
   let moveUp = SKAction.moveByX(0, y: 12, duration: 0.15)
   moveUp.timingMode = .EaseInEaseOut
   let moveDown = moveUp.reversedAction()
   sombrero.runAction(SKAction.sequence([moveUp,moveDown]))
}

如此每次用戶點(diǎn)擊一次屏幕组砚,就會(huì)重新計(jì)算Player應(yīng)該旋轉(zhuǎn)多少吻商。那么什么時(shí)候去真正更新Player的狀態(tài)呢?答案是update()方法糟红。這里我們要更新的是Player的信息艾帐,請找到updatePlayer()方法乌叶,新增如下內(nèi)容到最后:

if player.position.y < lastTouchY {
  playerAngularVelocity = -kAngularVelocity.degreesToRadians()
}

// Rotate player
let angularStep = playerAngularVelocity * CGFloat(dt)
player.zRotation += angularStep
player.zRotation = min(max(player.zRotation, kMinDegrees.degreesToRadians()), kMaxDegrees.degreesToRadians())

點(diǎn)擊運(yùn)行!不出意味應(yīng)該和預(yù)期效果一樣柒爸。

Shake動(dòng)畫

先前說到Player撞擊障礙物后要有一個(gè)搖晃的動(dòng)畫以及閃爍的小鍋准浴,那樣顯得更有真實(shí)感不是嗎,這里需要調(diào)用screenShakeWithNode來實(shí)現(xiàn)揍鸟,搖晃對象是誰兄裂?自然是worldNode嘍。

由于內(nèi)容簡單阳藻,請直接定位到switchToFalling()方法晰奖,替換早前內(nèi)容:

enum Layer: CGFloat {
  case Background
  case Obstacle
  case Foreground
  case Player
  case UI
  case Flash        //新增一個(gè)層
}

func switchToFalling() {
   gameState = .Falling
   
   // Screen shake
   let shake = SKAction.screenShakeWithNode(worldNode, amount: CGPoint(x: 0, y: 7.0), oscillations: 10, duration: 1.0)
   worldNode.runAction(shake)
   
   // Flash
   let whiteNode = SKSpriteNode(color: SKColor.whiteColor(), size: size)
   whiteNode.position = CGPoint(x: size.width/2, y: size.height/2)
   whiteNode.zPosition = Layer.Flash.rawValue
   worldNode.addChild(whiteNode)
   
   whiteNode.runAction(SKAction.removeFromParentAfterDelay(0.01))
   
   runAction(SKAction.sequence([
       whackAction,
       SKAction.waitForDuration(0.1),
       fallingAction
       ]))
   
   player.removeAllActions()
   stopSpawning()
}

哦對了,請注釋掉GameViewController.swift中的幾行代碼腥泥,去掉所有調(diào)試信息匾南,這樣才是一個(gè)完整的游戲;

// 4.設(shè)置一些調(diào)試參數(shù)
//skView.showsFPS = true          // 顯示幀數(shù)
//skView.showsNodeCount = true    // 顯示當(dāng)前場景下節(jié)點(diǎn)個(gè)數(shù)
//skView.showsPhysics = true      // 顯示物理體
//skView.ignoresSiblingOrder = true   // 忽略節(jié)點(diǎn)添加順序

點(diǎn)擊運(yùn)行蛔外,享受你的勞動(dòng)果實(shí)吧蛆楞!

結(jié)尾

這個(gè)游戲系列文章終于連載完成,當(dāng)時(shí)可能是一時(shí)興起夹厌,最后還是堅(jiān)持下來了豹爹。文章更多是在敘述整個(gè)游戲是如何開發(fā)出來,并未在一些基礎(chǔ)知識以及實(shí)現(xiàn)原理上細(xì)說矛纹,這是之后我要補(bǔ)充的臂聋,最后謝謝大家的支持。如果覺得不錯(cuò)或南,請點(diǎn)擊喜歡并關(guān)注我孩等,同時(shí)將我的文章推薦給你的朋友。8~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末采够,一起剝皮案震驚了整個(gè)濱河市肄方,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蹬癌,老刑警劉巖权她,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異逝薪,居然都是意外死亡伴奥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門翼闽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洲炊,你說我怎么就攤上這事感局∧岱龋” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我疆拘,道長鳖粟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任煞檩,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘雌续。我一直安慰自己,他們只是感情好胯杭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布驯杜。 她就那樣靜靜地躺著,像睡著了一般做个。 火紅的嫁衣襯著肌膚如雪鸽心。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天居暖,我揣著相機(jī)與錄音顽频,去河邊找鬼。 笑死太闺,一個(gè)胖子當(dāng)著我的面吹牛糯景,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播跟束,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼莺奸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冀宴?” 一聲冷哼從身側(cè)響起灭贷,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎略贮,沒想到半個(gè)月后甚疟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逃延,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年览妖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揽祥。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讽膏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拄丰,到底是詐尸還是另有隱情府树,我是刑警寧澤俐末,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站奄侠,受9級特大地震影響卓箫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜垄潮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一烹卒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弯洗,春花似錦旅急、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至果正,卻和暖如春炎码,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秋泳。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工潦闲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迫皱。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓歉闰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親卓起。 傳聞我的和親對象是個(gè)殘疾皇子和敬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容