Tips

【Swift3.0対応】色彩チェックアプリを作成してみよう!【まとめ】

【Swift3.0対応】色彩チェックアプリを作成してみよう!【まとめ】

【まとめ】

最後に、今まで書いたコードを全て掲載します。Outlet接続がうまくできていればコピペでも
動くはずです。

実際にコードを記述したのはGameViewController.swiftとResultViewController.swift
の2つのファイルですので、その2つを載せます。

GameViewController.swift

import UIKit

class GameViewController: UIViewController {

    @IBOutlet weak var centerView: UIView!
    @IBOutlet weak var scoreLabel: UILabel!
    @IBOutlet weak var timeLabel: UILabel!
    
    var myButtonAry: [UIButton] = []
    var countNum: Int = 2
    var scoreNum = 0
    var timeNum = 60
    var colorLebel: CGFloat = 0.1
    var timer: Timer = Timer()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        makeBtn(num: countNum)
        showBtn(num: countNum)
        timer = Timer.scheduledTimer(timeInterval: 1.0,
                                     target: self,
                                     selector: #selector(countDown),
                                     userInfo: nil,
                                     repeats: true)
    }

    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    
    }
    
    //ボタンを生成するメソッド。引数(num)を1つ取る。numが列数を表す。num×num個のボタンを生成する。
    func makeBtn(num: Int) {
        
        //ランダムな色を生成して、その色を格納する定数を定義する
        let color = makeColor()
        
        //ボタンをnum×num個生成する。for文で回す。
        for _ in 1...(num*num) {
            let button = UIButton(type: UIButtonType.custom)
            button.backgroundColor = color.0    //この部分を変更する
            button.layer.cornerRadius = 5
            button.layer.masksToBounds = true
            
            myButtonAry.append(button)
        }
        
        //生成されたボタンの中で1つだけ正解となるボタンを作りたいので、ランダムな数値を生成する
        let random = Int(arc4random_uniform(UInt32(num*num)))

        //その「ランダムな数値」番目のボタンにだけ、色を正解の色に変更する
        myButtonAry[random].backgroundColor = color.1
        //その「ランダムな数値」番目のボタンにだけ、タップアクションを定義する
        myButtonAry[random].addTarget(self, action: #selector(onClickBtn), for: UIControlEvents.touchDown)
    }

    
    //ボタンのサイズと座標を指定し、画面に描画するメソッド。これも引数(num)を取る。
    func showBtn(num: Int) {

        //ボタンの1辺の長さを表す変数side
        var side: CGFloat = 0
        //numはInt型なので、計算用にCGFLoat型の変数にキャストしておく
        let CGFloatNum: CGFloat = CGFloat(num)
        //ボタンの1辺の長さは、centerViewの1辺の長さから、両端の5pt×2=10ptと、ボタン同士の隙間の間隔を引いて、num個で割る。
        side = (centerView.frame.width - (10 + (CGFloatNum-1)*2)) / CGFloatNum
        
        //座標用の変数xとyを定義。
        var x: CGFloat = 0
        var y: CGFloat = 0
        //各ボタンの座標は異なるので、それぞれのx座標,y座標の値をを格納する空の配列を用意しておく。
        //座標を指定する値もCGFloat型のため、CGFloat型で宣言する。
        var point: [(CGFloat, CGFloat)] = []
        
        //ボタンの座標をfor文で生成する。
        for i in 0...num-1 {
            for j in 0...num-1 {
                x = 5 + (side + 2) * CGFloat(j)
                y = 5 + (side + 2) * CGFloat(i)
                point.append((x,y))
            }
        }
        
        //各ボタンの座標に、pointの値とsideの値をfor文で回して設定していく。
        for i in 0...(num*num)-1 {
            myButtonAry[i].frame = CGRect(x: point[i].0, y: point[i].1, width: side, height: side)
            //生成したボタンを画面に表示する
            centerView.addSubview(myButtonAry[i])
        }
    }
    
    //ランダムな色を生成するメソッド
    func makeColor() -> (UIColor, UIColor) {
        //RGBのそれぞれの値をランダムに生成する。このように書くことで、0〜1までの小数点以下3桁までの値を取得できる。
        //このように書くことで、色のバリエーションが増える(ような気がする)
        let red: CGFloat = CGFloat(arc4random_uniform(1001)) / 1000
        let green: CGFloat = CGFloat(arc4random_uniform(1001)) / 1000
        let blue: CGFloat = CGFloat(arc4random_uniform(1001)) / 1000
        
        let color = UIColor(red: red, green: green, blue: blue, alpha: 1)
        
        //正解となるボタンの色を生成する。明度を明るくすることで違いを生み出す。
        //RGBの色は0〜1の値を設定することができ、1に近づけば近づくほど白色寄りに、0に近づけば黒色寄りになるため、
        //ちょっと色の値を小さくする。
        let correctRed: CGFloat = red + colorLebel
        let correctGreen: CGFloat = green + colorLebel
        let correctBlue: CGFloat = blue + colorLebel
        
        let correctColor = UIColor(red: correctRed, green: correctGreen, blue: correctBlue, alpha: 1)

        //外れボタンの色と正解ボタンの色を戻り値としてタプルで返す
        return (color, correctColor)
    }
    
    
    //ボタンがタップされた時のメソッドを定義
    func onClickBtn() {
        //スコアを1加算してテキストに埋め込む
        scoreNum = scoreNum + 1
        scoreLabel.text = "\(scoreNum)"
        
        //正解ボタンをタップすると、まず、一度画面からボタンを取り除き、配列も空にする。
        for i in 0...(countNum*countNum-1) {
            myButtonAry[i].removeFromSuperview()
        }
        myButtonAry.removeAll()
        
        //難易度調整メソッド実行。このメソッドを実行することでボタンの数と色の違いが変わる。
        decideDifficulty()
        
        //再度ボタンを生成。これで新しいランダムな色のボタン&正解ボタンもランダムに決められたボタンが画面に表示される。
        makeBtn(num: countNum)
        showBtn(num: countNum)
    }

    //残り時間を減らしていくメソッド
    func countDown() {
        //1秒ごとに表示する残り時間を1ずつ減らし、その数値をラベルに表示する
        timeNum = timeNum - 1
        timeLabel.text = "\(timeNum)"
        //0秒でタイマーを止める。
        if timeNum <= 0 {
            timer.invalidate()
            
            //さらに、このタイミングで画面遷移も行う
            self.performSegue(withIdentifier: "toResult", sender: nil)
        }
    }
    
    //ゲーム画面→結果表示画面のViewControllerにプロパティの値を渡す
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let newVC = segue.destination as! ResultViewController
        newVC.scoreNum = self.scoreNum
    }

    //スコアに応じて表示されるボタンの数と難易度を決めるメソッド。
    func decideDifficulty() {
        switch scoreNum {
        case 0:
            countNum = 2
            colorLebel = 0.1
        case 1:
            countNum = 3
            colorLebel = 0.09
        case 2:
            countNum = 4
            colorLebel = 0.08
        case 3,4:
            countNum = 5
            colorLebel = 0.07
        case 5,6:
            countNum = 6
            colorLebel = 0.06
        case 7...9:
            countNum = 7
            colorLebel = 0.05
        case 10...15:
            countNum = 8
            colorLebel = 0.04
        case 16...29:
            countNum = 9
            colorLebel = 0.03
        default:
            countNum = 10
            colorLebel = 0.02
        }
    }
    
}

