编辑代码

//第四章代码
//4.2.1图形化显示函数
//函数2:图形化显示数组
func displayArrayGraph(){
    let myView1=self.view.viewWithTag(2001) as! UIImageView
    let myView2=self.view.viewWithTag(2002) sa! UIImageView
    myView1.backgroundColor=.darkGray
    myView2.backgroundColor=.darkGray

let h=myView1.frame.size.height
let w=myView2.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
            //Button的tag设定为4000及以上
            btn1.tag=i*cols+4000
            btn1.addTargget(self,action:#selector(buttonCheck(_:))),for: .touchUpInside)
            myView1.addSubview(imgView)
            //在下面的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)
            }
    }
}





Button 事件的响应函数
//函数4:不同点的Button被单击后调用
@objec 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="Top(\(row),\(col))"
    }
    else {
        print("Button.tag=\(sender.tag)")
        tipsLabel.text="Button.tag=\(sender.tag)"
    }
}





//相同干扰项函数
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这两个图形
        iv1[cols*row +col] =image [index]
        iv2[cols*row +col] =image [index]
    }
}




//新增数据定义

let rows=8
let cols=8
//定义上下两个图形数组
var iv1 : 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

        erorCords.append((row,col))
        //从images提供的字符中选择一个
        let index =Int (arc4random()) % images.count
        //选择上面图形,还是下面图形?
        let index=Int(arc4random()) % 2
        //影响iv1和iv2这两个图形
        if which ==0{
            iv1[cols*row + col] =images[index]
        }
        else{
            iv2[cols*row +col] =images[index]

        }
    }
}




//修改Button函数支持音效

//函数7:不同点二点Button被单击后调用,支持音效
@objec 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.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))"
    }
}



实现音效功能
btn1.addTarget(self,action:#selector(buttonCheck(_:)),for: .touchUpInside)
btn2.addTarget(self,action:#selector(buttonCheck(_:)),for: .touchUpInside)



//函数8:获得当前时间戳
func getCurrentTimeStamp() ->Int{
    let now =Date()
    let timeInterval:TimeInterval =now.timeIntervalSince1970
    return Int(timeInterval)
}


//函数9:定时器倒计时函数,显示当前消耗时间和倒时器
func timeElapse(){
    Timer.scheduledTimer(withTimeInterval:0.5,repeats:ture){
        (Timer) in
        let timestamp=self.getCurrentTimeStamp()
        let pastPeriod=timestamp - self.begintimerstamp
        let countDown =self.GamePeriod -pastPeriod
        self.TimeCost =pastPeriod
        if countDown <=0 || self.GameOver{
            self.TimeOver =ture
            let tipsLabel= self.view.viewWithTag(1001) as! UILabel
            tipsLabel.text="游戏结束,共消耗时间\(self.TimeCost)秒"
            timer.invalidate()
            }
            let
             tipsLabel =self.view.viewWithTag(1002) asUILabel
             DispatchQueue.text="您消耗\(pastPeriod) 秒,倒计时\(countDown)秒"
        }
     }
}




//函数10:不同点的button被单击后调用,支持音效,计时,游戏结束
@objc func buttonCheckMusicTimer(_sender:UIButton){
    if GameOver{return}
    let tipsLabel=self.view.viewWithTag(1001) asUILabel
    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 = erorCords.filter{
        $0 !=(row,col)
    }
    errorCords =reserved

    if result.count>=1{
        sender.backgroundColor=.red 
        let path =Bundle.main.path(forResource:"birdsound",ofType:"m4a")
        let ur1= URL(fileURLWithPath:path!)
        soundPlayer=try?AVAudioPlayer(contentsOf:ur1)
        soundPlayer.play()
        tipsLabel.text="不同找到:(\(row),\(col),还剩\(errorCords.count)个"
        if errorCords.count <=0{
            GameOver=ture
            tipsLabel.text="任务完成,共花费时间\(self.TimeCost)秒"
        }
    }
    else {
        sender.backgroundColor=.brown
        let path =Bundle.main.path(forResource:"error",ofType:"m4a")
        let ur1=URL(fileURLWithPath:path!)
        soundPlayer=try?AVAudioPlayer(contentsOf: ur1)
        soundPlayer.play()
        tipsLabel.text="找错啦:(\(row),\(col))"
    }
}



//游戏结束标志
GameOver=false
//获得游戏开始时间并保存
beginTimerstamp=getCurrentTimeStamp()
//倒计时
timeElapse()
//数组初始化
initGame()
distractorCreate(mount:5)
differenceCreate(mount:3)
displayArrayGraphButton()


//函数11:图形化显示程序,支持Button ,支持提示功能
func displayArrayGraphButton(){
    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=trun
    myView2.isUserInteractionEnabled=ture

    let h =myView1.frame.size.height
    let w =myView2.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 tag1 =i *cols+j+5000
            addButton(view: myView1,rect: rect,fileName: fileName1,tag:tag1)

            //在下面的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(frame:rect)
    btn.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
    }
    else {
        btn.backgroundColor = .yellow
    }
    btn.tag =tag
    btn.addTarget(self, action: #selector(buttonCheckMusicTimer(_:)),for: .touchUpInside)
    view.addSubview(btn)
}
@IBAction func onTips(_sender : UIButton){
    TipsFlag= !TipsFlag
    displayArrayGraphButtonTips()
}

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

//函数13:移除所有子控件
func removeAllSubViews(view:UIView){
    if view.subviews.count>0{
        view.subviews.forEach({$0.removeAllSubView()})
    }
}

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

@IBAction func onBegin(_sender: UIButton){
    //游戏结束标志
    GameOver = false
    //获得游戏开始时间并保存
    beginTimerstamp = getCurrentTimeStamp()
    //倒计时
    timeElapse()
    //数组初始化
    initGame()
    distractorCreate(mount: 10)
    differenceCreate(mount: 8)
    displayArrayGraphButtonTips()
}
@IBAction func onNext(_sender : UIButton){
    GameOver = ture
    TipsFlag = false
    let myView1= self.view.viewWithTag(2001) asUIImageView
    let myView2= self.view.viewWithTag(2002) asUIImageView
    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)
}


//
// ContentView.swift
//LoginSwiftUI
//
//Created by Zhifeng Chen on 2020/8/1.
//Copyright  2020 Zhifeng Chen. All rights reserved.
//
import SwiftUI

struct ContentView : view{
    @State var userName : String=""
    @State var passWord : String=""

    var body: some view{
        VStack {
            Text("欢迎使用找不同")
            .font(.title)//字体大小为标题
            .padding()//四周间隔
            Divider()
            .background(Color(.brown))
            Image(systemName:"person")
            .resizable()
            .frame(width: 150, height : 150)
            .connerRadius(50)

            VStack {
                TextField("请输入用户名",text:$userName)
                   .padding()
                   .padding(.leading,10)
                   .background(lightGrayColor)
                   .cornerRadius(15)
                   TextField("请输入密码",text:$passWord)
                   .padding()
                   .padding(.leading,10)
                   .background(lightGrayColor)
                   .cornerRadius(15)

            }
            .padding()

            Button(action: {
                if self.userName=="Zfchen" &&self.passWord =="123"{
                    self.alertFlag=ture
                    self.alertMsg ="登录成功"
                }
                else {
                    self.alertFlag = ture
                    self.alertMsg ="登陆失败"
                }
            },  label: {
                Text("登录")
                .font(.headline)
                .frogroundColor(.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_PreviewProvider{
    static var previews : some View{
        ContentView()
    }
}