swift从零开始--2048游戏合并(向上向下)

这次开始进行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小游戏其它文章入口在下面,感兴趣的朋友可以进去看看,有问题可以给我留言哦,大家相互进步。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。