用Swift做個游戲Lecture02 —— Player的誕生

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

01.添加游戲音樂

音樂主要有:Player揮動翅膀上升的聲音、撞擊障礙物的聲音、墜落至地面的聲音评凝、過關(guān)得分的聲音等等蟀苛。請打開項目看到Resource中的Sounds文件夾,包含了上述所有聲音侈玄,格式為.wav婉刀。

SpritKit提供playSoundFileNamed(soundFile: , waitForCompletion wait: )->SKAction方法用于實現(xiàn)音樂的播放,注意播放音樂也是一個Action動作序仙。請定位到GameScene.swift文件,找到GameScene類中的var playableHeight:CGFloat = 0突颊,在其下方添加如下代碼:

// MARK: 音樂Action
let dingAction = SKAction.playSoundFileNamed("ding.wav", waitForCompletion: false)
let flapAction = SKAction.playSoundFileNamed("flapping.wav", waitForCompletion: false)
let whackAction = SKAction.playSoundFileNamed("whack.wav", waitForCompletion: false)
let fallingAction = SKAction.playSoundFileNamed("falling.wav", waitForCompletion: false)
let hitGroundAction = SKAction.playSoundFileNamed("hitGround.wav", waitForCompletion: false)
let popAction = SKAction.playSoundFileNamed("pop.wav", waitForCompletion: false)
let coinAction = SKAction.playSoundFileNamed("coin.wav", waitForCompletion: false)

之后在需要音樂播放的時候調(diào)用這些已經(jīng)定義的動作即可。

02.添加Player

通過課程一的代碼練習(xí),添加一個Player只需實例化一個SKSpriteNode實例律秃,紋理為Bird0這張照片呈昔。由于這個精靈之后將在各個函數(shù)調(diào)用,因此設(shè)定了全局變量友绝,請在var playableHeight: CGFloat = 0下添加如下代碼實例化一個名為"Player"的精靈堤尾。如下:

let player = SKSpriteNode(imageNamed: "Bird0")

注意到此時我們并未添加該精靈到場景中的worldNode節(jié)點中,因此我們需要實現(xiàn)一個名為setupPlayer()的方法迁客,代碼如下

func setupPlayer(){
    player.position = CGPointMake(size.width * 0.2, playableHeight * 0.4 + playableStart)
    player.zPosition = Layer.Player.rawValue
    worldNode.addChild(player)
}

函數(shù)中僅設(shè)置了position以及zPosition屬性郭宝,而錨點anchorPoint并未設(shè)置,采用默認(rèn)值(0.5,0.5)掷漱。找到didMoveToView(view:)中的setupForeground()這行代碼粘室,將上述方法添加至其下方。

點擊運行程序卜范,Player出現(xiàn)在場景之中衔统。

03.update方法

不知道你有沒有玩過翻書動畫,先準(zhǔn)備一個厚厚的小本子海雪,然后在每一頁上描畫锦爵,最后通過快速翻閱組成最簡短的動畫。如下:

L02-Animation
L02-Animation

前文談及右下角的30fps客官可曾記得奥裸?fpsFrame Per Second的縮寫险掀,即每秒的幀數(shù),而一幀為一個畫面湾宙。因此30fps意味著在一秒鐘時間內(nèi)樟氢,App要渲染30次左右,平均每隔0.033333秒就要重新繪制一次畫面侠鳄。而渲染(繪制)完畢立刻跳入update(currentTime:)方法中埠啃,大約間隔33.33毫秒左右,執(zhí)行方法內(nèi)的代碼伟恶。不妨你在該函數(shù)中設(shè)個斷點感受一下碴开。

注意到左下角的幀數(shù)并不是始終保持在30fps,而是不斷在上下浮動變化。相鄰兩幀畫面之間的時間并不固定知押,可能是0.033秒叹螟,也可能是0.030秒。不妨測試打印下兩幀之間的時間差值,請在player下添加兩個全局變量:lastUpdateTime以及dt

var lastUpdateTime :NSTimeInterval = 0  //記錄上次更新時間
var dt:NSTimeInterval = 0               //兩次時間差值

接著在Update(currenTime:)方法中添加如下方法:

override func update(currentTime: CFTimeInterval) {
   if lastUpdateTime > 0{
       dt = currentTime - lastUpdateTime
   }else{
       dt = 0
   }
   lastUpdateTime = currentTime
   print("時間差值為:\(dt*1000) 毫秒")
}

可以看到打印結(jié)果(注意紅色框框處):

當(dāng)應(yīng)用剛啟動時台盯,幀數(shù)并不穩(wěn)定罢绽,導(dǎo)致時間間隔略大,不過之后基本穩(wěn)定在33毫秒左右静盅。

04.Player的下落公式

這里可能要涉及一些高中的物理知識良价。地球上的重力加速度為9.8g寝殴。物體在半空中靜止到下落,每隔dt時間明垢。

  • 速度V = V1 + a * dt蚣常,即當(dāng)前速度=初速度 + 加速度 * 時間間隔
  • dt時間內(nèi)痊银,下落距離d =V * dt,這里采用平均速度 * 時間差得到下落距離抵蚊。