GameViewController.swift

import UIKit

class ResultViewController: UIViewController {
    
    @IBOutlet weak var resultScoreLabel: UILabel!
    @IBOutlet weak var rankLabel: UILabel!
    var scoreNum: Int = 0


    override func viewDidLoad() {
        super.viewDidLoad()
        self.resultScoreLabel.text = String(scoreNum)
        showRank(num: scoreNum)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    
    }
    
    func showRank(num: Int) {
        var text: String
        switch num {
        case 0...10:
            text = "もっとがんばりましょう"
        case 11...20:
            text = "あと少しがんばりましょう"
        case 21...27:
            text = "正常な色彩です"
        case 28...32:
            text = "良い色彩の持ち主です"
        case 33...40:
            text = "素晴らしい色彩の持ち主です"
        default:
            text = "神レベル"
        }
        rankLabel.text = text
    }
}

これがみなさんの学習の助けになれば幸いです。

最後まで読んでいただいてありがとうございました!

TechProjin 開発系基礎講座 連載リンク

基礎からPHPWEBアプリ解発を学ぶなら・・
PHP基礎 連載

AIなどで注目急上昇!これから学ぶならPython!!
独学で学ぶ-pythonプログラミング 連載

汎用性◎ 定番プログラミング言語JAVA
Java基礎講座 連載

Recent News

Recent Tips

Tag Search