网页版空当接龙

已经一年没写前端代码了,手生得很,为了上班划水,三天写了个空当接龙游戏

兼容性

兼容现代浏览器

效果图

在这里插入图片描述

项目结构

free-cell
  css
    free-cell.css
  img
    存放图片素材(图片素材已上传至下载资源
  js
    free-cell.js
  free-cell.html

图片素材命名规则

num-color-type.png
num–数字(1 - 13)
color–颜色(1-红色 2-黑色)
type–类型(1–红心 2-黑桃 3-梅花 4-方块)

free-cell.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>空当接龙</title>
    <link rel="stylesheet" type="text/css" href="css/free-cell.css">
</head>
<body>
    <div class="container">
        <div class="menu"><span id="re-init" class="re-init">重新开始</span></div>
        <div class="top-panel">
            <div id="top-left-panel" class="top-left-panel">
                <div class="top-left-cell"><div class="top-cell" data-index="0"></div></div>
                <div class="top-left-cell"><div class="top-cell" data-index="1"></div></div>
                <div class="top-left-cell"><div class="top-cell" data-index="2"></div></div>
                <div class="top-left-cell"><div class="top-cell" data-index="3"></div></div>
            </div>
            <div id="top-right-panel" class="top-right-panel">
                <div class="top-right-cell"><div class="top-cell"></div></div>
                <div class="top-right-cell"><div class="top-cell"></div></div>
                <div class="top-right-cell"><div class="top-cell"></div></div>
                <div class="top-right-cell"><div class="top-cell"></div></div>
            </div>
            <div class="king-panel">
                <div class="king pri-king"></div>
                <div class="king sec-king"></div>
                <div class="king sec-king"></div>
                <div class="king pri-king"></div>
            </div>
        </div>
        <div class="splitter"></div>
        <div id="bottom-panel" class="bottom-panel">
            <div class="bottom-cell bottom-cell-1" data-index="0"></div>
            <div class="bottom-cell bottom-cell-2" data-index="1"></div>
            <div class="bottom-cell bottom-cell-3" data-index="2"></div>
            <div class="bottom-cell bottom-cell-4" data-index="3"></div>
            <div class="bottom-cell bottom-cell-5" data-index="4"></div>
            <div class="bottom-cell bottom-cell-6" data-index="5"></div>
            <div class="bottom-cell bottom-cell-7" data-index="6"></div>
            <div class="bottom-cell bottom-cell-8" data-index="7"></div>
        </div>
    </div>
</body>
<script type="text/javascript" src="js/free-cell.js"></script>
</html>

free-cell.css

.container {margin: auto;width: 1020px;height: 600px;background: #00AA00;overflow-x: hidden;overflow-y: scroll}
.menu {height: 30px;background: #D0CECC;position: relative;z-index: 4;padding-left: 8px;}
.re-init {line-height: 30px;font-size: 16px;cursor: pointer;
    -webkit-user-select: none;-ms-user-select: none;user-select: none;}
.top-panel {position: relative;height: 160px;}
.top-left-panel {position: absolute;top: 0;left: 10px;width: 450px;height: 160px;}
.top-left-cell {
    float: left;margin: 10px 0 0 10px;height: 140px;width: 100px;
    background: url("../img/back-face-top.png") no-repeat;background-size: 100% 100%;}
.top-right-panel {position: absolute;top: 0;right: 10px;width: 450px;height: 160px;}
.top-right-cell {float: right;margin: 10px 10px 0 0;height: 140px;width: 100px;
    background: url("../img/back-face-top.png") no-repeat;background-size: 100% 100%;}
.top-cell {position: relative;top: -26px;left: 0;height: 140px;width: 100px;}
.king-panel {position: absolute;width: 50px;height: 50px;top: 0;bottom: 0;left: 0;right: 0;margin: auto;}
.king {float: left;width: 50%;height: 50%;border: 1px outset #009900;opacity: 0.9;
    -webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
.pri-king {background: url("../img/pri-king.png") no-repeat center;background-size: cover;}
.sec-king {background: url("../img/sec-king.png") no-repeat center;background-size: cover;}
.splitter {margin: auto;width: 960px;height: 1px;background: #80d079;}
.bottom-panel {
    position: relative;margin: 10px auto 0 auto;width: 960px;height: 600px;}
.bottom-cell {
    position: absolute;top: 0;height: 140px;width: 100px;
    background: url("../img/back-face-bottom.png") no-repeat;background-size: 100% 100%;}
.bottom-cell > .cell-container {margin-top: -26px;}
.bottom-cell-1 {left: 10px;}
.bottom-cell-2 {left: 130px;}
.bottom-cell-3 {left: 250px;}
.bottom-cell-4 {left: 370px;}
.bottom-cell-8 {right: 10px;}
.bottom-cell-7 {right: 130px;}
.bottom-cell-6 {right: 250px;}
.bottom-cell-5 {right: 370px;}

.cell-container {position: absolute;top: 26px;left: 0;height: 140px;width: 100px;z-index: 0;}
.cell-body {
    position: absolute;top: 0;left: 0;height: 140px;width: 100px;
    -webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;
    border: 1px solid #D0CECC;border-radius: 4px;background-size: 100% 100%;
    background-repeat: no-repeat;z-index: 0;}

#cell-1 > .cell-body {background-image: url("../img/1-1-1.png");}
#cell-2 > .cell-body {background-image: url("../img/2-2-2.png");}
#cell-3 > .cell-body {background-image: url("../img/5-1-4.png");}
#cell-4 > .cell-body {background-image: url("../img/6-1-1.png");}
#cell-5 > .cell-body {background-image: url("../img/7-2-3.png");}
#cell-6 > .cell-body {background-image: url("../img/10-2-2.png");}
#cell-7 > .cell-body {background-image: url("../img/12-1-4.png");}
#cell-8 > .cell-body {background-image: url("../img/13-1-1.png");}

.layer {
    position: absolute;top: 26px;left: 0;height: 140px;width: 100px;z-index: 2;display: none;
    -webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;
    border: 2px solid #77cfd0;box-shadow:rgb(11, 234, 235) 0 0 12px inset;}

free-cell.js

(function () {
    function Cell(num, color, type) {
        this.num = num;
        this.color = color;
        this.type = type;
        this.dom = (function (window) {
            var cellContainer = window.document.createElement('div');
            cellContainer.className = 'cell-container';
            var cellBody = window.document.createElement('div');
            cellBody.className = 'cell-body';
            cellBody.setAttribute('data-num', num);
            cellBody.setAttribute('data-color', color);
            cellBody.setAttribute('data-type', type);
            cellBody.style.cssText = 'background-image: url("img/' + num + '-' + color + '-' + type + '.png");';
            cellContainer.appendChild(cellBody);
            return cellContainer;
        })(window);
    }

    var ver = 26;
    var param = {
        topLeftCells: [null, null, null, null],
        topRightCells: [[], [], [], []],
        bottomCells: [[], [], [], [], [], [], [], []]
    };
    var topLeftCellDoms = window.document.querySelectorAll('#top-left-panel .top-cell');
    var topRightCellDoms = window.document.querySelectorAll('#top-right-panel .top-cell');
    var bottomCellDoms = window.document.querySelectorAll('#bottom-panel .bottom-cell');
    var bottomPanel = window.document.querySelector('#bottom-panel');
    var topLeftPanel = window.document.querySelector('#top-left-panel');
    var reInitButton = window.document.querySelector('#re-init');

    var layer = (function (window) {
        var layer = window.document.createElement('div');
        layer.className = 'layer';
        return layer;
    })(window);

    reInitButton.addEventListener('click', (function () {
        var startTime = +new Date();
        return function (e) {
            var now = + new Date();
            if (now - startTime > 1500) {
                startTime = now;
                reInit();
            }
        }
    })());

    init();

    bottomPanel.addEventListener('dblclick', function (e) {
        e.preventDefault();
        var target = e.target;
        var parent = null;
        if (target.classList.contains('cell-body')) {
            parent = target.parentNode;
        } else if (target.classList.contains('cell-container')) {
            parent = target;
            target = parent.childNodes[0];
        }
        if (parent == null) {
            return;
        }
        var bottomIndex = getIndexInBottomCellsFirst(parent);
        if (bottomIndex < 0) {
            return;
        }
        var cell = param.bottomCells[bottomIndex][0];
        var topRightIndex = getIndexInTopRightCells(cell);
        if (topRightIndex >= 0) {
            param.bottomCells[bottomIndex].shift();
            param.topRightCells[topRightIndex].unshift(cell);
            topRightCellDoms[topRightIndex].appendChild(cell.dom);
            if (gameOverOrRun()) {
                autoMoveToTopRight();
            }
        } else {
            var topLeftIndex = getIndexInNullTopLeftCells();
            if (topLeftIndex < 0) {
                return;
            }
            param.bottomCells[bottomIndex].shift();
            param.topLeftCells[topLeftIndex] = cell;
            topLeftCellDoms[topLeftIndex].appendChild(cell.dom);
            if (gameOverOrRun()) {
                autoMoveToTopRight();
            }
        }
    });

    topLeftPanel.addEventListener('dblclick', function (e) {
        e.preventDefault();
        var target = e.target;
        var parent = null;
        if (target.classList.contains('cell-body')) {
            parent = target.parentNode;
        } else if (target.classList.contains('cell-container')) {
            parent = target;
            target = parent.childNodes[0];
        }
        if (parent == null) {
            return;
        }
        var topLeftIndex = getIndexInTopLeftCells(parent);
        if (topLeftIndex < 0) {
            return;
        }
        var cell = param.topLeftCells[topLeftIndex];
        var topRightIndex = getIndexInTopRightCells(cell);
        if (topRightIndex >= 0) {
            param.topLeftCells[topLeftIndex] = null;
            param.topRightCells[topRightIndex].unshift(cell);
            topRightCellDoms[topRightIndex].appendChild(cell.dom);
            autoMoveToTopRight();
        }
    });

    window.document.oncontextmenu = function (e) {
        return false;
    };

    dragEvent(topLeftPanel, (function () {
        var closest = null, selfTopLeftCell = null, selfTopLeftCellIndex = -1;
        var topLeftCells = param.topLeftCells;
        var topLeftCellDomList = topLeftCellDoms, topRightCellDomList = topRightCellDoms;
        var bottomCellDomsXY = null, topLeftCellDomsXY = null, topRightCellDomsXY = null;
        return function (parent, target, btnNum, phase, clientX, clientY, eX, eY, dx, dy) {
            if (btnNum === 0) {
                if (phase === 'down') {
                    closest = getClosest(parent, 'top-cell');
                    selfTopLeftCellIndex = closest.getAttribute('data-index') - 0;
                    selfTopLeftCell = topLeftCells[selfTopLeftCellIndex];
                    bottomCellDomsXY = getBottomCellDomsXY();
                    topLeftCellDomsXY = getTopLeftOrRightCellDomsXY(topLeftCellDomList);
                    topRightCellDomsXY = getTopLeftOrRightCellDomsXY(topRightCellDomList);
                } else if (phase === 'move') {
                    closest.style.zIndex = 3;
                    parent.style.left = dx + 'px';
                    parent.style.top = ver + dy + 'px';

                    var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
                    if (indexInTopLeftCells > -1) {
                        if (topLeftCells[indexInTopLeftCells] === null) {
                            showLayer(topLeftCellDoms[indexInTopLeftCells]);
                        } else {
                            hideLayer();
                        }
                    } else {
                        var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
                        if (indexInTopRightCells > -1) {
                            if (canDropTopLeftToTopRight(indexInTopRightCells, selfTopLeftCell)) {
                                showLayer(topRightCellDoms[indexInTopRightCells]);
                            } else {
                                hideLayer();
                            }
                        } else {
                            var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
                            if (indexInBottomCells > -1 && canDropToBottom(indexInBottomCells, selfTopLeftCell, 0)) {
                                showLayer(bottomCellDoms[indexInBottomCells], bottomCellDomsXY[indexInBottomCells].height);
                            } else {
                                hideLayer();
                            }
                        }
                    }
                } else {
                    hideLayer();
                    closest.style.zIndex = 0;
                    parent.style.left = 0 + 'px';
                    parent.style.top = ver + 'px';
                    target.style.zIndex = 0;

                    var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
                    if (indexInTopLeftCells > -1) {
                        if (topLeftCells[indexInTopLeftCells] === null) {
                            topLeft2TopLeft(selfTopLeftCellIndex, indexInTopLeftCells);
                        }
                    } else {
                        var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
                        if (indexInTopRightCells > -1) {
                            if (canDropTopLeftToTopRight(indexInTopRightCells, selfTopLeftCell)) {
                                topLeft2TopRight(selfTopLeftCellIndex, indexInTopRightCells);
                            }
                        } else {
                            var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
                            if (indexInBottomCells > -1 && canDropToBottom(indexInBottomCells, selfTopLeftCell, 0)) {
                                topLeft2Bottom(selfTopLeftCellIndex, indexInBottomCells);
                            }
                        }
                    }
                }
            }
        }
    })());

    dragEvent(bottomPanel, (function () {
        var closest = null, selfBottomCell = null, selfBottomCellIndex = -1, inBottomCellIndex = -1;
        var bottomCells = param.bottomCells, topLeftCells = param.topLeftCells;
        var topLeftCellDomList = topLeftCellDoms, topRightCellDomList = topRightCellDoms;
        var bottomCellDomsXY = null, topLeftCellDomsXY = null, topRightCellDomsXY = null;
        var canMove = false;
        return function (parent, target, btnNum, phase, clientX, clientY, eX, eY, dx, dy) {
            if (btnNum === 2) {
                if (phase === 'down') {
                    target.style.zIndex = 3;
                } else {
                    target.style.zIndex = 0;
                }
            } else if (btnNum === 0) {
                if (phase === 'down') {
                    closest = getClosest(parent, 'bottom-cell');
                    selfBottomCellIndex = closest.getAttribute('data-index') - 0;
                    selfBottomCell = bottomCells[selfBottomCellIndex];
                    inBottomCellIndex = getInCellIndex(target, selfBottomCell);
                    canMove = canMoveBottomCell(selfBottomCellIndex, inBottomCellIndex);
                    if (!canMove) {
                        target.style.zIndex = 3;
                        return;
                    }
                    bottomCellDomsXY = getBottomCellDomsXY();
                    if (inBottomCellIndex === 0) {
                        topLeftCellDomsXY = getTopLeftOrRightCellDomsXY(topLeftCellDomList);
                        topRightCellDomsXY = getTopLeftOrRightCellDomsXY(topRightCellDomList);
                    }
                } else if (phase === 'move') {
                    if (!canMove) {
                        return;
                    }
                    closest.style.zIndex = 3;
                    parent.style.left = dx + 'px';
                    parent.style.top = ver + dy + 'px';

                    var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
                    if (indexInBottomCells > -1) {
                        if (indexInBottomCells !== selfBottomCellIndex
                            && canDropToBottom(indexInBottomCells, selfBottomCell[inBottomCellIndex], inBottomCellIndex)) {
                            showLayer(bottomCellDoms[indexInBottomCells], bottomCellDomsXY[indexInBottomCells].height);
                        } else {
                            hideLayer();
                        }
                    } else if (inBottomCellIndex === 0) {
                        var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
                        if (indexInTopLeftCells > -1) {
                            if (topLeftCells[indexInTopLeftCells] === null) {
                                showLayer(topLeftCellDoms[indexInTopLeftCells]);
                            } else {
                                hideLayer();
                            }
                        } else {
                            var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
                            if (indexInTopRightCells > -1 && canDropBottomToTopRight(indexInTopRightCells, selfBottomCell)) {
                                showLayer(topRightCellDoms[indexInTopRightCells]);
                            } else {
                                hideLayer();
                            }
                        }
                    }
                } else {
                    if (!canMove) {
                        target.style.zIndex = 0;
                        return;
                    }
                    hideLayer();
                    closest.style.zIndex = 0;
                    parent.style.left = 0 + 'px';
                    parent.style.top = ver + 'px';
                    target.style.zIndex = 0;

                    var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
                    if (indexInBottomCells > -1) {
                        if (indexInBottomCells !== selfBottomCellIndex
                            && canDropToBottom(indexInBottomCells, selfBottomCell[inBottomCellIndex], inBottomCellIndex)) {
                            bottom2Bottom(selfBottomCell, inBottomCellIndex, indexInBottomCells);
                            if (gameOverOrRun()) {
                                autoMoveToTopRight();
                            }
                        }
                    } else if (inBottomCellIndex === 0) {
                        var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
                        if (indexInTopLeftCells > -1) {
                            if (topLeftCells[indexInTopLeftCells] === null) {
                                bottom2TopLeft(selfBottomCell, indexInTopLeftCells);
                                if (gameOverOrRun()) {
                                    autoMoveToTopRight();
                                }
                            }
                        } else {
                            var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
                            if (indexInTopRightCells > -1 && canDropBottomToTopRight(indexInTopRightCells, selfBottomCell)) {
                                bottom2TopRight(selfBottomCell, indexInTopRightCells);
                                if (gameOverOrRun()) {
                                    autoMoveToTopRight();
                                }
                            }
                        }
                    }
                }
            }
        }
    })());

    function showLayer(parent, height) {
        parent.appendChild(layer);
        if (height) {
            layer.style.top = '0px';
            layer.style.height = height + 'px';
        } else {
            layer.style.top = ver + 'px';
            layer.style.height = '140px';
        }
        layer.style.display = 'block';
    }

    function hideLayer() {
        layer.style.display = 'none';
    }

    function gameOverOrRun() {
        if (isSuccess()) {
            window.setTimeout(function () {
                alert("恭喜,游戏成功了");
            });
        } else if (isFail()) {
            window.setTimeout(function () {
                alert("已无牌可移动了");
            });
        }
        return true;
    }

    function isSuccess() {
        var topRightCells = param.topRightCells;
        for (var i = 0; i < topRightCells.length; i++) {
            if (topRightCells[i].length < 13) {
                return false;
            }
        }
        return true;
    }

    function isFail() {
        var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
        var topLeft = [], topRight = [], bottom = [];
        for (var i = 0; i < topLeftCells.length; i++) {
            if (topLeftCells[i] === null || topLeftCells[i].num === 1) {
                return false;
            }
            topLeft.push(topLeftCells[i]);
        }
        for (var i = 0; i < bottomCells.length; i++) {
            if (bottomCells[i].length === 0 || bottomCells[i][0].num === 1) {
                return false;
            }
            bottom.push(bottomCells[i][0]);
        }
        for (var i = 0; i < topRightCells.length; i++) {
            if (topRightCells[i].length > 0) {
                topRight.push(topRightCells[i][0]);
            }
        }
        for (var i = 0; i < topLeft.length; i++) {
            for (var j = 0; j < topRight.length; j++) {
                if (topLeft[i].num === topRight[j].num + 1 && topLeft[i].type === topRight[j].type) {
                    return false;
                }
            }
            for (var j = 0; j < bottom.length; j++) {
                if (topLeft[i].num === bottom[j].num - 1 && topLeft[i].color !== bottom[j].color) {
                    return false;
                }
            }
        }
        for (var i = 0; i < bottom.length; i++) {
            for (var j = 0; j < topRight.length; j++) {
                if (bottom[i].num === topRight[j].num + 1 && bottom[i].type === topRight[j].type) {
                    return false;
                }
            }
            for (var j = 0; j < bottom.length; j++) {
                if (bottom[i].num === bottom[j].num - 1 && bottom[i].color !== bottom[j].color) {
                    return false;
                }
            }
        }
        return true;
    }

    function autoMoveToTopRight() {
        var autoMove = false;
        (function timeoutMoveToTopRight() {
            window.setTimeout(function () {
                autoMove = moveOneToTopRight();
                if (autoMove) {
                    timeoutMoveToTopRight();
                }
            }, 200);
        })();

    }

    function moveOneToTopRight() {
        var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
        var one = getOneCanMoveTopRight();
        if (one === null) {
            return false;
        }
        var indexInTopRightCells = -1;
        if (one.position === 'topLeft') {
            var cell = topLeftCells[one.index];
            if (cell.num === 1) {
                for (var i = topRightCells.length - 1; i >= 0; i--) {
                    if (topRightCells[i].length === 0) {
                        indexInTopRightCells = i;
                        break;
                    }
                }
            } else {
                for (var i = 0; i < topRightCells.length; i++) {
                    if (topRightCells[i][0].num + 1 === cell.num && topRightCells[i][0].type === cell.type) {
                        indexInTopRightCells = i;
                        break;
                    }
                }
            }
            topLeft2TopRight(one.index, indexInTopRightCells);
        } else {
            var cells = bottomCells[one.index];
            if (cells[0].num === 1) {
                for (var i = topRightCells.length - 1; i >= 0; i--) {
                    if (topRightCells[i].length === 0) {
                        indexInTopRightCells = i;
                        break;
                    }
                }
            } else {
                for (var i = 0; i < topRightCells.length; i++) {
                    if (topRightCells[i][0].num + 1 === cells[0].num && topRightCells[i][0].type === cells[0].type) {
                        indexInTopRightCells = i;
                        break;
                    }
                }
            }
            bottom2TopRight(cells, indexInTopRightCells);
        }
        return true;
    }

    function getOneCanMoveTopRight() {
        var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
        var num = 13;
        for (var i = 0; i < topRightCells.length; i++) {
            if (topRightCells[i].length === 0) {
                num = 1;
                break;
            }
            var tmpNum = topRightCells[i][0].num;
            if (tmpNum < num) {
                num = tmpNum + 1;
            }
        }
        for (var i = 0; i < topLeftCells.length; i++) {
            if (topLeftCells[i] !== null && topLeftCells[i].num === num) {
                return {
                    position: 'topLeft',
                    index: i
                };
            }
        }
        for (var i = 0; i < bottomCells.length; i++) {
            if (bottomCells[i].length > 0 && bottomCells[i][0].num === num) {
                return {
                    position: 'bottom',
                    index: i
                }
            }
        }
        return null;
    }

    function canMoveBottomCount() {
        var topLeftCells = param.topLeftCells, bottomCells = param.bottomCells;
        var count = 1;
        for (var i = 0; i < topLeftCells.length; i++) {
            if (topLeftCells[i] === null) {
                count++;
            }
        }
        for (var i = 0; i < bottomCells.length; i++) {
            if (bottomCells[i].length === 0) {
                count++;
            }
        }
        return count;
    }

    function canMoveBottomCell(selfBottomCellIndex, inBottomCellIndex) {
        var bottomCellArr = param.bottomCells[selfBottomCellIndex];
        var cell = bottomCellArr[inBottomCellIndex];
        for (var i = inBottomCellIndex - 1; i >= 0; i--) {
            if (bottomCellArr[i].num + 1 !== cell.num || bottomCellArr[i].color === cell.color) {
                return false;
            }
            cell = bottomCellArr[i];
        }
        return true;
    }

    function canDropTopLeftToTopRight(indexInTopRightCells, selfTopLeftCell) {
        var topRightCell = param.topRightCells[indexInTopRightCells];
        return topRightCell.length === 0 ? selfTopLeftCell.num === 1
            : selfTopLeftCell.num === topRightCell[0].num + 1 && selfTopLeftCell.type === topRightCell[0].type;
    }

    function canDropBottomToTopRight(indexInTopRightCells, selfBottomCell) {
        var topRightCell = param.topRightCells[indexInTopRightCells];
        return topRightCell.length === 0 ? selfBottomCell[0].num === 1
            : selfBottomCell[0].num === topRightCell[0].num + 1 && selfBottomCell[0].type === topRightCell[0].type;
    }

    function canDropToBottom(indexInBottomCells, selfCell, inBottomCellIndex) {
        var bottomCell = param.bottomCells[indexInBottomCells];
        if (inBottomCellIndex > 0) {
            var count = canMoveBottomCount();
            if (bottomCell.length === 0 ? inBottomCellIndex + 1 >= count : inBottomCellIndex >= count) {
                return false;
            }
        }
        return bottomCell.length === 0
            || selfCell.num - 0 + 1 === bottomCell[0].num && selfCell.color - 0 !== bottomCell[0].color;
    }

    function topLeft2TopLeft(selfTopLeftCellIndex, indexInTopLeftCells) {
        var topLeftCells = param.topLeftCells;
        var topLeftCellDomList = topLeftCellDoms;
        var cell = topLeftCells[selfTopLeftCellIndex];
        topLeftCells[selfTopLeftCellIndex] = null;
        topLeftCellDomList[indexInTopLeftCells].appendChild(cell.dom);
        topLeftCells[indexInTopLeftCells] = cell;
    }

    function topLeft2TopRight(selfTopLeftCellIndex, indexInTopRightCells) {
        var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells;
        var topRightCellDomList = topRightCellDoms;
        var cell = topLeftCells[selfTopLeftCellIndex];
        topLeftCells[selfTopLeftCellIndex] = null;
        if (topRightCells[indexInTopRightCells].length > 0) {
            topRightCells[indexInTopRightCells][0].dom.appendChild(cell.dom);
            cell.dom.style.top = 0;
        } else {
            topRightCellDomList[indexInTopRightCells].appendChild(cell.dom);
        }
        topRightCells[indexInTopRightCells].unshift(cell);
    }

    function topLeft2Bottom(selfTopLeftCellIndex, indexInBottomCells) {
        var topLeftCells = param.topLeftCells, bottomCells = param.bottomCells;
        var bottomCellDomList = bottomCellDoms;
        var cell = topLeftCells[selfTopLeftCellIndex];
        topLeftCells[selfTopLeftCellIndex] = null;
        if (bottomCells[indexInBottomCells].length > 0) {
            bottomCells[indexInBottomCells][0].dom.appendChild(cell.dom);
        } else {
            bottomCellDomList[indexInBottomCells].appendChild(cell.dom);
        }
        bottomCells[indexInBottomCells].unshift(cell);
    }

    function bottom2TopLeft(selfBottomCell, indexInTopLeftCells) {
        var topLeftCells = param.topLeftCells;
        var topLeftCellDomList = topLeftCellDoms;
        var cell = selfBottomCell.shift();
        topLeftCellDomList[indexInTopLeftCells].appendChild(cell.dom);
        topLeftCells[indexInTopLeftCells] = cell;
        gameOverOrRun();
    }

    function bottom2TopRight(selfBottomCell, indexInTopRightCells) {
        var topRightCells = param.topRightCells;
        var topRightCellDomList = topRightCellDoms;
        var cell = selfBottomCell.shift();
        var topRightCell = topRightCells[indexInTopRightCells];
        if (topRightCell.length > 0) {
            topRightCell[0].dom.appendChild(cell.dom);
            cell.dom.style.top = 0;
        } else {
            topRightCellDomList[indexInTopRightCells].appendChild(cell.dom);
        }
        topRightCell.unshift(cell);
        gameOverOrRun();
    }

    function bottom2Bottom(selfBottomCell, inBottomCellIndex, indexInBottomCells) {
        var bottomCells = param.bottomCells;
        var bottomCellDomList = bottomCellDoms;
        var cells = selfBottomCell.splice(0, inBottomCellIndex + 1);
        if (bottomCells[indexInBottomCells].length > 0) {
            bottomCells[indexInBottomCells][0].dom.appendChild(cells[cells.length - 1].dom);
        } else {
            bottomCellDomList[indexInBottomCells].appendChild(cells[cells.length - 1].dom);
        }
        var targetCell = bottomCells[indexInBottomCells];
        for (var i = cells.length - 1; i >= 0; i--) {
            targetCell.unshift(cells[i]);
        }
        gameOverOrRun();
    }

    function getBottomCellDomsXY() {
        var width = 100, minHeight = 140;
        var bottomCellDomList = bottomCellDoms, bottomCells = param.bottomCells;
        var bottomCellDomsXY = [];
        var point = null;
        for (var i = 0; i < bottomCellDomList.length; i++) {
            point = getAbsPoint(bottomCellDomList[i]);
            point.width = width;
            point.height = (function (i) {
                var length = bottomCells[i].length;
                if (length < 2) {
                    return minHeight;
                } else {
                    return minHeight + (length - 1) * ver;
                }
            })(i);
            bottomCellDomsXY.push(point);
        }
        return bottomCellDomsXY;
    }

    function getTopLeftOrRightCellDomsXY(topLeftOrRightCellDoms) {
        var width = 100, height = 140;
        var topCellDomsXY = [];
        var point = null;
        for (var i = 0; i < topLeftOrRightCellDoms.length; i++) {
            point = getAbsPoint(topLeftOrRightCellDoms[i]);
            point.width = width;
            point.height = height;
            topCellDomsXY.push(point);
        }
        return topCellDomsXY;
    }

    function getInCellIndex(target, selfCell) {
        var num = target.getAttribute("data-num") - 0;
        var type = target.getAttribute('data-type') - 0;
        for (var i = 0; i < selfCell.length; i++) {
            if (selfCell[i].num === num && selfCell[i].type === type) {
                return i
            }
        }
        return -1;
    }

    function getIndexInTopCells(eX, eY, cellDomsXY) {
        for (var i = 0; i < cellDomsXY.length; i++) {
            if (eX >= cellDomsXY[i].x
                && eX <= cellDomsXY[i].x + cellDomsXY[i].width
                && eY >= cellDomsXY[i].y + ver
                && eY <= cellDomsXY[i].y + cellDomsXY[i].height + ver
            ) {
                return i;
            }
        }
        return -1;
    }

    function getIndexInBottomCells(eX, eY, cellDomsXY) {
        for (var i = 0; i < cellDomsXY.length; i++) {
            if (eX >= cellDomsXY[i].x
                && eX <= cellDomsXY[i].x + cellDomsXY[i].width
                && eY >= cellDomsXY[i].y
                && eY <= cellDomsXY[i].y + cellDomsXY[i].height
            ) {
                return i;
            }
        }
        return -1;
    }

    function getClosest(target, clazz) {
        var parent = target;
        for(;;) {
            parent = parent.parentNode;
            if (parent === null) {
                return null;
            } else if (parent.classList.contains(clazz)) {
                return parent;
            }
        }
    }

    function getIndexInNullTopLeftCells() {
        var topLeftCells = param.topLeftCells;
        for (var i = 0; i < topLeftCells.length; i++) {
            if (topLeftCells[i] === null) {
                return i;
            }
        }
        return -1;
    }

    function getIndexInTopLeftCells(dom) {
        var topLeftCells = param.topLeftCells;
        for (var i = 0; i < topLeftCells.length; i++) {
            if (topLeftCells[i] !== null && dom === topLeftCells[i].dom) {
                return i;
            }
        }
        return -1;
    }

    function getIndexInTopRightCells(cell) {
        var topRightCells = param.topRightCells;
        if (cell.num === 1) {
            for (var i = topRightCells.length - 1; i >= 0; i--) {
                if (topRightCells[i].length === 0) {
                    return i;
                }
            }
            return -1;
        } else {
            for (var i = 0; i < topRightCells.length; i++) {
                if (topRightCells[i].length > 0) {
                    var topRightCell = topRightCells[i][0];
                    if (topRightCell.num + 1 === cell.num && topRightCell.type === cell.type) {
                        return i;
                    }
                }
            }
            return -1;
        }
    }

    function getIndexInBottomCellsFirst(dom) {
        var bottomCells = param.bottomCells;
        for (var i = 0; i < bottomCells.length; i++) {
            if (bottomCells[i].length > 0 && dom === bottomCells[i][0].dom) {
                return i;
            }
        }
        return -1;
    }

    function reInit() {
        var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
        var topLeftCellDomList = topLeftCellDoms, topRightCellDomList = topRightCellDoms, bottomCellDomList = bottomCellDoms;
        for (var i = 0; i < topLeftCells.length; i++) {
            topLeftCells[i] = null;
            topLeftCellDomList[i].innerHTML = '';
        }
        for (var i = 0; i < topRightCells.length; i++) {
            topRightCells[i].length = 0;
            topRightCellDomList[i].innerHTML = '';
        }
        for (var i = 0; i < bottomCells.length; i++) {
            bottomCells[i].length = 0;
            bottomCellDomList[i].innerHTML = '';
        }
        init();
    }

    function init() {
        var initArr = [];
        var num, type, color;
        var random;
        for (var i = 0; i < 52; i++) {
            num = ~~(i / 4) + 1;
            type = i % 4 + 1;
            color = (type === 1 || type === 4) ? 1 : 2;
            random = ~~(Math.random() * initArr.length);
            initArr.splice(random, 0, new Cell(num, color, type));
        }
        var bottomCells = param.bottomCells;
        appendTimeout(bottomCells, initArr, 0);
    }
    function appendTimeout(bottomCells, initArr, i) {
        window.setTimeout(function () {
            if (i > initArr.length - 1) {
                return;
            }
            appendBottom(bottomCells[i % 8], bottomCellDoms[i % 8], initArr[i]);
            appendTimeout(bottomCells, initArr, i + 1);
        }, 25);
    }

    function appendBottom(bottomCell, bottomCellDom, cell) {
        if (bottomCell.length === 0) {
            bottomCellDom.appendChild(cell.dom);
        } else {
            bottomCell[0].dom.appendChild(cell.dom);
        }
        bottomCell.unshift(cell);
    }

    function dragEvent(dom, func) {
        var disX = 0,disY = 0, clientX = 0, clientY = 0, dx = 0, dy = 0;
        var el = dom.setCapture ? dom : document;
        var docElem, win,
            elem = dom,
            doc = elem && elem.ownerDocument;
        if ( !doc ) {
            return;
        }
        docElem = doc.documentElement;
        win = getWindow( doc );

        dom.onmousedown = function (ev) {
            dom.focus();
            var oEvent = ev || window.event, target = oEvent.target, btnNum = oEvent.button;
            var parent = null;
            if (target.classList.contains('cell-body')) {
                parent = target.parentNode;
            } else if (target.classList.contains('cell-container')) {
                parent = target;
                target = parent.childNodes[0];
            }
            if (parent == null) {
                return false;
            }
            var xOffset = ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 );
            var yOffset = ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 );

            disX = dx = oEvent.offsetX || oEvent.layerX || 0; disY = dy = oEvent.offsetY || oEvent.layerY || 0;
            clientX = oEvent.clientX; clientY = oEvent.clientY;
            var timeoutFunc = function (phase, oEvent) {
                func(parent, target, btnNum, phase, clientX + xOffset, clientY + yOffset,
                    oEvent.clientX + xOffset, oEvent.clientY + yOffset, oEvent.clientX - clientX, oEvent.clientY - clientY);
            };
            timeoutFunc('down', oEvent);
            if (btnNum !== 2) {
                el.onmousemove = function (ev) {
                    var oEvent = ev || window.event;
                    if(oEvent.stopPropagation) {
                        oEvent.stopPropagation();
                    } else {
                        oEvent.cancelBubble = true;
                    }
                    dx = disX + oEvent.clientX - clientX;  dy = disY + oEvent.clientY - clientY;
                    if (dx < 0) {dx = 0} else if (dx > dom.offsetWidth - 1) {dx = dom.offsetWidth - 1}
                    if (dy < 0) {dy = 0} else if (dy > dom.offsetHeight - 1) {dy = dom.offsetHeight - 1}
                    timeoutFunc('move', oEvent);
                    return false;
                };
            }
            el.onmouseup = function (ev) {
                var oEvent = ev || window.event;
                if(oEvent.stopPropagation) {
                    oEvent.stopPropagation();
                } else {
                    oEvent.cancelBubble = true;
                }
                timeoutFunc('up', oEvent);
                el.onmousemove = null; el.onmouseup = null; if(dom.releaseCapture) {dom.releaseCapture();}
            };
            if(dom.setCapture) {dom.setCapture();}
            return false;
        };
    }

    function isWindow ( obj ) {
        return obj != null && obj == obj.window;
    }

    function getWindow( elem ) {
        return isWindow( elem ) ?
            elem :
            elem.nodeType === 9 ?
                elem.defaultView || elem.parentWindow :
                false;
    }

    function getAbsPoint (el){
        var docElem, win,
            box = { top: 0, left: 0 },
            elem = el,
            doc = elem && elem.ownerDocument;

        if ( !doc ) {
            return;
        }

        docElem = doc.documentElement;

        if ( typeof elem.getBoundingClientRect !== typeof undefined ) {
            box = elem.getBoundingClientRect();
        }
        win = getWindow( doc );
        return {
            x: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ),
            y: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 )
        };
    }
})();
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值