用Swift做個游戲Lecture01 —— 初窺游戲場景

作者:PMST
VERSION:V1.0
NOTICE:目前第一版以敘述內(nèi)容為主,之后對其中一些細(xì)節(jié)知識點(diǎn)進(jìn)行講解。
更新時間:每周日

本教程參考自RayWenderlich的視頻教程How To Make a Game Like Flappy Bird Series (Swift)。本教程中,你將從無到有親自開發(fā)一個基于SpriteKit框架的Flappy bird小游戲??傮w難度不大,但要求你掌握Swift基礎(chǔ)語法與SpriteKit框架知識。此外,教程中所有素材均來自Raywenderlich,鼓勵學(xué)習(xí)交流,但請勿用于商業(yè)用途。

友情幫助: 為了方便大家快速上手項(xiàng)目,我在github中上傳了起始項(xiàng)目文件供大家下載,請點(diǎn)擊這里下載。

01.項(xiàng)目文件介紹

首先請打開項(xiàng)目,先介紹項(xiàng)目已有文件,你將看到如下目錄:

L01-Dir
L01-Dir

主要講解以下一些重要的文件:

  • Resource文件夾:資源文件放置處

    • Art:以atlas圖冊方式管理素材文件。

    • SKTUtiles:采用Extension對一些類進(jìn)行拓展,添加一些有用的方法或?qū)傩浴?/p>

    • Sounds:游戲聲音素材

  • GameScene.swift:Flappy游戲比較簡單,因此一個游戲場景足以,有關(guān)于場景內(nèi)容設(shè)置、交互等均在該場景中設(shè)置。

  • GameViewController.swift:視圖控制器,包含一個視圖view,當(dāng)然這個視圖比較特殊:為SKView,用于呈現(xiàn)場景Scene。

02.呈現(xiàn)視圖

選中GameViewController.swift文件,先前提及視圖控制器中的SKView,其職責(zé)在于呈現(xiàn)游戲場景Scene。不過現(xiàn)在空文件中神馬都沒有,我們將重寫viewWillLayoutSubviews()方法呈現(xiàn)場景。定位到GameViewController類,添加以下代碼:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    // 1.對view進(jìn)行父類向子類的變形,結(jié)果是一個可選類型 因此需要解包
    if let  skView = self.view as? SKView{
        // 倘若skView中沒有場景Scene,需要重新創(chuàng)建創(chuàng)建一個
        if skView.scene == nil{

            /*==  創(chuàng)建場景代碼  ==*/

            // 2.獲得高寬比例
            let aspectRatio = skView.bounds.size.height / skView.bounds.size.width
            // 3.new一個場景實(shí)例 這里注意場景的width始終為320 至于高是通過width * aspectRatio獲得
            let scene = GameScene(size:CGSizeMake(320, 320 * aspectRatio))

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

            // 5.設(shè)置場景呈現(xiàn)模式
            scene.scaleMode = .AspectFill

            // 6.呈現(xiàn)場景
            skView.presentScene(scene)
        }
    }
}

這里需要注意2、3處,固定了游戲場景的寬度Width = 320,高度則通過Width乘以高寬比相乘得到,對于iPhone4s iPhone5/5s這些寬為320的設(shè)備來說自然沒什么影響,但是對于iPhone6/6Pluse設(shè)備,相當(dāng)于將設(shè)備寬高同時縮小相同倍數(shù),直至寬為320時停止;再通過設(shè)置scaleModeAspectFill(更多ScaleMode,請點(diǎn)擊這里了解)呈現(xiàn)視圖。

對于4來說,我們需要了解游戲運(yùn)行時每秒的幀數(shù)、當(dāng)前場景中節(jié)點(diǎn)個數(shù)、顯示節(jié)點(diǎn)的物理體等,因此通過設(shè)置這些參數(shù)能幫助我們更好的調(diào)試。

OK,點(diǎn)擊運(yùn)行項(xiàng)目,模擬器運(yùn)行結(jié)果一片漆黑,不過右下角顯示node=1 60.0fps,表明當(dāng)前場景中顯示了一個節(jié)點(diǎn),幀數(shù)為60左右。

Question:什么都還沒添加,視圖中怎么會有一個節(jié)點(diǎn)Node了呢?

