【JavaScript】拼圖小遊戲

效果預覽:https://sevlt.github.io/puzzle-game/index.html

Html 代碼:

<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="./style.css" />
        <title>Puzzle Game</title>
    </head>
    <body>
        <div class="wrapper">
            <div class="start">開始</div>
            <div class="content"></div>
        </div>
        <script src="./jquery.js"></script>
        <script src="./main.js"></script>
    </body>
</html>

CSS 代碼:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body{
    background-color: #F5FFFA;
}
.wrapper {
    /* border: 1px solid red; */
    width: 500px;
    height: 500px;
    margin: 10px auto;
    position: relative;
    display: flex;
    justify-content: center;
}
.start {
    border: 1px solid #ebebeb;
    border-radius: 5px;
    width: 80px;
    height: 40px;
    background-color: #fff8dc;
    text-align: center;
    line-height: 40px;
    position: absolute;
    bottom: 70px;
    cursor: pointer;
}
.content {
    position: absolute;
    width: 300px;
    height: 300px;
    top: 50px;
}
.content .box {
    float: left;
    position: absolute;
    border-radius: 4px;
    box-shadow: 0 0 8px #fff;
}
.content .hover {
    opacity: 0.7;
    border: 1px solid #8E8E8E;
    box-shadow: 0 0 5px #8E8E8E;
}

JavaScript 代碼:

var btn = $('.start')
var content = $('.content')
var boxBefore = []
var boxAfter = []
var boxes
var states = true

init()
go()

function init() {
    content.html('') //清空子內容
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            boxBefore.push(i * 3 + j) //原數組順序爲0-9
            var box = $('<div></div>') //常見九個格子
            $(box).attr('class', 'box')
            $(box).css({
                width: '100px',
                height: '100px',
                'background-image': 'url(./mountain.png)',
                top: i * 100 + 'px',
                left: j * 100 + 'px',
                //注意第一個px後面有一個空格
                'background-position': -j * 100 + 'px ' + -i * 100 + 'px',
            })
            content.append(box)
        }
    }
    boxes = $('.box')
}
//亂序數組函數
function mixArry() {
    //sort()會改變原數組順序,這裏創建一個臨時數組
    var boxTemp = boxBefore.slice(0)
    boxAfter = boxTemp.sort(() => {
        return Math.random() - 0.5
    })
}
//根據數組順序擺放元素函數
function dropArry(arr) {
    for (var i = 0; i < arr.length; i++) {
        $(boxes[i]).animate(
            {
                top: Math.floor(arr[i] / 3) * 100 + 'px',
                left: (arr[i] % 3) * 100 + 'px',
            },
            400
        )
    }
}
function go() {
    btn.on('click', function () {
        if (states) {
            $('.start').text('復原')
            states = false
            mixArry()
            dropArry(boxAfter)
            boxes
                .css({ cursor: 'pointer' })
                .on('mouseover', function () {
                    $(this).addClass('hover')
                })
                .on('mouseleave', function () {
                    $(this).removeClass('hover')
                })
                .on('mousedown', function (e) {
                    $(this).css({
                        cursor: 'move',
                    })
                    var index1 = $(this).index()
                    var boxY = e.pageY - boxes.eq(index1).offset().top
                    var boxX = e.pageX - boxes.eq(index1).offset().left
                    $(document)
                        .on('mousemove', function (e1) {
                            boxes.eq(index1).css({
                                'z-index': 20,
                                top: e1.pageY - boxY - content.offset().top + 'px',
                                left: e1.pageX - boxX - content.offset().left + 'px',
                            })
                        })
                        .on('mouseup', function (e2) {
                            var index2 = getIndex(
                                e2.pageY - content.offset().top,
                                e2.pageX - content.offset().left,
                                index1
                            )
                            if (index1 == index2) {
                                dropArry(boxAfter)
                                boxes.eq(index1).css({ 'z-index': 10 })
                            } else {
                                changeArry(index1, index2)
                            }
                            $(document).off('mousemove').off('mouseup')
                        })
                })
                .on('mouseup', function () {
                    $(this).css({
                        cursor: 'pointer',
                    })
                })
        } else {
            $('.start').text('開始')
            states = true
            dropArry(boxBefore)
            //移除鼠標事件,使用戶未點擊開始鼠標經過圖片無任何響應
            boxes.css({ cursor: 'default' }).off('mouseup').off('mousedown').off('mouseover')
        }
    })
}
function getIndex(y, x, index) {
    if (x < 0 || x > 300 || y < 0 || y > 300) {
        return index
    } else {
        var row = Math.floor(y / 100)
        var col = Math.floor(x / 100)
        var location = row * 3 + col
        //與cellOrder()關聯,location號位在亂序數組
        //中的下標n即爲該位置圖片的序號(順序序號)
        return boxAfter.indexOf(location)
    }
}
function changeArry(index1, index2) {
    boxes.eq(index1).animate(
        {
            top: Math.floor(boxAfter[index2] / 3) * 100 + 'px',
            left: (boxAfter[index2] % 3) * 100 + 'px',
        },
        400,
        function () {
            $(this).css({ 'z-index': 10 })
        }
    )
    boxes.eq(index2).animate(
        {
            top: Math.floor(boxAfter[index1] / 3) * 100 + 'px',
            left: (boxAfter[index1] % 3) * 100 + 'px',
        },
        400,
        function () {
            $(this).css({ 'z-index': 10 })
            //亂序數組交換後還是與順序數組是否一致
            var temp = boxAfter[index1]
            boxAfter[index1] = boxAfter[index2]
            boxAfter[index2] = temp
            //對象相等無法直接比較,因此通過自定義函數比較
            if (isEqual(boxAfter, boxBefore)) {
                success()
            }
        }
    )
}
function isEqual(arry1, arry2) {
    var str1 = arry1.join(',')
    var str2 = arry2.join(',')
    if (str1 === str2) {
        return true
    } else {
        return false
    }
}
function success() {
    boxes.css({ cursor: 'default' }).off('mouseup').off('mousedown').off('mouseover')
    btn.text('開始')
    states = true
    alert('成功!')
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章