iOS TriLogic小游戏 教程

来源:互联网 发布:手机淘宝订单生成器 编辑:程序博客网 时间:2024/06/05 11:23

Swift3 小游戏开发 项目实战

最近在AppStore上看见一款小游戏,名字叫做:TriLogic,可以去看看游戏介绍再来写这个游戏。大体内容是 水灭火,火烧草,草克水,每个面板上有生命数,代表能走几步。走到能克的小块上就会同化为自己的颜色,最后全部小块变成一个颜色,游戏进入下一关。



上面图是store里的样子,下面图是我们今天要实现的:


下面开始写代码吧:


新建项目 在这里:

下面这个类就是起始界面,读者读一遍自己写

import UIKit


class ViewController: UIViewController {

    

    overridefunc viewDidLoad() {

        super.viewDidLoad()

       

        view.backgroundColor =UIColor.black

        let wid =view.bounds.width

        let hei =view.bounds.height

      

        let startButton1 =UIButton(frame:CGRect(x:0, y: hei/3, width: wid, height:20))

        startButton1.setTitleColor(UIColor.red, for: .normal)

        startButton1.setTitle("TriLogic", for: .normal)

        startButton1.contentHorizontalAlignment = .center

        startButton1.addTarget(self, action:#selector(start1), for: .touchUpInside)


        view.addSubview(startButton1)

 

    }


    func start1(){

//先新建一个类  TriLogicPanel 再写这个响应事件

        present(TriLogicPanel(), animated:false, completion:nil)

        

    }

}

好了,下面是游戏区的代码

import UIKit

import Foundation

class TriLogicPanel:UIViewController{   

先说明一下,这是简化版本,有10行6列,小格全是正方形,这里我用5.5寸的6p为例,为了简便直接设小格边长69,因为屏宽/6 = 69 ,那么高度10*69 屏幕还多了一点,正好用来做一个bar 看图 ,有返回按钮,重玩按钮等

先做完了简单版再说!

    let h = 46

    //存放6*10小格的区域:belowView:

    var belowView:UIView!

    //当前关卡数:

    var currentRank:Int!


