【等待補充完整】70課:開發(fā)一個井字游戲App吧

這節(jié)課我們要開發(fā)一個小游戲:Tick Tack Toe 也叫 Noughts & Crosses,翻譯過來應該是井字游戲暮顺。

我百度了一下,有人這么回答的:

是一種倆人制的棋類游戲,又名為圈圈叉叉掘殴,兩名游戲者在圈圈(O)和叉叉(X)兩種符號中泡孩,各選一種车摄,然后在一張3x3格(也就是我們所說九宮格)棋盤上輪流下,一般叉叉先走珍德,當一種符號在棋盤中的空格內练般,或豎向,或橫向锈候,或斜向成3連的情形時薄料,該符號的游戲者勝出,此游戲由于不復雜泵琳,一般適用于小朋友們摄职。

課程筆記文集地址:Udemy課程:The Complete iOS 9 Developer Course - Build 18 Apps

也就是從這節(jié)視頻中,我意識到获列,編程的思維的重要性谷市。我可以照著作者的方法迅速敲擊出來代碼,然后實現(xiàn)這個效果击孩,但是迫悠,如果規(guī)則變了呢?或者規(guī)則沒變巩梢,我沒看過這節(jié)視頻创泄,我該如何實現(xiàn)這樣的規(guī)則呢?為什么這一步要用這個方法呢括蝠?為什么要遍歷結果呢鞠抑?還有沒有其他的方法可以實現(xiàn)同樣的規(guī)則?單單是這些問題忌警,讓我在這節(jié)視頻上困了一個周搁拙,繼續(xù)往下看的進度嚴重被延后了。

慶幸的是法绵,我在這個周里箕速,接觸到了李笑來的書《把時間當朋友》,里面說礼烈,卡住了弧满,先繼續(xù)往前走,只要把這個卡住的記下來就好了此熬,說不定等你往前走到一定程度庭呜,回頭看滑进,發(fā)現(xiàn)這個問題就能輕易解決了呢。

所以募谎,我決定把這節(jié)視頻先擱置起來扶关,繼續(xù)往前走酿矢,繼續(xù)看剩下的視頻啤握,記得有天要回來。

視頻看到了 27:00锯仪。

一拐纱、布局Storeboard

1.首先布局棋盤背景铜异,使用UIIamgeView控件,設置AutoLayout約束秸架。

2.放置UIButton控件揍庄,去掉Button的文字使用圖片,放置到正確的位置然后东抹,設置AutoLayout約束蚂子。然后依次放置設置剩下的Button控件,一共有9個UIButton控件缭黔。實際效果圖如下:


實際效果圖

3.給Button控件建立Action和Outlet連接食茎,不用給9個Button都建立連接,只給第一個建立連接就可以了馏谨。(剩下的8個Button的Action連接后面說怎么做)

    @IBOutlet weak var button: UIButton!
    
    @IBAction func buttonPressed(sender: AnyObject) {
        
    }

二别渔、寫代碼:初步布局

1. setImage 方法

Button控件上顯示哪個圖片可以用setImage方法,如下:

    @IBAction func buttonPressed(sender: AnyObject) {
        var image = UIImage(named: "cross.png")
        
        button.setImage(image, forState: UIControlState.Normal)
    }

這樣點擊一下按鈕惧互,按鈕外表就變成了叉號钠糊。

2.給剩下的8個Button控件創(chuàng)建Action連接

將剩下的8個Button控件用Ctrl拖拽法連接到Action的代碼上,如下圖:

拖拽8次壹哺。這樣點擊任何一個按鈕,第一個按鈕外表就變成了叉號艘刚。這不是我們想要的效果啊管宵。

3. 參數(shù) sender 的作用

我們想要的效果是,點擊哪個按鈕攀甚,哪個按鈕變成叉號箩朴。這怎么辦?建立八個Outlet連接秋度?太麻煩了炸庞!這時候,我們就用到了@IBAction func buttonPressed():方法中參數(shù) sender 的功能:

    @IBAction func buttonPressed(sender: AnyObject) {
        var image = UIImage(named: "cross.png")
        
        sender.setImage(image, forState: UIControlState.Normal)
    }

用了sender荚斯,我們可以把一開始創(chuàng)建的Outlet連接刪掉了埠居。
這效果對了查牌。

4. Tag 屬性的作用

Button控件有個屬性叫 tag,如下圖:


每個Button控件的Tag是一個單獨的數(shù)字滥壕,這樣就給每個Button控件一個唯一的標識符纸颜。Tag的作用像是標識符(identifier),不過tag只能是Int類型的數(shù)值且正數(shù)绎橘。

第一個Button控件的tag是0胁孙,第二個是2,以此類推称鳞,第九個是8涮较。

這樣,當我們點擊集中某個按鈕時冈止,sender.tag就是我們設置的對應的tag值狂票。比如我們給最后一個Button設置的tag值是8,點擊最后一個Button時靶瘸,sender.tag實際上就是數(shù)字8苫亦。

5.實現(xiàn)圓圈叉號交替出現(xiàn)的效果

在Storyborad中去掉Button的圖片,按鈕是叉號還是圓圈全部用代碼來控制怨咪。

    // 1 是圓圈 2 是叉號
    var activePlayer = 1

    @IBAction func buttonPressed(sender: AnyObject) {
        var image = UIImage()
        
        if activePlayer == 1 {
            image = UIImage(named: "nought.png")!
            activePlayer = 2
        } else {
            image = UIImage(named: "cross.png")!
            activePlayer = 1
        }

        sender.setImage(image, forState: UIControlState.Normal)
    }

