swift 实战项目之 2048游戏
之前看过网上很多写小项目的文章,但大多是旧版或者不全的,这里推出swift5 项目之2048给大家分享
【2020年更新,建议直接看源码:源码地址】
本文将要使用的思路和上面2020更新的源码思路不一样,本文的思路清晰但是代码复杂。
1.首先新建一个项目,自动生成我们的viewController,添加如下代码,构造最简单的起始页面:
class ViewController:UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
let wid =view.bounds.width
let hei =view.bounds.height
// 想点button跳转入游戏界面,因此
let startButton1 =UIButton(frame:CGRect(x:0, y:hei/3, width: wid, height:20))
startButton1.setTitleColor(UIColor.red, for: .normal)
startButton1.setTitle("2048",for: .normal)
//文字居中
startButton1.contentHorizontalAlignment = .center
startButton1.addTarget(self,action:#selector(start1),for: .touchUpInside)
view.addSubview(startButton1)
}
// 点击事件:需要新建一个swift文件:GamePanel.swift ,继承UIViewController。点击按钮后就进这个ViewController界面。
func start1(){
self.present( GamePanel(), animated: false, completion: nil)
}
GamePanel.swift:
import Foundation
import UIKit
class GamePanel:UIViewController{
let dimension:Int =4 // 四行四列,等项目做完,试试自定义行列数。
let boardwidth:CGFloat! // 游戏区域宽度
let scorewidth:CGFloat=50 // 记分板垂直方向的宽度
let thinPadding:CGFloat=5 // 最小滑块的间距
var unit:CGFloat! // 最小滑块的边长
var x:CGFloat! // 包容小方块的大正方形的位置 x,y,也就是游戏区域
var y:CGFloat!
说到这,我们有大正方形,有最小滑块,有记分板,那就得先新建三个类:
1、新建: GameView.swift,是大正方形,里面包着16个小正方形
然后:
var game:GameView!
2、新建: ScoreView.swift,是记分板,显示分数
然后:
var scoreBoard:ScoreView!
3、一会再说,大正方形还没写呢,何谈小块?
构造方法
init( ) {
boardwidth = 400 // 设成多宽随意
super.init(nibName: nil, bundle: nil) // 这句没意思 可照抄
}
override func viewDidLoad() {
super.viewDidLoad()
准备好游戏区域大正方形的位置 x,y,为了居中,下面是简单的计算
x = (view.bounds.width-boardwidth)/2
y = (view.bounds.height-boardwidth+scorewidth)/2
self.view.backgroundColor =UIColor(red:0.95, green:0.83, blue:1, alpha:1)
展示大正方形和积分板的俩方法:
showGridView()
showScoreBoard()
}
requiredinit?(coderaDecoder:NSCoder) {
fatalError("init(coder:) has not beenimplemented")
}
GamePanel是负责控制游戏的(Controller),其他view要单设类重写
这两个方法可以在写完那两个类的构造方法再来写,现在先写个方法头扔这就行
1 展示大正方形:
func showGridView(){
unit = (boardwidth-thinPadding*CGFloat(dimension+1))/CGFloat(dimension)
game =GameView(unit:unit,dime:dimension,x:x,y:y,thin:thinPadding) //一会写
view.addSubview(game)
}
2 展示记分板,
func showScoreBoard(){
scoreBoard =ScoreView(unit:unit,y:y,screenX:view.bounds.width) //一会写
scoreBoard.score =0
view.addSubview(scoreBoard)
}
}
大方块GameView.swift:
import Foundation
import UIKit
class GameView:UIView {
var dimension:Int!
var unitwidth:CGFloat!
var thinPadding:CGFloat!
var x:CGFloat!
var y:CGFloat! // 这几个属性看之前注释 一样的意思
构造方法
init(unit:CGFloat,dime:Int,x:CGFloat,y:CGFloat,thin:CGFloat){
self.x= x
self.y= y
self.thinPadding= thin
self.dimension= dime
self.unitwidth= unit
let wid = thinPadding!*CGFloat(dime+1)+unit*CGFloat(dime)
确定frame位置:
super.init(frame:CGRect(x:x, y: y, width: wid, height: wid))
调用下面的方法初始化小单元方格 :
setGrid()
}
required init?(coderaDecoder: NSCoder) {
fatalError("init(coder:) has not beenimplemented")
}
//初始化空的小单元们 PS。这只是初始化单元的位置,不是最小块。
func setGrid(){
layer.cornerRadius =10
clipsToBounds = true
backgroundColor =UIColor(red: 0.73, green: 1, blue: 0.85, alpha: 1)
两个for循环初始化位置:
var tempy:CGFloat= 0
for _ in 0..<dimension{
var tempx:CGFloat =0
for _ in 0..<dimension{
let viewUnit=UIView(frame:CGRect(x:thinPadding+tempx, y:thinPadding+tempy, width:unitwidth,height: unitwidth))
viewUnit.layer.cornerRadius =8
viewUnit.clipsToBounds =true
viewUnit.backgroundColor=UIColor(red: 0.9, green: 1, blue: 0.97, alpha: 1)
addSubview(viewUnit)
tempx += unitwidth+thinPadding
}
tempy += unitwidth+thinPadding
}
}
下面是记分板类ScoreView.swift 继承 UILabel 。你也可以继承UIView。我为了省事就这样了。。
import Foundation
import UIKit
class ScoreView:UILabel{
属性观察者 传score值
var score:Int =0{
didSet{
text ="SCORE:\(score)"
}
}
初始化
init(unit:CGFloat,y:CGFloat,screenX:CGFloat){
let height:CGFloat=68 // 随便
let width =2.5*unit // 自己定
根据屏幕和游戏区位置确定记分板位置:
let localX = (screenX-width)/2
let localY = (y-height)/2
super.init(frame:CGRect(x: localX, y: localY, width: width,height: height))
backgroundColor =UIColor(red: 0.47, green: 0.84, blue: 0.97, alpha: 1)
textColor = UIColor.red
textAlignment = .center
}
required init?(coderaDecoder: NSCoder) {
fatalError("init(coder:) has not beenimplemented")
}
}
写完排排错 运行看看什么样子