    overridefunc viewDidLoad() {

        super.viewDidLoad()

        self.view.backgroundColor = #colorLiteral(red: 0.24, green: 0.67, blue: 0.97, alpha: 1) 

//颜色自己设个好看的就行

        let w =view.bounds.width

//这个 aboveView 是上面的 bar ,这个bar颜色要随时变的和第一行小格颜色相同(为了美观):   

        let aboveView =UIView(frame:CGRect(x:0, y:0, width:Int(w), height:h))

//对button初始化:

        let button =UIButton(frame:CGRect(x:10, y:17, width:70, height:26))

        let button2 =UIButton(frame:CGRect(x: w-78, y:17, width:70, height:26))

        let button3 =UIButton(frame:CGRect(x: w/2-35, y:17, width: 70, height:26))

       

  button.setTitle("HOME", for: .normal)

        button3.setTitle("RESET", for: .normal)

        button2.setTitle("SKIP", for: .normal)


        button2.addTarget(self, action:#selector(skip), for: .touchUpInside)

        button.addTarget(self, action:#selector(back), for: .touchUpInside)

        button3.addTarget(self, action:#selector(reset), for: .touchUpInside)


        aboveView.backgroundColor =UIColor.clear

//这里颜色设成透明,因为我们要呈现背景色,美观

        aboveView.addSubview(button3)

        aboveView.addSubview(button2)

        aboveView.addSubview(button)

        

        belowView =UIView(frame:CGRect(x:0, y:h, width:Int(w), height:690))

        view.addSubview(aboveView)

        view.addSubview(belowView)

  }

 //这是三个事件,现在先空着,一会再补上

 func back(){

        present(ViewController(), animated: false, completion: nil)

    }

    func skip(){

        

    }

    func reset(){

        

    }

    


现在开始想想游戏区是怎么实现的

每一个小块都有颜色,值属性,我们新建一个类来做小块:

为了简单起见,先不做难的,做个unit继承label算了.


import Foundation

import UIKit

class Unit:UILabel

{

    var color:Int =0{

        didSet{

//为了使代码好看点,可以使用枚举代表颜色,但是这里为了简单直接用switch吧 不同数字设置不同颜色

            switchcolor {

            case1:

                self.backgroundColor = #colorLiteral(red: 0.94, green: 0.35, blue:0.2, alpha: 1)

            case2:

                self.backgroundColor = #colorLiteral(red: 0.47, green: 0.76, blue:0.27, alpha: 1)

            default:

self.backgroundColor = #colorLiteral(red: 0.24, green: 0.67, blue:0.97, alpha: 1)

            }

        }

    }

    //边长

    let n =69

    //给value值,设好text,如果是0就不显示

    var value:Int =0{

        didSet{

            textvalue != 0"\(value)"""

        }

    }

    //这个是小块的位置,以后用

    let position:(row:Int,col:Int)



    //初始化,值,颜色,行,列

    init(value:Int,color:Int,row:Int,col:Int) {

        self.value = value

        self.color = color

        position = (row,col)

        super.init(frame:CGRect(x: col*n, y:n*row, width: n, height:n))  位置

        textColor =UIColor.black 

        textAlignment = .center 居中

    }

    

    required init?(coder aDecoder:NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }

    //设置值和颜色的方法

    func initState(value:Int,color:Int){

        self.value = value

        self.color = color

    }

    //返回小格位置的方法

    func getPosition() ->(row:Int,col:Int){

        returnposition

    }  

}

小格类写完了,准备在TriLogicPanel里初始化游戏面板,先加一个全局变量 

var arr = [[Unit]]() 用二维数组存放小格

viewDidLoad()里最后调用方法:

setUpInitialPanel()

    

    //添加这个方法:  

    func setUpInitialPanel(){ //设置初始面板

        var count =0

        for rowin0..<10{

            var arr1 = [Unit]()

            for colin0..<6{

                let viewUnit =Unit(value:0, color:0, row:row, col:col)

                

//设置标签是干什么的? 我们在手势事件里需要用标签确定是点了哪个 unit

count +=1

                viewUnit.tag = count 


//arr1是一行:

                arr1.append(viewUnit)


                //设为可以互动(UILabel默认不能互动):

                viewUnit.isUserInteractionEnabled =true


//添加手势 上下左右:

                let up =UISwipeGestureRecognizer(target:self,action:#selector(upCommand(_ :)))

手势的方法先在下面自己写个空的免得报错,一会补上

                up.direction = .up

                viewUnit.addGestureRecognizer(up)


                let down =UISwipeGestureRecognizer(target:self,action:#selector(downCommand(_:)))

                down.direction = .down

                viewUnit.addGestureRecognizer(down)

                

                let leftSwipe =UISwipeGestureRecognizer(target:self,action:#selector(leftCommand(_:)))

                leftSwipe.direction = .left

                viewUnit.addGestureRecognizer(leftSwipe)

                

                let rightSwipe =UISwipeGestureRecognizer(target:self,action:#selector(rightCommand(_:)))

                rightSwipe.direction = .right

                viewUnit.addGestureRecognizer(rightSwipe)

                

                belowView.addSubview(viewUnit)

            }

    //其实这里初始化空小格目的就是把arr给弄好。

    //以后再改小格颜色、值直接对arr操作 不用担心数组越界。

            arr.append(arr1)

        }

    }

    //四个响应方法   

    func upCommand(_ swiper:UISwipeGestureRecognizer){

      

    }

    func downCommand(_ swiper:UISwipeGestureRecognizer){

       

    }

    func leftCommand(_ swiper:UISwipeGestureRecognizer){

       

    }

    func rightCommand(_ swiper:UISwipeGestureRecognizer){

       

    }

   viewDidLoad()里最后调用方法

  setUpGame(rank:1) 开始第一关

添加方法:

    func setUpGame(rank:Int){

        currentRank = rank 

//对关卡switch,画内容

        switch rank {

//第一关

        case 1:

//上次把bar设成透明,才可能显示出背景色,这里把背景色设成和关卡最后的颜色一样

            view.backgroundColor = #colorLiteral(red: 0.24, green: 0.67, blue: 0.97,alpha: 1)

//先全部初始化为蓝色值为0,然后在设置个别的颜色

            for row in 0..<10{

                for col in 0..<6{

                    arr[row][col].initState(value:0, color:3)

                }

            }

            arr[2][1].initState(value:3, color: 1)

            arr[2][2].initState(value:2, color: 1)

            arr[2][3].initState(value:3, color: 1)

            arr[2][4].initState(value:4, color: 2)

            arr[4][2].initState(value:2, color: 2)

            arr[4][3].initState(value:4, color: 3)

            arr[5][2].initState(value:3, color: 3)

            arr[6][1].initState(value:4, color: 3)

//第二关。这些代码可照抄,无所谓

        case 2:

            for row in 0..<10{

                for col in 0..<6{

                    arr[row][col].initState(value:0, color:3)

                }

            }

            arr[3][1].initState(value:3, color: 2)

            arr[2][2].initState(value:7, color: 3)

            arr[3][2].initState(value:0, color: 2)

            arr[2][4].initState(value:0, color: 2)

            arr[2][3].initState(value:5, color: 1)

            arr[3][3].initState(value:5, color: 1)

            arr[3][4].initState(value:3, color: 2)

            arr[4][3].initState(value:7, color: 3)

            arr[4][2].initState(value:5, color: 1)

            arr[4][1].initState(value:0, color: 1)

            arr[5][3].initState(value:0, color: 1)

            arr[5][2].initState(value:0, color: 2)

            arr[5][1].initState(value:3, color: 2)

            arr[6][2].initState(value:7, color: 3)

            arr[6][3].initState(value:0, color: 1)

第三关

        case 3:

            view.backgroundColor = #colorLiteral(red: 0.47, green: 0.76, blue: 0.27,alpha: 1)

            for row in 1..<11{

                for col in 0..<6{

                    arr[row-1][col].initState(value:0, color: 2)

                }

            }

            arr[1][1].initState(value:2, color: 2)

            arr[1][2].initState(value:0, color: 3)

            arr[1][3].initState(value:0, color: 3)

            arr[1][4].initState(value:2, color: 2)

            arr[2][2].initState(value:5, color: 3)

            arr[2][3].initState(value:5, color: 3)

            arr[3][1].initState(value:2, color: 1)

            arr[3][3].initState(value:0, color: 1)

            arr[3][2].initState(value:0, color: 1)

            arr[3][4].initState(value:2, color: 1)

            arr[4][2].initState(value:3, color: 2)

            arr[4][3].initState(value:3, color: 2)

            arr[5][1].initState(value:4, color: 2)

            arr[5][2].initState(value:0, color: 3)

            arr[6][1].initState(value:0, color: 1)

            arr[5][3].initState(value:0, color: 3)

            arr[6][2].initState(value:0, color: 3)

            arr[5][4].initState(value:4, color: 2)

            arr[6][2].initState(value:0, color: 3)

            arr[6][3].initState(value:0, color: 3)

            arr[6][4].initState(value:0, color: 1)

第四关

        case 4:

            for col in 0..<6{

                var row =2

                arr[row][col].initState(value:0, color:2)

                row = 9

                arr[row][col].initState(value:0, color:2)

            }

            for col in 0..<6{

                for row in 3...7{

                    arr[row][col].initState(value:0, color: col%2==01 : 2)

                }

            }

            for col in 1...5 {

                if (col+1)%2==0{

                    var row =5

                    arr[row][col].value =4

                    row = 7

                    arr[row][col].initState(value:4, color:1)

                }

            }

            for rowin0...8{

                if row ==0{

                    for colin0...5{

                        arr[0][col].initState(value: col%2==0 ? 4 : 7, color: col%2==0?2 :3)

                    }

                }else if row ==1{

                    for colin0...5{

                        arr[1][col].initState(value: col%2==0 ? 0 : 2, color: col%2==0?3 :1)

                    }

                }else if row ==8{

                    for colin0...5{

                        arr[8][col].initState(value: col%2==0 ? 6 : 8, color: col%2==0?3 :2)

                    }

                }

            }

第五关

        case 5:

            view.backgroundColor = #colorLiteral(red: 0.94, green: 0.35, blue: 0.2,alpha: 1)

            for row in 1..<11{

               

                for col in 0..<6{

                    if row !=7{

                        arr[row-1][col].initState(value:0, color: 1)

                    }else {

                        arr[row-1][col].initState(value:0, color: 2)

                    }

                }

            }

            arr[2][0].initState(value:14, color: 2)

            arr[2][5].initState(value:14, color: 2)

            arr[3][0].value = 6

            arr[3][5].value = 6

            arr[3][2].initState(value:5, color: 3)

            arr[3][3].initState(value:5, color: 3)

            arr[4][2].value = 5

            arr[4][3].value = 5

            arr[5][0].initState(value:8, color: 1)

            arr[5][5].initState(value:8, color: 1)

            arr[6][0].initState(value:7, color: 3)

            arr[6][5].initState(value:7, color: 3)

            arr[6][1].color = 2

            arr[6][4].color = 2

            arr[7][0].color = 2

            arr[7][5].color = 2

        default:

            break

        }

    }

    

}

现在都初始化好了,可以写手势了:

在这之前,先想想 如果用户画了最后一块,游戏会自动跳到下一关,所以先写一个方法判断是否赢了:

func hasWon() -> Bool{

        let probe = arr[5][3].color

//这里为了提高效率,我随便找了中间一个小格颜色作为参照。然后遍历找不同

        for row in 0..<10{

            for col in 0..<6{

                if probe != arr[row][col].color {

                    return false

                }

            }

        }

        return true

    }

四方法:

 func upCommand(_ swiper:UISwipeGestureRecognizer){

//这句非常重要,就是取出是谁触发的事件:

        let unit =view.viewWithTag((swiper.view?.tag)!)as!Unit


//得到位置:

        let (row,col) = unit.getPosition()


  //向上滑动时候肯定row != 0,值不是0,上面的值不是0.如果上面值不是0,就画不动       

        if row==0||unit.value==0 {   return   }


        let temp =arr[row-1][col]

        if temp.value !=0 {return }


        //下面判断是哪个颜色在画,分别响应,代码都一样的==

        if unit.color==3 {

            if temp.color==1 {

                temp.initState(value: unit.value-1, color:3)

                unit.initState(value:0, color:3)

            }

        }else if unit.color==1{

            if temp.color==2 {

                temp.initState(value: unit.value-1, color:1)

                unit.initState(value:0, color:1)

            }

        }else if temp.color==3 {

            temp.initState(value: unit.value-1, color:2)

            unit.initState(value:0, color:2)

        }

//如果赢了,下一关

        if hasWon(){

            skip()

        }

    }

//现在可以去补充skip方法了:

    func skip(){

//别忘了,如果正在玩第五关,下一关没了,需要弹窗提示,关于弹窗很简单就不讲了,看看吧:

        if currentRank ==5 {

            let alerView =UIAlertController(title:"Congratulations", message:"You Have Passed All Levels.Once Again? ", preferredStyle: .alert)

            let action1 =UIAlertAction(title:"OK", style: .cancel, handler: {(a:UIAlertAction)inself.setUpGame(rank:1)})

            let action2 =UIAlertAction(title:"No", style: .default, handler: {(a:UIAlertAction)inself.present(ViewController(),animated:false, completion:nil)})

            alerView.addAction(action1)

            alerView.addAction(action2)

            present(alerView, animated:true, completion:nil)

        }else{

    //不是第五关:下一关

            setUpGame(rank:currentRank+1)

        }

    }

下:

    func downCommand(_ swiper:UISwipeGestureRecognizer){

        let unit =view.viewWithTag((swiper.view?.tag)!)as!Unit

        let (row,col) = unit.getPosition()

        

        if row==9||unit.value==0 {   return   }

        let temp =arr[row+1][col]

        if temp.value !=0 {return }

        

        if unit.color==3 {

            if temp.color==1 {

                temp.initState(value: unit.value-1, color:3)

                unit.initState(value:0, color:3)

            }

        }else if unit.color==1{

            if temp.color==2 {

                temp.initState(value: unit.value-1, color:1)

                unit.initState(value:0, color:1)

            }

        }else if temp.color==3 {

            temp.initState(value: unit.value-1, color:2)

            unit.initState(value:0, color:2)

        }

        if hasWon() {

            skip()

        }

    }

    func leftCommand(_ swiper:UISwipeGestureRecognizer){

        let unit =view.viewWithTag((swiper.view?.tag)!)as!Unit

        let (row,col) = unit.getPosition()

        

        if col==0||unit.value==0 {   return   }

        let temp =arr[row][col-1]

        if temp.value !=0 {return }

        

        if unit.color==3 {

            if temp.color==1 {

                temp.initState(value: unit.value-1, color:3)

                unit.initState(value:0, color:3)

            }

        }else if unit.color==1{

            if temp.color==2 {

                temp.initState(value: unit.value-1, color:1)

                unit.initState(value:0, color:1)

            }

        }else if temp.color==3 {

            temp.initState(value: unit.value-1, color:2)

            unit.initState(value:0, color:2)

        }

        if hasWon() {

            skip()

        }

    }

    func rightCommand(_ swiper:UISwipeGestureRecognizer){

        let unit =view.viewWithTag((swiper.view?.tag)!)as!Unit

        let (row,col) = unit.getPosition()

        

        if col==5||unit.value==0 {   return   }

        let temp =arr[row][col+1]

        if temp.value !=0 {return }

        

        if unit.color==3 {

            if temp.color==1 {

                temp.initState(value: unit.value-1, color:3)

                unit.initState(value:0, color:3)

            }

        }else if unit.color==1{

            if temp.color==2 {

                temp.initState(value: unit.value-1, color:1)

                unit.initState(value:0, color:1)

            }

        }else if temp.color==3 {

            temp.initState(value: unit.value-1, color:2)

            unit.initState(value:0, color:2)

        }

        if hasWon() {

            skip()

        }

    }

   //好了,现在再补充一下

  func reset(){

        setUpGame(rank:currentRank)

    }

    开始游戏吧!如果报错,自己排一排,由于写本文时间紧迫,难免疏漏一些地方


    玩完会发现:1.不能连续滑动

2.有值的块没有图标

    有能力的同学自己实现这两个功能,留个悬念嘿嘿~



0 0
原创粉丝点击