这次开始进行2048小游戏最后的步骤,方块滑动时碰到相同块后合并成更大的数字块。
1. 数据结构修改
修改了下之前代码的数据结构,直接用一个UILabel数组来存放4*4的grid,显示在页面上的数字块加入到view中,初始和合并后不显示的方块从view中移除并重置,这样操作起来更好理解。
func initGridArr() {
for i in 0..<DIM*DIM {
// 背景空白label
gridArr[i] = getEmptyGrid(index : i)
self.addSubview(gridArr[i])
// 数字块的不加入到view中
digitArr.append(getEmptyGrid(index: i))
}
}
func isEmpty(index : Int) -> Bool {
return digitArr[index].text == ""
}
2. 方块移动及合并
数字快移动和合并的代码可以用一个公共的方法去实现,传入from位置及to位置即可。判断如果to位置有数字且和from的不同,则直接返回;如果有数字且不同,则合并后移动,同时从View中移除to;如果无数字则直接移动。最后交换两个方块的位置。
// 移动动画
func move(fromIndex : Int, toIndex: Int) {
let from = digitArr[fromIndex]
let to = digitArr[toIndex] //该label是不显示的
//结束位置有方块且数字不同则什么都不做
if(to.text != "" && to.text != from.text) {
return
}
//结束位置数字相同合并后移动;空白直接移动
if(to.text != "") {
to.text = ""
to.removeFromSuperview() //合并的块要移除旧的
to.backgroundColor = UIColor.white
from.text = String(2*Int(from.text!)!)
from.backgroundColor = getBgColor(text: from.text)
}
let fromX = from.center.x
let fromY = from.center.y
from.center.x = to.center.x
from.center.y = to.center.y
to.center.x = fromX
to.center.y = fromY
// 交换移动的两个grid
digitArr[toIndex] = from
digitArr[fromIndex] = to
}
3. 向上及向下滑动
对于移动的逻辑,没想到很好的办法。就是遍历每个有数字的方块,一次移动一格,调用move方法,直到不再数组范围。对于向上和向下移动,就是位置加或减4来判断。
// 向上移动
func moveUp() {
for i in 0 ..< DIM*DIM {
if(!isEmpty(index: i) && i > 3) {
// 向上移动一格直到到底
var tmp = i-4;
while(tmp >= 0) {
move(fromIndex: tmp+4, toIndex: tmp)
tmp = tmp - 4
}
}
}
}
//向下移动
func moveDown() {
for i in (0...DIM*DIM-1).reversed() {
if(!isEmpty(index: i) && i < 12) {
// 向上移动一格直到到底
var tmp = i+4;
while(tmp <= 15) {
move(fromIndex: tmp-4, toIndex: tmp)
tmp = tmp + 4
}
}
}
}
4. 动画的优化
由于动画是异步的,修改修改动画的逻辑,加入动画结束的逻辑,在动画结束后再加入新的数字,不然可能会混乱。同时也加入一个判断动画是否结束的标志,避免上一个动画没结束,滑动手势又开始了。
{
if(!moveFinish) {
NSLog("动画正在执行...")
return
}
moveFinish = false
UIView.animate(withDuration: 0.1, animations: {
if(direction == "up") {
self.moveUp()
} else if(direction == "down") {
self.moveDown()
}
}, completion: { _ in
// 动画完成之后调用,不然数据改变会影响动画函数的执行
self.insertRandUnit()
self.moveFinish = true
})
NSLog("动画正在异步执行,但动画后面代码已经开始执行了")
}
5. 下一步计划
现在向上和向下滑动已经能正常玩了,下一次增加向左和向右的滑动和积分就基本完成了。
往期文章
swift实现2048小游戏其它文章入口在下面,感兴趣的朋友可以进去看看,有问题可以给我留言哦,大家相互进步。