【QML】分享一个纯QML实现的2048小游戏

随着QT6的问世,UI设计+Qt代码联动的设计方式在Qt Creator中已经变成了不可用状态(虽然可以手动打开),官方开始推广用QML来进行界面设计,当时蠢蠢欲动做了一个小游戏,忽然想起来分享一下,代码开源在本人github上,欢迎拉取

一、Git开源地址:https://github.com/xutengteng/2048

【QML】分享一个纯QML实现的2048小游戏_第1张图片

二、代码说明

主要逻辑都在几个qml文件中
【QML】分享一个纯QML实现的2048小游戏_第2张图片

三、主要逻辑说明

本游戏主要逻辑没有参考网上,是按照我自己的想法写的,不知道有没有更优解,主要是方块的合并算法和随机方块的生成算法,一下罗列一下主要逻辑,详细代码还需参考git

1.合并算法我主要分四步(三个模块):

  • 缩进
  • 矩阵变换
  • 合并
  • 最后再缩进

缩进主要作用是让方块每行都处于两两相邻状态,方便比较,合并后会产生空挡,所以要再缩进一次

    /*************************缩进***********************/
    function move_retract(){
        var i=0

        for(i;i<4;i++){
            if(item.itemArray[0+i*4] === 0){
                item.itemArray[0+i*4] = item.itemArray[1+i*4]
                item.itemArray[1+i*4] = item.itemArray[2+i*4]
                item.itemArray[2+i*4] = item.itemArray[3+i*4]
                item.itemArray[3+i*4] = 0
            }
            if(item.itemArray[1+i*4] === 0){
                item.itemArray[1+i*4] = item.itemArray[2+i*4]
                item.itemArray[2+i*4] = item.itemArray[3+i*4]
                item.itemArray[3+i*4] = 0
            }
            if(item.itemArray[2+i*4] === 0){
                item.itemArray[2+i*4] = item.itemArray[3+i*4]
                item.itemArray[3+i*4] = 0
            }
        }
    }

矩阵变换是为了应对四个方向的滑动,通过把格子下标进行左右翻转和对角线翻转,任意方向的滑动都可当作左划,代码量骤减

 function r_2_l(){//左右互换下标
        var i=0
        var dt0,dt1,dt2,dt3
        for(i;i<4;i++){
            dt0 = item.itemArray[0+i*4]
            dt1 = item.itemArray[1+i*4]
            dt2 = item.itemArray[2+i*4]
            dt3 = item.itemArray[3+i*4]
            item.itemArray[0+i*4] = dt3
            item.itemArray[1+i*4] = dt2
            item.itemArray[2+i*4] = dt1
            item.itemArray[3+i*4] = dt0
        }
    }
    function u_2_l(){//对角线互换下标
        var i=0
        var dt1,dt2,dt3,dt6,dt7,dt11
        dt1 = item.itemArray[1]
        dt2 = item.itemArray[2]
        dt3 = item.itemArray[3]
        dt6 = item.itemArray[6]
        dt7 = item.itemArray[7]
        dt11 = item.itemArray[11]
        item.itemArray[1] = item.itemArray[4]
        item.itemArray[2] = item.itemArray[8]
        item.itemArray[3] = item.itemArray[12]
        item.itemArray[6] = item.itemArray[9]
        item.itemArray[7] = item.itemArray[13]
        item.itemArray[11]= item.itemArray[14]
        item.itemArray[4] = dt1
        item.itemArray[8] = dt2
        item.itemArray[12]= dt3
        item.itemArray[9] = dt6
        item.itemArray[13]= dt7
        item.itemArray[14]= dt11
    }
    function d_2_l(mode){
        if(mode === "end"){//先左右,再对角线
            r_2_l()
            u_2_l()
        }
        if(mode === "start"){//先对角线,再左右
            u_2_l()
            r_2_l()
        }
    }

基于以上两个算法,合并时只考虑一个方向上一行中两两相邻方块就可以了

    /***************************合并***********************/
    function add(){
        var i=0
        for(i;i<4;i++)
        {
            move_retract()
            if(item.itemArray[0+i*4]===item.itemArray[1+i*4]){//1=2
                item.itemArray[0+i*4] = 2*item.itemArray[0+i*4]
                score += item.itemArray[0+i*4]
                item.itemArray[1+i*4] = 0
                if(item.itemArray[2+i*4]===item.itemArray[3+i*4]){//3=4
                    item.itemArray[1+i*4] = 2*item.itemArray[2+i*4]
                    score += item.itemArray[1+i*4]
                    item.itemArray[2+i*4] = 0
                    item.itemArray[3+i*4] = 0
                }
            }else if(item.itemArray[1+i*4]===item.itemArray[2+i*4]){//2=3
                item.itemArray[1+i*4] = 2*item.itemArray[1+i*4]
                score += item.itemArray[1+i*4]
                item.itemArray[2+i*4] = item.itemArray[3+i*4]
                item.itemArray[2+i*4] = 0
            }else if(item.itemArray[2+i*4]===item.itemArray[3+i*4]){//3=4
                item.itemArray[2+i*4] = 2*item.itemArray[2+i*4]
                score += item.itemArray[2+i*4]
                item.itemArray[3+i*4] = 0
            }else{
                score += 0
            }
            move_retract()

        }

    }

2.随机方块生成

    /******************在空闲位置随机产生方块******************/
    property var freeArray:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    property var rand_pos
    property var rand_num
    function random_rec(){
        var zero = 0
        for(var i=0;i<16;i++){//寻找空闲位
            if(item.itemArray[i] === 0){
                freeArray[zero] = i
                zero++
            }
        }
        if(zero !== 0){//仍有空位
            rand_pos = Math.floor(Math.random()*zero)
            console.log("rand_pos:",rand_pos+1)
            rand_num = Math.pow(2,Math.floor(Math.random()*2)+1)
            item.itemArray[freeArray[rand_pos]] = rand_num
            console.log("rand_num:",rand_num)
            freeArray={}
        }else//无空位,退出
        {
            console.error("game over")
            console.error(score)
            //提示分数,刷新纪录,重新开始
            max_number.text = score
            //fina.visible = true
        }
    }

这个写了没几个小时,细节没怎么扣,分数统计懒得写了,毕竟不是做项目,但重要逻辑已实现,仅作为QML学习

你可能感兴趣的:(C++/QT,QML,Qt6,2048,小游戏)