【swift3实战】2048 教程(二)

来源:互联网 发布:辛巴软件 编辑:程序博客网 时间:2024/05/25 02:31

这节我们要加入一个model,里面装的数据、逻辑 算法。

新建文件GameModel.swift

import UIKit

import Foundation

前面定义协议方便控制信息传递:

protocol GameModelProtocol :class {

//协议内容现在先不用知道干啥的 一会再说

    func changeScore(to score:Int)

    func moveOneUnit(from: (Int,Int), to: (Int,Int), value: Int)

    func moveTwoUnits(from: ((Int,Int), (Int,Int)), to: (Int,Int), value:Int)

    func insertUnit(at location:(Int,Int), withValue value:Int)


}

记录一个单元上有没有小块

enum UnitEnum {

    case empty

    case unit(Int)

}

自定义一个结构体,定义下标(学过swift二维数组实现吧?)作用: <记录每个数字块的信息,状态是空还是有值,值为几>  。现在也不用理解,一会用的时候会想

struct SequenceGameView<T> {


    var dimension :Int

    var unitArray:[T]


    init(dime d:Int,initValue:T) {

        dimension = d

        unitArray = [T](repeating:initValue,count: d*d)

它的内部有一个泛型数组保存着小块信息

    }


 subscript就是给结构体定义下标访问方式

    subscript(row :Int , col :Int) ->T {


        get{

            returnunitArray[dimension*row + col]

        }

        set{

            unitArray[dimension*row + col] = newValue

        }

    }

}


class GameModel :NSObject{


    let dimension :Int

    let delegate :GameModelProtocol

    //结构体用处:声明一个实例 gameView存放数字块信息

    var gameView :SequenceGameView<UnitEnum>


    var score :Int =0{

        didSet{

            delegate.changeScore(to:score)

我们通过协议来传值,所以上面协议里第一个方法 get ✅

        }

    }


//    初始化

    init(dimension :Int , delegate :GameModelProtocol) {

        self.dimension = dimension

        self.delegate = delegate


        gameView =SequenceGameView(dime: dimension , initValue: .empty)


        super.init()

    }

 

在GamePanel.swift里:实现GameModelProtocol:

classGamePanel:UIViewController,GameModelProtocol{


所以这里新增为:

var game:GameView!

var scoreBoard:ScoreView!

var gameModle:GameModel?


然后构造方法要加入:

gameModle = GameModel(dimension:dimension, delegate:self)


// 肯定要实现协议方法,这里先写空的占着,以后需要的时候再补上去(实际写代码时候这些方法都是需要的时候现加的,谁都不知道还会有什么方法==再加呗)

    func changeScore(to score:Int) {

        scoreBoard.score = score

    }

   

    func moveOneUnit(from: (Int,Int), to: (Int,Int), value: Int) {

       

    }

   

    func moveTwoUnits(from: ((Int,Int), (Int,Int)), to: (Int,Int), value:Int) {

       

    }

   

    func insertUnit(at location: (Int,Int),withValue value:Int) {

     

}

 

好  弄点细节       单元格上数字不同 则颜色不同,   这就需要写一个协议来 管理颜色


新建文件AppearanceProvider.swift  

这个类纯粹是辅助!!!!没意思!!!!看看粘贴上去就行!

import Foundation

import UIKit

提供颜色协议,具体细分到单元格颜色,数字颜色和字体:

protocol AppearanceProviderProtocol:class {


    func unitColor(_ value:Int)->UIColor

    func numberColor(_ value:Int)->UIColor

    func fontForNumbers() ->UIFont

}


class AppearanceProvider:AppearanceProviderProtocol{


1.字体:  

 func fontForNumbers() ->UIFont {


        if let font = UIFont(name: "HelveticaNeue-Bold", size: 20){

            return font

        }


        returnUIFont.systemFont(ofSize:20)

    }


2.数字颜色

    func numberColor(_ value:Int)->UIColor {


        if value==4||value==2{

            returnUIColor(red:0.4, green:110/255.0,blue:100/255.0, alpha:1.0)

        }


        returnUIColor.white

    }


3.单元格颜色:不同数字 switch

    func unitColor(_ value:Int)->UIColor {


        switch value {

        case 2:

            returnUIColor(red:238.0/255.0, green:228.0/255.0,blue:218.0/255.0, alpha:1.0)

        case 4:

            returnUIColor(red:237.0/255.0, green:224.0/255.0,blue:200.0/255.0, alpha:1.0)

        case 8:

            returnUIColor(red:242.0/255.0, green:177.0/255.0,blue:121.0/255.0, alpha:1.0)

        case 16:

            returnUIColor(red:245.0/255.0, green:149.0/255.0,blue:99.0/255.0, alpha:1.0)

        case 32:

            returnUIColor(red:246.0/255.0, green:124.0/255.0,blue:95.0/255.0, alpha:1.0)

        case 64:

            returnUIColor(red:246.0/255.0, green:94.0/255.0,blue:59.0/255.0, alpha:1.0)

        case 128, 256, 512,1024,2048:

            returnUIColor(red:237.0/255.0, green:207.0/255.0,blue:114.0/255.0, alpha:1.0)

        case 4096,8192:

            returnUIColor(red:0.99, green:0.2,blue:0.2, alpha:1.0)

        default:

            returnUIColor.white

        }

    }

}

颜色协议弄好啦

思考: 每个单元格上的颜色小块到底是怎么实现的? 改变某个位置的属性吗?因为涉及到移动,合并等行为,以及每个块上有自己的数字,颜色,写java的同学会情不自禁的新建一个类来管理:

新建文件UnitView.swift  是小单元格上贴的带数字的view

import Foundation

import UIKit

class UnitView:UIView{


   var label:UILabel!      / /  用来显示格子的值,以及根据 值的颜色协议 确定格子颜色:


   var value:Int =0{

        didSet{

            backgroundColor =delegate.unitColor(value)

            label.textColor =delegate.numberColor(value)

            label.text ="\(value)"

        }

    }


    let delegate:AppearanceProviderProtocol!


   初始化

    init(pos:CGPoint,wid:CGFloat,value:Int,delegated:AppearanceProviderProtocol) {


        delegate = d

        self.value = value


注意,任意view的frame是相对于superView的,因此:


     1. label相对于这个unitview的frame: 

        label =UILabel(frame:CGRect(x:0, y:0, width: wid, height: wid))

        label.textAlignment = .center

        label.minimumScaleFactor =0.5

        label.font =UIFont(name:"HelveticaNeue-Bold", size:15)


      2。这个unitview相对大正方形的frame:

        super.init(frame:CGRect(x: pos.x, y:pos.y, width: wid, height: wid))


        label.layer.cornerRadius =6

label.clipsToBounds = true

addSubview(label)


第一篇文章里两个for循环是初始化一个外观,这里UnitView类才是真正的单元格上的动态显示内容

        backgroundColor=delegate.unitColor(value)

        label.textColor =delegate.numberColor(value)

        label.text ="\(value)"


    }   

    requiredinit?(coder aDecoder:NSCoder) {

        fatalError("init(coder:) has not beenimplemented")

    }

} 

这里单元格的view弄好了,在GameView.swift里:

    var dimension:Int!

    var unitwidth:CGFloat!

    var thinPadding:CGFloat!

    var x:CGFloat!

    var y:CGFloat!


多出  存储小块的字典   其中IndexPath是小块对应的位置(x,y)

    var units:Dictionary<IndexPath,UnitView>


    let provider=AppearanceProvider()


然后在构造函数里添加:

      units = Dictionary()


UI部分基本结束了 下篇文章开始真正的操控方块



0 0