讀源碼系列(swift2048)-controller篇

前言

筆者是swift自學(xué)新手胳施,希望借助閱讀別人開源項目提升自己swift水平。文中盡量使用文字說明來代替代碼的堆砌谦秧,建議對著源碼閱讀鼠次,以便更好理解項目。文中難免有錯誤之處邢笙,歡迎各路大牛留言指正啸如。

項目信息

swift-2048 github地址


項目主界面

該項目可以說一個帶有實驗學(xué)習性質(zhì)的項目,其中部分功能沒有實現(xiàn)或不完整氮惯。但2048游戲的基本功能均完整實現(xiàn)叮雳。筆者將分3篇文章,分別按controller妇汗、model帘不、view的進行介紹。

本篇是第1篇杨箭,將重點展開介紹controller部分寞焙。

開始

對于一個完整項目,筆者喜歡從AppDelegate讀起:

1.AppDelegate沒有添加代碼互婿;

2.Main.storyboard中只有一個startGame按鈕捣郊;

3.開始按鈕對應(yīng)的方法也內(nèi)也只有2句代碼:

@IBAction func startGameButtonTapped(sender : UIButton) {

? ? let game = NumberTileGameViewController(dimension: 4, threshold: 2048)

? ? self.presentViewController(game, animated: true, completion: nil)

}

可見游戲的所有功能業(yè)務(wù)邏輯應(yīng)該全部在NumberTileGameViewController中慈参。

補充解釋

dimension 表示游戲盤的維度,dimension=4表示4*4大小的游戲盤驮配。

threshold 表示游戲勝利條件着茸,threshold=2048表示當出現(xiàn)2048時游戲結(jié)束。

正題

NumberTileGameViewController是整個游戲的的入口琐旁。不說大家應(yīng)該也猜到了涮阔,本類里面的內(nèi)容就是model+view旋膳。

//model:

var model: GameModel? //整個游戲的model

//view:

var board: GameboardView? //游戲盤的view

var scoreView: ScoreViewProtocol? //顯示等分的view

contoller如何使用model?


全文中“游戲盤”“棋子”的含義


model在init中初始化:

model = GameModel(dimension: dimension, threshold: threshold, delegate: self)

model有主要4個方法被controller主動調(diào)用:

m.insertTileAtRandomLocation(2) 在游戲盤上一個隨機位置插入一枚棋子

m.userHasWon() 判斷是否是獲勝

m.userHasLost() 判斷是否是失敗

m.queueMove(MoveDirection.Down, completion: { ... })//移動棋子(向下滑動手勢)

上面4個方法途事,主要是在用戶滑動手勢之后進行調(diào)用验懊,滑動手勢對應(yīng)的方法中主要完成以下3步:

1》queueMove移動格子

2》移動完成后,判斷是否獲勝userHasWon或失敗userHasLost

3》如果游戲可以繼續(xù)尸变,插入新格子insertTileAtRandomLocation

可見义图,上面是典型的 view(手勢)更新 model 的流程召烂。

model通知view,也使用了典型的做法--委托

model定義了如下協(xié)議:

protocol GameModelProtocol : class {

? ? func scoreChanged(score: Int)

? ? func moveOneTile(from: (Int, Int), to: (Int, Int), value: Int)

? ? func moveTwoTiles(from: ((Int, Int), (Int, Int)), to: (Int, Int), value: Int)

? ? func insertTile(location: (Int, Int), value: Int)

}

本協(xié)議定義了游戲model所產(chǎn)生的結(jié)果動作:

1》scoreChanged 得分變化

2》moveOneTile 移動一個棋子怕篷,到一個新位置

3》moveTwoTiles 移動2個棋子酗昼,到一個新位置

4》insertTile 插入新棋子

其中,1麻削、4還是很好理解。2呛哟、3 是開發(fā)者根據(jù)游戲的特點所抽象出的2種棋子移動方式(具體說明將在專門分析model時提到)。這四個方法均在NumberTileGameViewController中實現(xiàn)榛鼎。實現(xiàn)很簡單鳖孤,即直接調(diào)用相應(yīng)view的方法:1調(diào)用的是scoreView的scoreChange;2.3.4調(diào)用是board(GameBoardVIew)的moveOneTile淌铐、moveTwoTiles、insertTile方法际起。例如:

func insertTile(location: (Int, Int), value: Int) {//插入新棋子的協(xié)議實現(xiàn)

? ? assert(board != nil)

? ? let b = board!

? ? b.insertTile(location, value: value)//調(diào)用view對應(yīng)的方法

}


梳理controller主要方法的流程

init方法:

1.創(chuàng)建GameModel

2.setupSwipeControls 創(chuàng)建滑動手勢的動作

viewDidLoad方法:

調(diào)用setupGame, 安裝Game相關(guān)的view (后面有本函數(shù)的流程說明)

滑動手勢的處理方法:

func downCommand(r: UIGestureRecognizer!) {

? ? assert(model != nil)

? ? let m = model!

? ? m.queueMove(MoveDirection.Down, //調(diào)用model街望,進行業(yè)務(wù)處理

? ? completion: { (changed: Bool) -> () in //本無名閉包將在model調(diào)用委托方法之后,執(zhí)行

? ? ? ? if changed {

? ? ? ? ? ? self.followUp() //這個是后續(xù)方法防症,執(zhí)行如判斷游戲勝利失敗或插入新棋子)

? ? ? ? }

? ?})

}

setupGame方法:

1創(chuàng)建內(nèi)部函數(shù)xPositionToCenterView。返回一個view水平居中后的x

2內(nèi)部函數(shù)yPositionForViewAtPosition 給一組view垂直居中后蔫敲,其中某一個view的y

3創(chuàng)建scoreView

4創(chuàng)建game board view

5通過前面的內(nèi)部函數(shù)炭玫,計算出scoreView和gameBoardView的frame中的xy

6將scoreView和game board加入主view,并賦值到viewcontrller的對應(yīng)屬性

7調(diào)用model吞加,新增隨機游戲棋子,開始游戲

總結(jié)

本項目中的viewcontroller的職能很清晰的叶圃,主要是下面2點:

1》初始化view践图、model、手勢

2》協(xié)助view和model交互(手勢處理函數(shù)中調(diào)用model平项;model的委托函數(shù)中調(diào)用view)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闽瓢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子扣讼,更是在濱河造成了極大的恐慌,老刑警劉巖椭符,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件销钝,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒸健,警方通過查閱死者的電腦和手機婉商,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門丈秩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蘑秽,你說我怎么就攤上這事箫攀。” “怎么了匠童?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵汤求,是天一觀的道長严拒。 經(jīng)常有香客問我,道長裤唠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任墓赴,我火速辦了婚禮航瞭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刊侯。我一直安慰自己,他們只是感情好藕届,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布亭饵。 她就那樣靜靜地躺著,像睡著了一般辜羊。 火紅的嫁衣襯著肌膚如雪懂算。 梳的紋絲不亂的頭發(fā)上庇麦,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音垮媒,去河邊找鬼航棱。 笑死,一個胖子當著我的面吹牛饮醇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播朴艰,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼祠墅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了毁嗦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤克锣,失蹤者是張志新(化名)和其女友劉穎腔长,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饼酿,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡故俐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了药版。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡何缓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碌廓,到底是詐尸還是另有隱情,我是刑警寧澤慨蛙,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布纪挎,位于F島的核電站,受9級特大地震影響异袄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜封孙,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一玖绿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斑匪,春花似錦锋勺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至枫绅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間并淋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工句喷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唾琼。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓锡溯,卻偏偏與公主長得像神郊,于是被迫代替她去往敵國和親趾唱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

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