官术网_书友最值得收藏!

Finishing the game

In this section, we will finally be able to play the game.

Implementing the game logic

After having all the required functions in place, it's now a straightforward task to complete the game. First of all, we add the instance variables to hold the number of the pairs already created, the current score, and the list of selected cards turned up:

private var selectedIndexes = Array<NSIndexPath>()
private var numberOfPairs = 0
private var score = 0

Then, we apply the logic when a card is selected:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        if selectedIndexes.count == 2 || selectedIndexes .contains(indexPath) {
                return
            }
            selectedIndexes.append(indexPath)

        let cell = collectionView.cellForItemAtIndexPath(indexPath)
        as! CardCell
        cell.upturn()

        if selectedIndexes.count < 2 {
            return
        }

        let card1 = deck[selectedIndexes[0].row]
        let card2 = deck[selectedIndexes[1].row]

        if card1 == card2 {
            numberOfPairs++
            checkIfFinished()
            removeCards()
        } else {
            score++
            turnCardsFaceDown()
        }
}

We first check whether we have touched an already turned-up card or whether we have two cards turned up. If not, we save the index. Then, we check whether we have flipped the first card, and if not, we proceed to check the values of the cards.

The pattern of checking a condition and leaving the current function if the condition is true is called Guard. It helps make the code more readable by avoiding the use of the else clause and the nesting of curly braces.

We got a pair

As shown in the previous part of the source, we implement the missing actions in a private extension:

// MARK: Actions
private extension MemoryViewController {
    func checkIfFinished(){
    }
    func removeCards(){
    }
    func turnCardsFaceDown(){
    }
}

The first one checks whether we have completed all the pairs, and if so, it presents a popup with the score and returns to the main menu:

func checkIfFinished(){
    if numberOfPairs == deck.count/2 {
        showFinalPopUp()
    }
}
func showFinalPopUp() {
    let alert = UIAlertController(title: "Great!", message: "You won with score: \(score)!", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { action in self.dismissViewControllerAnimated(true, completion: nil)}))

    self.presentViewController(alert, animated: true, completion: nil)
}

Note that in iOS 8, UIAlertController is slightly different from that in the previous version. In our case, a simple dialog box with an OK button is enough.

If the cards are equal, we need to remove them:

func removeCards(){
    execAfter(1.0) {
        self.removeCardsAtPlaces(self.selectedIndexes)
        self.selectedIndexes = []
    }
}

func removeCardsAtPlaces(places: Array<NSIndexPath>){
    for index in selectedIndexes {
        let cardCell = collectionView.cellForItemAtIndexPath(index)
         as! CardCell
         cardCell.remove()
    }
}

The remove() function in CardCell is similar to turnUp() and turnDown(), but instead of making a transition, it just performs an animation before hiding the cell:

func remove() {
    UIView.animateWithDuration(1,
        animations: {
            self.alpha = 0
        },
        completion: { completed in
        self.hidden = true
    })
}

We made the wrong move

Finally, if the cards are different, we need to turn them down:

func turnCardsFaceDown(){
    execAfter(2.0) {
        self.downturnCardsAtPlaces(self.selectedIndexes)
        self.selectedIndexes = []
    }
}

func downturnCardsAtPlaces(places: Array<NSIndexPath>){
    for index in selectedIndexes {
        let cardCell = collectionView.cellForItemAtIndexPath(index)
        as! CardCell
        cardCell.downturn()
    }
}

Et voilà! The game is completed

As you can see in the following screenshot, the game presents a smooth animation and nice images:

Note

The complete source can be downloaded from https://github.com/gscalzo/Swift2ByExample/tree/2_Memory_4_Complete.

主站蜘蛛池模板: 镇原县| 潢川县| 镇雄县| 正宁县| 滁州市| 平安县| 霍山县| 塔城市| 崇明县| 商丘市| 安宁市| 临城县| 瑞安市| 瑞昌市| 乐业县| 钟山县| 博爱县| 长葛市| 文水县| 湖北省| 顺昌县| 额尔古纳市| 合水县| 酒泉市| 白朗县| 河池市| 莱芜市| 丰县| 宁强县| 长沙市| 博野县| 泗水县| 台东市| 沂南县| 广东省| 航空| 咸丰县| 南郑县| 永济市| 拉萨市| 普兰店市|