Answer:場景Scene類為SKScene,繼承自SKNode,因此當(dāng)skView呈現(xiàn)場景時,自然就將一個節(jié)點(diǎn)置于其中了。

03場景內(nèi)容的填充

定位到GameScene.swift文件,可以看到文件中已經(jīng)聲明了一個GameScene類,當(dāng)然類中我們還未實(shí)現(xiàn)任何東西,因此這是運(yùn)行項(xiàng)目呈現(xiàn)出來的場景是漆黑一片。是時候一步步配置游戲場景了!

首先,定位到GameScene類中,在類中頂部添加如下三個變量,如下:

class GameScene:SKScene:{
let worldNode = SKNode()
var playableStart:CGFloat = 0
var playableHeight:CGFloat = 0
//...文件其他內(nèi)容
}

如上實(shí)例化了一個節(jié)點(diǎn)命名為worldNode,原因在于之后游戲中所有的節(jié)點(diǎn)都將添加至這個節(jié)點(diǎn)中,方便管理。此外游戲中場景分為BackgroundGround兩部分,前者是背景,鳥可以在該區(qū)域中上下飛行;后者地面,小鳥僅限于跌落至上面。具體劃分請看下圖:

L01-Scene
L01-Scene

其中,背景和地面均作為節(jié)點(diǎn)添加至worldNode節(jié)點(diǎn)中。請在didMoveToView(view:)方法中添加如下代碼:

override func didMoveToView(view: SKView) {
    addChild(worldNode)
    setupBackground()
    setupForeground()
}

首先添加worldNode節(jié)點(diǎn)到場景中,接著setupBackground()setupForeground()兩個方法分別設(shè)置背景和地面兩個節(jié)點(diǎn),當(dāng)然此時方法還未實(shí)現(xiàn)。

通常游戲包含多個節(jié)點(diǎn),為了細(xì)化節(jié)點(diǎn)的圖層關(guān)系,節(jié)點(diǎn)Node中設(shè)定了一個zPosition屬性用于標(biāo)識節(jié)點(diǎn)相距你的程度,越小越里面,越大越外面。顯然游戲中,背景至于最底部,其次是地面,最后才是Player那只鳥。為此我們將使用枚舉來說明層級關(guān)系,在GameScene類上方添加Layer的聲明:

enum Layer: CGFloat {
  case Background
  case Foreground
  case Player
}
class GameScene:SKScene{}

干完這些,是時候補(bǔ)充剩下的兩個方法的實(shí)現(xiàn)了。首先添加setupBackground()方法至GameScene類中:

func setupBackground(){
    // 1
    let background = SKSpriteNode(imageNamed: "Background")
    background.anchorPoint = CGPointMake(0.5, 1)
    background.position = CGPointMake(size.width/2.0, size.height)
    background.zPosition = Layer.Background.rawValue
    worldNode.addChild(background)

    // 2
    playableStart = size.height - background.size.height
    playableHeight = background.size.height
}

依葫蘆畫瓢實(shí)現(xiàn)setupForeground()方法:

func setupForeground() {

  let foreground = SKSpriteNode(imageNamed: "Ground")
  foreground.anchorPoint = CGPoint(x: 0, y: 1)
  foreground.position = CGPoint(x: 0, y: playableStart)
  foreground.zPosition = Layer.Foreground.rawValue
  worldNode.addChild(foreground)
}

點(diǎn)擊運(yùn)行,你將看到如下畫面,Good Job! 你已經(jīng)完成了第一步,之后我們將添加Player以及障礙物到場景中。

L01-end
L01-end

倘若你覺得SpritKit的基礎(chǔ)知識不夠扎實(shí),不妨看看這個

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,052評論 4 61
  • 嗯哼嗯哼蹦擦擦~~~ 轉(zhuǎn)載自:https://github.com/Tim9Liu9/TimLiu-iOS 目錄 ...
    philiha閱讀 5,235評論 0 6
  • 本文轉(zhuǎn)自http://blog.csdn.net/lmj623565791/article/details/242...
    radish520like閱讀 521評論 0 0
  • 有些時候,一個人若是給你留了條路找他,趕緊去,別傷她的心,他只是害怕了…… 可有些時候,當(dāng)她徹徹底底的從你的世界消...
    初畫影閱讀 205評論 0 0

友情鏈接更多精彩內(nèi)容