Shadowverse精神衰落/連連看 第一版

pan
彼得潘的 Swift iOS / Flutter App 開發教室
11 min readJan 9, 2020

製作時間:大約兩個晚上

這是簡單的益智遊戲,可以用撲克牌來玩

但想到卡牌,我只會想到遊戲王、爐石戰記、暗影詩章等卡牌手遊(電玩中毒?)

這次使用暗影詩章(Shadowverse)的卡圖來顯示

推坑(XD

因為我只有ipad Air 所以製作了平板的介面 我可以休閒時玩玩

我是不是該買iphone呢?<No $$$$$>

實際遊玩畫面
import UIKitimport GameplayKitclass OpenViewController: UIViewController {@IBOutlet var cardCollections: [UIButton]!@IBOutlet weak var timeLabel: UILabel!@IBOutlet weak var flipPointLabel: UILabel!let face = [UIImage(named: "a"),UIImage(named: "b"),UIImage(named: "c"),UIImage(named: "d"),UIImage(named: "e"),UIImage(named: "f")]var faceArray = [UIImage]()var  counter = 0.0var timer:Timer?var isPlaying = falsevar count = 0var sum = 0var point = 0override func viewDidLoad() {super.viewDidLoad()gameInit()}var flipCount: Int = 0{didSet{flipPointLabel.text = String(flipCount)}}struct MatchState {var isOnBinding = falsevar bindCardIdentifier: Int = 0var bindCardCollectionIndex: Int? = nilvar timeoutHolding = false}var matchState = MatchState()@objc func UpdateTimer() {counter = counter + 1.0if Float(counter) == 180.0 {timer?.invalidate()timer = nilisPlaying = falselet controller = UIAlertController(title: "You lose QQ", message: "回家練練再來吧!", preferredStyle: .alert)let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)controller.addAction(okAction)present(controller, animated: true, completion: nil)}timeLabel.text = String(format: "%.1f", counter)}@IBAction func touchCard(_ sender: UIButton) {if timer == nil{timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(UpdateTimer), userInfo: nil, repeats: true)}isPlaying = trueif let cardIndex = cardCollections.firstIndex(of: sender), !cards[cardIndex].isMatch ,!matchState.timeoutHolding{//是否是還沒翻過牌(兩次的第一次)if !matchState.isOnBinding{matchState.isOnBinding = truematchState.bindCardIdentifier = cards[cardIndex].identifiermatchState.bindCardCollectionIndex = cardIndexflipCount += 1sender.setImage(cards[cardIndex].cardImage, for: .normal)UIView.transition(with: sender, duration: 0.3, options: .transitionFlipFromRight, animations: nil, completion: nil)}else{if let bindingIndex = matchState.bindCardCollectionIndex, bindingIndex !=cardIndex{matchState.isOnBinding = falseflipCount += 1//判斷是否相同sender.setImage(cards[cardIndex].cardImage, for: .normal)UIView.transition(with: sender, duration: 0.3, options: .transitionFlipFromRight, animations: nil, completion: nil)if matchState.bindCardIdentifier == cards[cardIndex].identifier{viewCardChange(for: bindingIndex, withImage: matchImage, transFrom: .transitionFlipFromTop)cards[bindingIndex].isMatch = trueviewCardChange(for: cardIndex, withImage: matchImage, transFrom: .transitionFlipFromTop)cards[cardIndex].isMatch = truecount = count + 1point = point + 20if (count == 6) {sum = point - flipCountif let controller = storyboard?.instantiateViewController(withIdentifier: "scorepage")as? ScoreViewController {controller.nameText = String(sum)present(controller, animated: true, completion: nil)}}}else{matchState.timeoutHolding = trueDispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {self.viewCardChange(for: bindingIndex, withImage: self.backImage, transFrom: .transitionFlipFromLeft)self.viewCardChange(for: cardIndex, withImage: self.backImage, transFrom: .transitionFlipFromLeft)self.matchState.timeoutHolding = false}}}}}}func viewCardChange (for cardIndex: Int, withImage: UIImage, transFrom: UIView.AnimationOptions){cardCollections[cardIndex].setImage(withImage, for: .normal)UIView.transition(with: cardCollections[cardIndex], duration: 0.8, options: transFrom, animations: nil, completion: nil)}let backImage = UIImage(named: "ba")!let matchImage = UIImage(named: "ok")!var cards = [Card]()struct Card {var cardImage:UIImagelet identifier: Intvar isMatch:Bool}func gameInit() {faceArray = [UIImage]()cards = [Card]()choiceFace()//亂數取出圖案//將圖案分配給卡片for i in cardCollections.indices {let btn = cardCollections[i]let card = Card(cardImage: faceArray[i], identifier: face.firstIndex(of: faceArray[i])! , isMatch: false)cards.append(card)btn.setImage(backImage, for: .normal)}}//取出目前所有卡片二分之一的圖案func choiceFace() {let randomOfnums = GKShuffledDistribution(lowestValue: 0, highestValue: face.count - 1)let numberOfPairsOfCards = Int(cardCollections.count / 2)for _ in 0 ..< numberOfPairsOfCards{let index = randomOfnums.nextInt()if let faceX = face[index] {faceArray.append(faceX)faceArray.append(faceX)}}faceArray.shuffle()}@IBAction func resetBtn(_ sender: UIButton) {gameInit()flipCount = 0isPlaying = falsetimer?.invalidate()timer = nilcounter = 0.0timeLabel.text = String(counter)count = 0}}extension Array{mutating func shuffle() {for _ in 0 ..< self.count {sort{(_,_) in arc4random() < arc4random()}}}}

主要控制的程式

import UIKitclass ScoreViewController: UIViewController {var nameText:String = " "@IBOutlet weak var myPoint: UILabel!override func viewDidLoad() {super.viewDidLoad()myPoint.text = nameText}@IBAction func backButton(_ sender: Any) {dismiss(animated: false)}}

接收成績,並且呈現出來

心得:目前的版本還不是很滿意,畫面不是很完美,之後再改進畫面跟動畫的呈現,能的話追加數量

花了點時間才寫完,有些還沒學習到google了一下

附上GitHub 恩!

--

--