目录

使用Grid布局制作拼图小游戏

目录

使用Grid布局制作拼图小游戏

在学习grid布局时突发奇想利用这个布局的特性做一个拼图小游戏

先简单实现了一个demo,后期再优化,效果如下图:

https://i-blog.csdnimg.cn/blog_migrate/3637c72d9cb152f6871b92a68fd1e3da.gif

先上一下主要的css样式

.container {
        display: inline-grid;
        grid-template-columns: repeat(3, 100px);
        grid-template-rows: repeat(3, 100px);
        grid-gap: 1px 1px;
        grid-template-areas:
            'a b c'
            'd e f'
            'g h i';
        place-items: center center;
        place-content: center center;
    }

    .container>div {
        width: 100px;
        height: 100px;
        text-align: center;
        padding: 50px 0;
        box-sizing: border-box;
        counter-increment: section1;
        background-image: url(../images/nkss2.png);
        background-size: 300% 300%;
    }

方块的切换是利用的grid布局的grid-area切换实现,简单快捷,至于确定,就是grid-area不支持动画属性,所以没法实现漂亮的滑动效果,主要JS如下:

var AlphaBeta = "abcdefghi";
    var divs = document.getElementById("content").children;
    var emptyNode = divs[8];
    var emptyFlag = 'i';
    var IsGameOver = false;
    var startTime = new Date();
    for (var i = 0; i < divs.length; i++) {
        divs[i].style["grid-area"] = AlphaBeta[i];
        divs[i].style["background-position"] = -1 * (i % 3) * 100 + "% " + -1 * Math.floor(i / 3) * 100 + "%";
        divs[i].addEventListener("click", function(event) {
            if (getMovePos(emptyFlag).indexOf(this.style.gridRowStart) > -1) {
                emptyNode.style["grid-area"] = this.style["grid-area"];
                this.style["grid-area"] = emptyFlag;
                emptyFlag = emptyNode.style.gridRowStart;
                if (checkFinished()) {
                    IsGameOver = true;
                    successAnimation();
                }
            }

        })
    }

另外还有初始时的打乱方法:

// 打乱方法
    function randomLayut(step) {
        var pos, ran, node, preNodeFlag;
        while (step > 0) {
            pos = getMovePos(emptyFlag);
            ran = Math.floor((Math.random() * pos.length));
            while (pos[ran] == undefined || pos[ran] == preNodeFlag) {
                ran = Math.floor((Math.random() * pos.length));
            }
            console.log(pos[ran]);
            node = [...divs].filter(function(item) {
                return item.style.gridRowStart == pos[ran];
            })
            emptyNode.style["grid-area"] = node[0].style["grid-area"];
            node[0].style["grid-area"] = emptyFlag;
            preNodeFlag = emptyFlag;
            emptyFlag = emptyNode.style.gridRowStart;

            step--;
        }
    }

获取可移动位置的方法:

// 计算可移动的方块位置
    function getMovePos(empty) {
        var pos = AlphaBeta.indexOf(empty);
        if (pos % 3 == 0) {
            return [AlphaBeta[pos + 1],AlphaBeta[pos + 3],undefined,AlphaBeta[pos - 3]];
        } else if (pos % 3 == 1) {
            return [AlphaBeta[pos + 1],AlphaBeta[pos + 3],  AlphaBeta[pos - 1], AlphaBeta[pos - 3]];
        } else {
            return [undefined, AlphaBeta[pos + 3], AlphaBeta[pos - 1], AlphaBeta[pos - 3]];
        }
    }

以及使用键盘移动的监听方法:

document.onkeydown = function(e){
        if(IsGameOver)return;
        var code = e.keyCode || e.which, 
            pos = getMovePos(emptyFlag),
            node;
        if (pos[code-37] != undefined) {
                node = [...divs].filter(function(item) {
                        return item.style.gridRowStart == pos[code-37];
                    })
                emptyNode.style["grid-area"] = node[0].style["grid-area"];
                node[0].style["grid-area"] = emptyFlag;
                emptyFlag = emptyNode.style.gridRowStart;
                if (checkFinished()) {
                    IsGameOver = true;
                    successAnimation();
                }
            }
    }

完整代码持续更新地址: