2048小游戏估计很多人都玩过,界面元素相对简单,试着编写下这个游戏,了解swift编程的各个方面,这次先编写游戏的主界面。
1. 页面布局
页面包含以下元素:
- 左上角一个2048标题
- 右上角一个积分块
-
下面包含一个大面板,大面板里面有4*4个小面板
嗯,差不多就这些,相对还算比较简单。做的比较粗糙,不过总算出来啦,最终效果图如下:
image.png
2. 主界面编写逻辑
- 首先得自定义一个整个界面的UIView MainScene,放在UIVIewController里。
- 在MainView中定义一个2048标题的UILabel及一个积分的UILabel以及4*4大面板的UIView
- 定义4*4大面板UIVIew GamePanel,里面定义16个UILabel BlockLabel存放在数组里。如果是空的,则设置text为空;非空,则设置text及背景色
3. 代码逻辑
- UIVIewController里很简单,就是加一个MainView。
class GameViewController: UIViewController {
var mainScene : MainScene!
override func viewDidLoad() {
super.viewDidLoad()
//设置mainSence的大小位置,铺满屏幕
mainScene = MainScene(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
view.addSubview(mainScene)
}
- MainSecene中定义界面上的各个组件,调用函数初始化。由于4*4的grid看起来复杂一点,单独定义了一个UIView(BoardPanel)去处理。
class MainScene : UIView {
var titleLabel : UILabel!
var socreLabel : UILabel!
var boardPanel : BoardPanel!
// define some paremeters
let SPACE :CGFloat = 8 // space betewwn each grid
let DIM = 4
var BLOCK_WID :CGFloat!
var titleWidth :CGFloat!
init(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) {
super.init(frame: CGRect(x: x, y: y, width: width, height: height))
// set background
self.backgroundColor = UIColor(red: 0.9, green: 0.8, blue: 1, alpha: 1)
initParameters()
initTitleLabel()
initScoreLabel()
initBoardPanel()
}
func initParameters() {
BLOCK_WID = (self.frame.width - 5*SPACE)/4
titleWidth = (self.frame.width - 3*SPACE)/2
}
// init title label in the up-left
func initTitleLabel() {
titleLabel = UILabel(frame: CGRect(x: SPACE, y: SPACE, width: titleWidth, height: BLOCK_WID))
titleLabel.textAlignment = .center
titleLabel.minimumScaleFactor = 0.5
titleLabel.font = UIFont(name: "HelveticaNeue-Bold", size: 24)
self.addSubview(titleLabel)
titleLabel.text = "2048"
titleLabel.backgroundColor = UIColor.yellow
}
// init score label
func initScoreLabel() {
socreLabel = UILabel(frame: CGRect(x: 2*SPACE + titleWidth, y: SPACE, width: titleWidth, height: BLOCK_WID))
socreLabel.textAlignment = .center
socreLabel.minimumScaleFactor = 0.5
socreLabel.font = UIFont(name: "HelveticaNeue-Bold", size: 16)
self.addSubview(socreLabel)
socreLabel.text = "0"
socreLabel.backgroundColor = UIColor(red: 0.5, green: 0.8, blue: 0.97, alpha: 1)
}
// init the 4*4 board panel which will includes 16 blocks
func initBoardPanel() {
let y = BLOCK_WID + 3*SPACE
boardPanel = BoardPanel(x: 0, y: y, width: self.frame.width, height: self.frame.width)
self.addSubview(boardPanel)
}
- BoardPanel里定义一个UILabel的数组,保存16个数字方格的定义,先初始化,在计算每个格子的位置,最后放到view中即可。
class BoardPanel : UIView {
let SPACE :CGFloat = 8 // space betewwn each grid
let DIM = 4
var BLOCK_WID :CGFloat!
let emptyLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
var gridArr : [UILabel]! // 定义grid块数组,每个是一个label
init(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) {
super.init(frame: CGRect(x: x, y: y, width: width, height: height))
self.backgroundColor = UIColor(red: 0.75, green: 1, blue: 0.85, alpha: 1)
BLOCK_WID = (self.frame.width - 5*SPACE)/4
// 数组先随便初始化一下, 不然运行会报错
gridArr = [UILabel](repeating: emptyLabel, count:16)
initGridArr()
initGrids()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func initGridArr() {
for i in 0..<DIM*DIM {
gridArr[i] = getEmptyGrid(index : i)
}
}
func getEmptyGrid(index: Int) ->UILabel {
NSLog(String(index))
// 根据grid位置下标计算坐标
let row = index / 4 //行,从0开始
let col = index % 4 //列,从0开始
let x = SPACE*CGFloat(col + 1) + BLOCK_WID * CGFloat(col)
let y = SPACE*CGFloat(row + 1) + BLOCK_WID * CGFloat(row)
let label = UILabel(frame: CGRect(x: x, y: y, width: BLOCK_WID, height: BLOCK_WID))
label.textAlignment = .center
label.minimumScaleFactor = 0.5
label.font = UIFont(name: "HelveticaNeue-Bold", size: 16)
label.text = ""
label.backgroundColor = UIColor.white
NSLog("return")
return label
}
func initGrids() {
for i in 0 ..< DIM*DIM {
self.addSubview(gridArr[i])
}
}
4. 下一步计划
先不管界面是否粗糙了,下一步实现滑动事件,可能后面代码会要优化下,目前只是堆了界面,没考虑后续的实现。继续加油。
网友评论