游戲中設(shè)定且只有Y軸方向上的重力加速度kGravity = -1500,這個值是可調(diào)節(jié)的,我覺得恰到好處溯革;此外每次玩家點擊屏幕贞绳,對Player要有一個向上的拉力,不妨設(shè)為kImpulse = 400致稀;最后聲明一個變量playerVelocity追蹤當(dāng)前Player的速度冈闭。請?zhí)砑由鲜鋈齻€全局變量的聲明,現(xiàn)在GameScene類中的全局變量有以下這些:

// MARK: - 常量
let kGravity:CGFloat = -1500.0  //重力
let kImpulse:CGFloat = 400      //上升力

let worldNode = SKNode()
var playableStart:CGFloat = 0
var playableHeight:CGFloat = 0
let player = SKSpriteNode(imageNamed: "Bird0")
var lastUpdateTime :NSTimeInterval = 0
var dt:NSTimeInterval = 0
var playerVelocity = CGPoint.zero   //速度 注意變量類型為一個點
//...其他內(nèi)容

請在GameScene類中添加一個方法,將先前公式用swift實現(xiàn)更新playerposition抖单。

func updatePlayer(){
    // 只有Y軸上的重力加速度為-1500
    let gravity = CGPoint(x: 0, y: kGravity)
    let gravityStep = gravity * CGFloat(dt) //計算dt時間下速度的增量
    playerVelocity += gravityStep           //計算當(dāng)前速度
    
    // 位置計算
    let velocityStep = playerVelocity * CGFloat(dt) //計算dt時間中下落或上升距離
    player.position += velocityStep                 //計算player的位置
    
    // 倘若Player的Y坐標(biāo)位置在地面上了就不能再下落了 直接設(shè)置其位置的y值為地面的表層坐標(biāo)
    if player.position.y - player.size.height/2 < playableStart {
        player.position = CGPoint(x: player.position.x, y: playableStart + player.size.height/2)
    }
}

將該方法添加至update(currentTime)方法中的最下面萎攒。意味著每隔33.3毫秒左右就要更新一次Player的位置。

點擊運行矛绘,Player自由落地至地面耍休,不錯吧!

05.讓Player動起來

游戲中我們點擊一次屏幕蔑歌,Player會獲得一個向上的牽引力羹应,揮動翅膀向上飛一段距離,倘若之后沒有持續(xù)的力次屠,則開始自由落體。怎么實現(xiàn)呢雳刺?實現(xiàn)機制不難,只需每次玩家點擊屏幕劫灶,使得Player獲得向上的速度,具體為先前設(shè)定的400即可掖桦。

因此本昏,添加一個方法到GameScene類中,用于每次用戶點擊屏幕時調(diào)用枪汪,作用是讓Player獲得向上的速度涌穆!

func flapPlayer(){
    // 發(fā)出一次煽動翅膀的聲音
    runAction(flapAction)
    // 重新設(shè)定player的速度!雀久!
    playerVelocity  = CGPointMake(0, kImpulse)
}

正如前面談到的宿稀,方法中主要做兩件事:1.發(fā)出一次揮動翅膀的聲音。2.重新設(shè)定player的速度赖捌。

而用戶每次點擊都會調(diào)用touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)方法祝沸。不用我多說了吧,把flapPlayer()方法添加進(jìn)去吧。

運行工程罩锐,player墜落奉狈,點擊幾下,哇靠涩惑,飛起來了仁期!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市竭恬,隨后出現(xiàn)的幾起案子跛蛋,更是在濱河造成了極大的恐慌,老刑警劉巖萍聊,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件问芬,死亡現(xiàn)場離奇詭異,居然都是意外死亡寿桨,警方通過查閱死者的電腦和手機此衅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亭螟,“玉大人挡鞍,你說我怎么就攤上這事≡だ樱” “怎么了墨微?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長扁掸。 經(jīng)常有香客問我翘县,道長,這世上最難降的妖魔是什么谴分? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任锈麸,我火速辦了婚禮,結(jié)果婚禮上牺蹄,老公的妹妹穿的比我還像新娘忘伞。我一直安慰自己,他們只是感情好沙兰,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布氓奈。 她就那樣靜靜地躺著,像睡著了一般鼎天。 火紅的嫁衣襯著肌膚如雪舀奶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天训措,我揣著相機與錄音伪节,去河邊找鬼光羞。 笑死,一個胖子當(dāng)著我的面吹牛怀大,可吹牛的內(nèi)容都是我干的纱兑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼化借,長吁一口氣:“原來是場噩夢啊……” “哼潜慎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蓖康,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤铐炫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蒜焊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倒信,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年泳梆,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳖悠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡优妙,死狀恐怖乘综,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情套硼,我是刑警寧澤卡辰,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站邪意,受9級特大地震影響九妈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜雾鬼,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一允蚣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呆贿,春花似錦、人聲如沸森渐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽同衣。三九已至竟块,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耐齐,已是汗流浹背浪秘。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工蒋情, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耸携。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓棵癣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夺衍。 傳聞我的和親對象是個殘疾皇子狈谊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348

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