编辑代码

//4.2.1主界面显示
//函数2:图形化显示数组
func displayArrayGraph() {
    let myView1 = self.view.viewWithTag(2001) as! UIImageView
    let myView2 = self.view.viewWithTag(2002) as! UIImageView
    myView1.backgroundColor = .darkGray
    myView2.backgroundColor = .darkGray

    let h = myView1.frame.size.height
    let w = myView1.frame.size.width

    let padding : CGFloat = 5
    let margin : CGFloat = 10

    //计算每个格子的高度和宽度
    let grid_w = (w - margin * 2 - padding * CGFloat(cols-1)) / CGFloat(cols)
    let grid_h = (h - margin * 2 - padding * CGFloat(rows-1)) / CGFloat(rows)

    for i in 0..<rows {
        for j in 0..<cols {
            let x = margin + CGFloat(j) * (grid_w + padding)
            let y = margin + CGFloat(i) * (grid_h + padding)
            let rect = CGFloat(x: x, y:y, width: grid_w, height: grid_h)
            //在上面的ImageView中显示
            let fileName1 = iv1[i*cols+j]
            let img1 = UIImage(named: fileName1)
            let imgView1 = UIImageView(frame: rect)
            imgView1.image = img1
            imgView1.backgroundColor = .yellow
            myView1.addSubview(imgView1)
            //在下面的ImageView中显示
            let fileName2 = iv2[i*cols+j]
            let img2 = UIImage(named: fileName2)
            let imgView2 = UIImageView(frame: rect)
            imgView2.image = img2
            imgView2.backgroundColor = .yellow
            myView2.addSubview(imgView2)
        }
    }
}
//4.2.2基础功能
//函数3:图形显示程序,支持Button
func displayArrayGraphBuhhon() {
    let myView1 = self.view.viewWithTag(2001) as! UIImageView
    let myView2 = self.view.viewWithTag(2002) as! UIImageView
    myView1.backgroundColor = .darkGray
    myView2.backgroundColor = .darkGray
    //支持View可以进行交互等操作
    myView1.isUserInteractionEnabled = true
    myView2.isUserInteractionEnabled = true

    let h = myView1.frame.size.height
    let w = myView1.frame.size.width

    let padding : CGFloat = 5
    let margin : CGFloat = 10

    //计算每个格子的高度和宽度
    let grid_w = (w - margin * 2 - padding * CGFloat(cols-1)) / CGFloat(cols)
    let grid_h = (h - margin * 2 - padding * CGFloat(rows-1)) / CGFloat(rows)

    for i in 0..<cols {
        for j in 0..<cols {
            let x = margin + CGFloat(j) * (grid_w + padding)
            let y = margin + CGFloat(i)*(grid_h + padding)
            let rect = CGRect(x: x,y:y , width: grid_w, height: grid_h)
            //在上面的ImageView中显示
            let fileName1 = iv1[i*cols+j]
            let img1 = UIImage(named: fileName1)
            let btn1 = UIButton(frame: rect)
            btn1.setImage(img1, for: .normal)
            btn1.backgroundColor = .yellow
            //Button的tag设定为4000及以上
            btn1.tag = i*cols+j + 4000
            btn1.addTarget(self, action: #selector(buttonCheck(_:)),for: .touchUpInside)
            myViewl.addSubview(btn1)
            //在下面的ImageView中显示
            let fileName2 = iv2[i*cols+j]
            let img2 = UIImage(named: fileName2)
            let btn2 = UIButton(frame: rect)
            btn2.setImage(img2, for: .normal)
            btn2.backgroundColor = .yellow
            //Button的tag设定为5000及以上
            btn2.tag = i*cols+j + 5000
            btn2.addTarget(self, action: #selector(buttonCheck(_:)),for: .touchUpInside)
            myView2.addSubview(btn2)
        }
    }
}
//函数4:不同点的Button被单击后调用
@objc func buttonCheck(_ sender : UIButton) {
    let tipsLabel = self.view.viewWithTag(1001) as! UILabel
    let tag = sender.tag
    if tag >= 5000 {
        let row = Int ((tag - 5000) / cols)
        let col = tag - 5000 - cols * row
        print("Bottom(\(row),\(col))")
        tipsLabel.text = "Bottom(\(row),\(col))"
    }
    else if tag >= 4000 {
        let row = Int ((tag - 4000) / cols)
        let col = tag - 4000 - cols * row
        print("Top(\(row),\(col)")
        tipsLabel.text = "Top(\(row),\(col))"
    }
    else {
        print("Button.tag=\(sender.tag)")
        tipsLabel.text = "Button.tag=\(sender.tag)"
    }
}
//函数5:生成干扰项的随机位置和随机内容
func distractorCreate(mount:Int){
    for _ in 0..<mount {
        let col = Int(arc4random()) % cols
        let row = Int(arc4random()) % rows

        cords.append((row,col))
        //从images提供的字符中选择一个
        let index = Int(arc4random()) % images.count
        //影响ivl和iv2这两个图形
        ivl[cols*row + col] = images[index]
        iv2[cols*row + col] = images[index]
    }
}
//数据定义开始--
//定义行数和列数
let rows = 8
let cols = 8
//定义上下两个图形数组
var ivl : Array<String> = []
var iv2 : Array<String> = []
//定义上下相同的干扰项数组
var cords : Array<(Int,Int)> = []
//干扰项和不同项只能是小图形
let images ; Array<String> = ["bird","bee","flower","mogu"]
//4.2.3音效功能
//函数6:生成不同项的随机位置和随机内容
func differenceCreate(mount:Int){
    for _ in 0..<mount {
        let col = Int(arc4random()) % cols
        let row = Int(arc4random()) % rows

        errorCords.append((row,col))
        //从images提供的字符中选择一个
        let index = Int(arc4random()) % images.count
        //选择上面图像,还是下面图形?
        let which = Int(arc4random()) % 2
        //影响ivl和iv2这两个图形
        if which ==0 {
            ivl[cols*row + col] = images[index]
        }
        else {
            iv2[cols*row + col] = images[index]
        }
    }
}
//函数7:不同点的Butten被单机后调用,支持音效
@objc func buttonCheckMusic(_ sender : UIButton) {
    let tipsLabel = self.view.viewWithTag(1001) as! UILabel
    var tag = sender.tag
    if tag >= 5000 {
        tag -= 5000
    }
    else if tag >= 4000{
        tag -= 4000
    }
    let row = Int (tag / cols)
    let col = tag - cols * row

    let result = errorCords.filter {
        $0 ==(row,col)
    }
    if result.count >= 1 {
        let path = Bundle.main.path(forResource:"birdsound",ofType:"m4a")
        let url = URL(fileURLWithPath: path!)
        soundPlayer=try? AVAudioPlayer(contentsOf: url)
        soundPlayer.play()
        tipsLabel.text = "不同找到:(\(row),\(col))"
    }
    else {
        let path = Bundle.main.path(forResource:"error",ofType:"m4a")
        let url = URL(fileURLWithPath:path!)
        soundPlayer=try? AVAudioPlayer(contentsOf: url)
        soundPlayer.play()
        tipsLabel,text = "找错啦:(\(row),\(col))"
    }
}

btnl.addTarget(self, action: #selector(buttonCheckMusic(_:)),for: .touchUpInside)
btn2.addTarget(self, action: #selector(buttonCheckMusic(_:)),for: .touchUpInside)
//4.2.4计时功能
//游戏是否结束标记
var GameOver = flase
//游戏开始时间戳
var beginTimestamp : Int = 0
//游戏限定时间,单位:秒
let GamePeriod = 20
//游戏本次花费时间,单位:秒
var TimeCost = 0
//函数8:获得当前时间戳
func getCurrentTimeStamp() -> Int {
    let now = Date()
    let timeInterval : timeInterval = now.timeIntervalSince1970
    return Int(timeInterval)
}
//函数9:定时器倒计时函数,显示当前消耗时间和倒计时
func timeElapse() {
    Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) {
        (timer) in
        let timestamp = self.getCurrentTimeStamp()
        let pastPeriod = timestamp - self.neginTimestamp
        let countDown = self.GamePeriod - pastPeriod
        self.TimeCost = pastPeriod
        if countDown <= 0 || self.GameOver {
            self.GameOver = true
            let tipsLabel = self.view.viewWithTag(1001) as! UILabel
            tipsLabel.text = "游戏结束,共消耗时间\(self.TimeCost)秒"
            timer.invalidate()
        }
        let tipsLabel = self.view.viewWithTag(1002) as! UILabel
        DispatchQueue.main.async {
            tipsLabel.text = "您消耗\(pastPeriod)秒,倒计时\(countDown)秒"
        }
        
    }
}
//函数10:不同点的Button被单机后调用,支持音效,计时,游戏结束
@objc func buttonCheckMusicTimer(_sender : UIButton) {
    if GameOver {return}
    let tipsLabel = self.view.viewWithTag(1001) as! UILabel
    var tag = sender.tag
    if tag >= 5000{
        tag -= 5000
    }
    else if tag >= 4000 {
        tag -= 4000
    }
    let row = Int (tag / cols)
    let col = tag - cols * row

    let result = errorCords.filter {
        $0 ==(row.col)
    }
    let reserved = errorCords.filter {
        $0 !=(row.col)
    }
    errorCords = reserved

    if result.count >= 1 {
        sender.backgroundColor = .reserved
        let path = Bundel.main.path(forResource: "birdsound", ofType: "m4a")
        let url = URL(fileURLWithPath: path!)
        soundPlayer=try? AVAudioPlayer(countentsOf: url)
        soundPlayer.play()
        tipsLabel.text = "不同找到的: (\(row),\(col)),还剩\(errorCords.count)个"
        if errorCords.count <= 0 {
            GameOver = true
            tipsLabel.text = "任务完成,共花费时间\(self.TimeCost) 秒"
        }
    }
    else {
        sender.backgroundColor = .brown
        let path = Bundel.main.path(forResource: "error", ofType: "m4a")
        let url = URL(fileURLWithPath: path!)
        soundPlayer= try? AVAudioPlayer(contentsOf: url)
        soundPlayer.play()
        tipsLabel.text = "找错啦: (\(row),\(col))"
    }
}
//游戏结束标志
GameOver = fasle
//获取游戏开始时间并保存
beginTimestamp = getCurrentTimeStamp()
//倒计时
timeElapse()
//数组初始化
initGame()
distractorCreate(mount: 5)
differenceCreate(mount: 3)
displayArrayGraphBuhhon()
//函数11:图形化显示程序,支持Button,支持提示功能
func displayArrayGraphButtonTips() {
    let myViewl = self.view.viewWithTag(2001) as! UIImageView
    let myView2 = self.view.viewWithTag(2002) as! UIImageView
    myViewl.backgroundColor = .darkGray
    myView2.backgroundColor = .darkGray
    //支持view可以进行交互等操作
    myViewl.isUserInteractionEnabled = true
    myView2.isUserInteractionEnabled = true

    let h = myViewl.frame.size.height
    let w = myViewl.frame.size.width

    let padding : CGFloat = 5
    let margin : CGFloat = 10

    //计算每个格子的高度和宽度
    let grid_w = (w - margin * 2 - padding * CGFloat(cols-1)) / CGFloat(cols)
    let grid_h = (h - margin * 2 - padding * CGFloat(rows-1)) / CGFloat(rows)
    for i in 0..<rows {
        for j in 0..<cols {
            let x = margin + CGFloat(j) * (grid_w + padding)
            let y = margin + CGFloat(i) * (grid_h + padding)
            let rect = CGRect(x: x, y:y , width: grid_w, height: grid_h)
            
            //在上面的ImageView中显示
            let fileName2 = iv2[i*cols+j]
            let tag2 = i*cols+j + 4000
            addButton(view: myView2, rect: rect, fileName: fileName2, tag: tag2)
        }
    }
}
//函数12: view上面添加Button的函数,提示功能,用于减少代码数量
func addButton(view:UIView,rect:CGRect,fileName:String,tag:Int) {
    let img = UIImage(named:fileName)
    let btn = UIButton(fram: rect)
    bth.setImage(img, for: .normal)
    
    var mytag = tag
    if mytag >= 5000 {
        mytag -= 5000
    }
    else if mytag >= 4000 {
        mytag -= 4000
    }
    let row = Int (mytag / cols)
    let col = mytag - cols * row
    
    let result = errorCords.filter {
        $0 == (row,col)
    }

    if result.count >= 1 && TipsFlag {
        btn.backgroundColor = .blue
        btn.tag = tag
        bth.addTarget(self, action: #selector(buttonCheckMusicTimer(_:)),for: .touchUpInside)
        view.addSubview(btn)
    }

    let resultl = cords.filter {
        $0 == (row.col)
    }
    if resultl.count >= 1 {
        btn.tag = tag
        btn.addTarget(self, action: #selector(buttonCheckMusicTimer(_:)),for: .touchUpInside)
        view.addSubview(btn)
    }
}
//函数13:移除所有子控件
func removeAllSubViews(view:UIView) {
    if view.subviews.count>0 {
        view.subviews.forEach({$0.removeFromSuperview()})
    }
}

@IBAction func onTips(_sender : UIButton){
    TipsFlag = !TipsFlag
    displayArrayGraphButtonTips()
}

@IBAction func onBegin(_sender : UIButton){
//游戏结束标志
GameOver = flase
//获取游戏开始时间并保存
beginTimestamp = getCurrentTimeStamp()
//倒计时
timeElapse()
//数组初始化
initGame()
distractorCreate(mount: 10)
differenceCreate(mount: 8)
displayArrayGraphButtonTips()
}

@IBAction func onNext(_sender : UIButton){
    GameOver = true
    TipsFlag = flase
    let myView1 = self.view.viewWithTag(2001) as! UIImageView
    let myView2 = self.view.viewWithTag(2002) as! UIImageView
    CurrentBackground += 1
    if CurrentBackground > 4 {
        CurrentBackground = 1
    }
    let image = UIImage(named: "back0\(CurrentBackground)")!
    myView1.image = image
    myView2.image = image
    removeAllSubViews(view: myView1)
    removeAllSubViews(view: myView2)
}
//4.3拓展学习:SwifUI
//4.3.2登陆界面的实现
//
// ContentView.swift
// LoginSwiftUI
//
// Created by Zhifeng Chen on 2020/8/1.
// Copyright © 2020 Zhifeng. All rights reserved.
//
import LoginSwiftUI

struct ContentView : View {

    @State var userName : String = ""
    @State var passWord : String = ""

    var body: some View {
        VStack {
            Text("欢迎使用找不同")
            .font(.title)//字体大小为标题
            .padding()//四周间隔
            Divider()
            .background(Color(.brown))//背景色为brown
            Image(systemName:"person")//系统图像person
            .resizable()//允许改变图像尺寸
            .frame(width: 150, height: 150)//尺寸改为150*150
            .cornerRadius(50)//圆角半径50

            VStack {
                TextField("请输入用户名",text: $userName)
                .padding()//四周默认间隔
                .padding(.leading,10)//前方间隔10
                .background(Color(.lightGray))//背景色
                .cornerRadius(15)//圆角半径15
                TextField("请输入密码", text: $passWord)
                .padding()//四周默认间隔
                .padding(.leading,10)//前方间隔10
                .background(Color(.lightGray))//背景色
                .cornerRadius(15)//圆角半径15
            }
            .padding() //四周默认间隔

            Button(action: {
                print("被点击了...")
            }, label: {Text"登录")})
            .padding()

            Spacer()
        }
    }
}

struct ContentView_Previews: ContentViewPreviews {
    static var previews: some View {
        ContentView()
    }
}
//
// ContentView.swift
// LoginSwiftUI
//
// Created by Zhifeng Chen on 2020/8/1.
// Copyright © 2020 Zhifeng. All rights reserved
//

import LoginSwiftUI

let lightGrayColor = Color(red: 239.0 / 255.0, green: 243.0 / 255.0, blue: 244.0 / 255.0, opacity: 1.0)

struct ContentView : View {

    //保存输入的用户名
    @State var userName : String = ""
    //保存输入的密码
    @State var passWord : String = ""
    //是否需要弹出Alert窗口
    @State private var alertFlag : Bool = flase
    //弹出窗口里面的具体内容
    @State private var alertMsg : String = ""
    var body: some View {
        VStack {
            Text("欢迎使用找不同")
            .font(.title)//字体大小为标题
            .padding()//四周间隔
            Divider()
            .background(Color(.brown))//背景色为brown
            Image(systemName:"person")//系统图像person
            .resizable()//允许改变图像尺寸
            .frame(width: 150, height: 150)//尺寸改为150*150
            .cornerRadius(50)//圆角半径50

            VStack {
                TextField("请输入用户名",text: $userName)
                .padding()//四周默认间隔
                .padding(.leading,10)//前方间隔10
                .background(Color(.lightGray))//背景色
                .cornerRadius(15)//圆角半径15
                TextField("请输入密码", text: $passWord)
                .padding()//四周默认间隔
                .padding(.leading,10)//前方间隔10
                .background(Color(.lightGray))//背景色
                .cornerRadius(15)//圆角半径15
            }
            .padding() //四周默认间隔

            Button(action: {
                if self.userName =="Zfchen" && self.passWord == "123" {
                    self.alertFlag = true
                    self.alertMsg = "登录成功"
                }
                else {
                    self.alertFlag = true
                    self.alertMsg = "登录失败"
                }
                }, label: {
                    Text("登录")
                    .font(.headline)
                    .foregroundColor(.white)
                    .frame(width: 220, height: 60)
                    .background(Color.green)
                    .cornerRadius(15.0)
            })
            .padding()
            Spacer()
        }
        .alert(isPresented: $alertFlag) { () -> Alert in
        Alert(title: Text("登录提示"), message: Text(self.alertMsg),dismissButton: .default(Text("确定")))
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}