運行屋剑,點擊不同的框,先出現(xiàn)圓圈然后叉號诗眨,不錯唉匾,幾乎是我們的效果了。不過匠楚,點擊出現(xiàn)圓圈巍膘,再點擊一下,變成叉號了芋簿。需要的效果是峡懈,在某個框中畫了圈或者叉號,就不能再改了与斤。

三肪康、寫代碼:實現(xiàn)游戲規(guī)則

1.數(shù)組的力量

現(xiàn)在我們想辦法讓被點擊過一次的按鈕再次點擊時不會更換圖片。這里我們用到數(shù)組撩穿。

    var gameState = [0,0,0,0,0,0,0,0,0]
    
    @IBAction func buttonPressed(sender: AnyObject) {
        if gameState[sender.tag] == 0 {
            var image = UIImage()
            
            gameState[sender.tag] = activePlayer
            
            if activePlayer == 1 {
                image = UIImage(named: "nought.png")!
                activePlayer = 2
            } else {
                image = UIImage(named: "cross.png")!
                activePlayer = 1
            }
            
            sender.setImage(image, forState: UIControlState.Normal)

        }
    }

妙用了數(shù)組的index 和 sender.tag磷支。
關鍵代碼:

gameState[sender.tag]

sender.tag可能的值是數(shù)字0-8,數(shù)組gameState的index也是0-8

2.什么條件就贏了食寡?

這才是一個游戲的關鍵雾狈,涉及到算法,很多游戲的算法才是關鍵抵皱,界面什么的都好弄善榛。
先列出作者的代碼辩蛋,燒腦:

var winningCombinations = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]

@IBAction func buttonPressed(sender: AnyObject) {
    ...

    for combination in winningCombinations {
         if gameState[combination[0]] != 0 && gameState[combination[0]] == gameState[combination[1]] && gameState[combination[1]] == gameState[combination[2]] {
                    print("你贏啦!锭弊!")
         }
    }
}

想要實現(xiàn)游戲規(guī)則堪澎,首先我們要判斷出什么情況下就算是贏了。比如橫著3個連成行味滞,豎著3個連成排樱蛤,斜著3個連成一條線。
橫著3個連成行:[0,1,2],[3,4,5],[6,7,8]
豎著3個連成排[0,3,6],[11,4,7],[2,5,8]
斜著3個連成一條線[0,4,8],[2,4,6]
看代碼:

關鍵代碼是:

gameState[combination[0]] != 0 && gameState[combination[0]] == gameState[combination[1]] && gameState[combination[1]] == gameState[combination[2]]

可以拆分成3個條件:
1)首先不等于0
2)第一個數(shù)等于第二個
3)第二個數(shù)等于第三個數(shù)字

只需要遍歷所有的情況剑鞍,然后只要符合這個情況昨凡,就算贏啦

3.有人贏了之后就停止游戲

gameActive = false

在你贏了之后,賦值

 @IBAction func buttonPressed(sender: AnyObject) {
        //這里加入 gameActive 狀態(tài)的判斷
        if (gameState[sender.tag] == 0 && gameActive == true) {

4.判斷是誰贏了蚁署,彈出顯示文案

 if gameState[combination[0]] == 1 {
     gameOverLabel.text = "Noughts have won!"
 } else {
    gameOverLabel.text = "Crosses have won!"
 }
endGame()

endGame的方法如下:

    func endGame() {
    
        gameOverLabel.hidden = false
        playAgainButton.hidden = false
    
        UIView.animateWithDuration(0.5, animations: { () -> Void in
    
            self.gameOverLabel.center = CGPointMake(self.gameOverLabel.center.x + 500, self.gameOverLabel.center.y)
    
            self.playAgainButton.center = CGPointMake(self.playAgainButton.center.x + 500, self.playAgainButton.center.y)
        })
    }

四便脊、寫代碼:

課程筆記記錄到了27:00

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市光戈,隨后出現(xiàn)的幾起案子哪痰,更是在濱河造成了極大的恐慌,老刑警劉巖久妆,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晌杰,死亡現(xiàn)場離奇詭異,居然都是意外死亡筷弦,警方通過查閱死者的電腦和手機肋演,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烂琴,“玉大人爹殊,你說我怎么就攤上這事〖楸粒” “怎么了梗夸?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長号醉。 經(jīng)常有香客問我绒瘦,道長,這世上最難降的妖魔是什么扣癣? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮憨降,結果婚禮上父虑,老公的妹妹穿的比我還像新娘。我一直安慰自己授药,他們只是感情好士嚎,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布呜魄。 她就那樣靜靜地躺著,像睡著了一般莱衩。 火紅的嫁衣襯著肌膚如雪爵嗅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天笨蚁,我揣著相機與錄音睹晒,去河邊找鬼。 笑死括细,一個胖子當著我的面吹牛伪很,可吹牛的內容都是我干的。 我是一名探鬼主播奋单,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼锉试,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了览濒?” 一聲冷哼從身側響起呆盖,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贷笛,沒想到半個月后应又,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡昨忆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年丁频,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邑贴。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡席里,死狀恐怖,靈堂內的尸體忽然破棺而出拢驾,到底是詐尸還是另有隱情奖磁,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布繁疤,位于F島的核電站咖为,受9級特大地震影響,放射性物質發(fā)生泄漏稠腊。R本人自食惡果不足惜躁染,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望架忌。 院中可真熱鬧吞彤,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至埋嵌,卻和暖如春破加,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雹嗦。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工范舀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俐银。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓尿背,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捶惜。 傳聞我的和親對象是個殘疾皇子田藐,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內容