JS版的俄罗斯方块

上班偷懒写了个JS版的俄罗斯方块,给各位屌丝娱乐娱乐!BUG是有的,也还有很多可以改进的。以后有时间了再整有完美版的,

        写这个DEMO主要原因是为了重温下:那些年学习程序开发时,写过的游戏DEMO。

        重新拾起当年为"为激情(兴趣)而CODE",而不是现在的为生活而CODE。工作的几年中,总是想方涉法的想在工作中学到更多关于软件开发方面的东西,总是期待在工作中能接触到更多新潮的、前卫的、牛B的技术。要说为什么会这样,原因其实很简单:就是为了在自己在下一份工作中,不落后别人,期待自己掌握的技术越多,找下一份工作就越容易,当然薪水也会涨得相对高点。然后就足渐的迷失了自己当年的那份激情。

       看来得找个时间,找个幽静的地方,一个人坐下来好好的思考一下今后的路和方向该怎么走了。



<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>


</body>


<script type="text/javascript">

(function () {
    var box = {
        status: [
//------------------------------------------------------------------------------------------------
        /****/
//------------------------------------------------------------------------------------------------
            [   //长条****
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 1, 0, 0],
                    [0, 1, 0, 0],
                    [0, 1, 0, 0],
                    [0, 1, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 1, 0, 0],
                    [0, 1, 0, 0],
                    [0, 1, 0, 0],
                    [0, 1, 0, 0]
                ]
            ] ,
//------------------------------------------------------------------------------------------------
            /*
             *
             * */
//------------------------------------------------------------------------------------------------
            [
                [
                    [0, 0, 0, 0],
                    [0, 2, 0, 0],
                    [0, 2, 2, 2],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [0, 2, 2, 0],
                    [0, 2, 0, 0],
                    [0, 2, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [2, 2, 2, 0],
                    [0, 0, 2, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 2, 0],
                    [0, 0, 2, 0],
                    [0, 2, 2, 0],
                    [0, 0, 0, 0]
                ]
            ] ,
//------------------------------------------------------------------------------------------------
            /*
             *
             * */
//------------------------------------------------------------------------------------------------
            [
                [
                    [0, 0, 0, 0],
                    [0, 3, 3, 3],
                    [0, 3, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 3, 3, 0],
                    [0, 0, 3, 0],
                    [0, 0, 3, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [0, 0, 3, 0],
                    [3, 3, 3, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 3, 0, 0],
                    [0, 3, 0, 0],
                    [0, 3, 3, 0],
                    [0, 0, 0, 0]
                ]
            ] ,
//------------------------------------------------------------------------------------------------
            /*
             * *
             */
//------------------------------------------------------------------------------------------------
            [
                [
                    [0, 4, 0, 0],
                    [0, 4, 4, 0],
                    [0, 0, 4, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [0, 4, 4, 0],
                    [4, 4, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 4, 0, 0],
                    [0, 4, 4, 0],
                    [0, 0, 4, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [0, 4, 4, 0],
                    [4, 4, 0, 0],
                    [0, 0, 0, 0]
                ]
            ] ,
//------------------------------------------------------------------------------------------------
            /*
             * *
             */
//------------------------------------------------------------------------------------------------
            [
                [
                    [0, 0, 5, 0],
                    [0, 5, 5, 0],
                    [0, 5, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [5, 5, 0, 0],
                    [0, 5, 5, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 5, 0],
                    [0, 5, 5, 0],
                    [0, 5, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [5, 5, 0, 0],
                    [0, 5, 5, 0],
                    [0, 0, 0, 0]
                ]
            ] ,

//------------------------------------------------------------------------------------------------
            /*
             * * */
//------------------------------------------------------------------------------------------------
            [
                [
                    [0, 0, 0, 0],
                    [0, 6, 0, 0],
                    [6, 6, 6, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 6, 0, 0],
                    [0, 6, 6, 0],
                    [0, 6, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [6, 6, 6, 0],
                    [0, 6, 0, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 6, 0, 0],
                    [6, 6, 0, 0],
                    [0, 6, 0, 0],
                    [0, 0, 0, 0]
                ]
            ] ,

//------------------------------------------------------------------------------------------------
            /*
             * * */
//------------------------------------------------------------------------------------------------
            [
                [
                    [0, 0, 0, 0],
                    [0, 7, 7, 0],
                    [0, 7, 7, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [0, 7, 7, 0],
                    [0, 7, 7, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [0, 7, 7, 0],
                    [0, 7, 7, 0],
                    [0, 0, 0, 0]
                ],
                [
                    [0, 0, 0, 0],
                    [0, 7, 7, 0],
                    [0, 7, 7, 0],
                    [0, 0, 0, 0]
                ]
            ]
        ],

        statusSum: 7,
        width: 10,

        nextStatus: null,
        nextIndex: 0,
        nextBlock: null,

        curIndex: 0,
        curStatus: [],
        curBlock: null,
        color: ["", "red", "green", "blue", "yellow", "orange", "pink", "purple", "black"],
        x: 0,
        y: 0,

        tetris: null,

        move: function (x, y) {
            this._move(x, y);
            this.draw();
        },

        around: function () {
            this.curIndex++;
            if (this.curIndex >= 4) {
                this.curIndex = 0;
            }
            this._createBlock(this.curStatus);
            var bak = this.curBlock;
            this.curBlock = this._createBlock(this.curStatus);
            bak.parentNode.removeChild(bak);
        },

        newBlock: function () {
            if (this.curBlock) {
                this.curBlock.parentNode.removeChild(this.curBlock);
            }

            if (this.nextStatus) {
                this.curIndex = this.nextIndex;
                this.curStatus = this.nextStatus;
                this.curBlock = this.nextBlock;
            } else {
                var statusIndex = Math.random() * 7;
                this.curStatus = this.status[parseInt(statusIndex) ];
                this.curBlock = this._createBlock(this.curStatus);
            }
            this.x = 5;
            this.y = -4;

            this._newNextBlock();

        },
        _newNextBlock: function () {
            var statusIndex = Math.random() * 7;
            this.nextStatus = this.status[parseInt(statusIndex) ];
            this.nextBlock = this._createBlock(this.nextStatus);
            this.drawNext();
        },
        _move: function (px, py) {
            this.x = this.x + px;
            this.y = this.y + py;
        },

        draw: function () {
            this.curBlock.style.left = this.x * this.width + "px";
            this.curBlock.style.top = this.y * this.width + "px";
        },

        drawNext: function () {
            this.nextBlock.style.left = parseFloat(this.tetris.scoreBox.style.left)+ this.width + "px";
            this.nextBlock.style.top = parseFloat(this.tetris.scoreBox.style.top) + 50 + "px";
            document.body.appendChild(this.nextBlock)
        },

        _createBlock: function (_curStatus) {
            var bbox = document.createElement("div");
            bbox.style.position = "absolute";
            var curStatu = _curStatus[this.curIndex];
            for (var y in  curStatu) {
                for (var x in curStatu[y]) {
                    if (curStatu[y][x] == 0) {
                        continue;
                    }
                    var box = document.createElement("div");
                    box.style.position = "absolute";
                    box.style.top = y * this.width + "px";
                    box.style.left = x * this.width + "px";
                    box.style.width = this.width + "px";
                    box.style.height = this.width + "px";
                    box.style.backgroundColor = this.color[curStatu[y][x]];
                    bbox.appendChild(box);
                }
            }
            return bbox;
        }
    };

    function Tetris() {
        return this.init();
    }

    Tetris.prototype = {
        wall: [],
        wallBlocks: [],
        wallBox: [],
        width: 20,
        time: 0,
        delay: 500,
        isMove: false,
        score: 0,
        scoreBox: null,

        colorBlack: box.color.length - 1,

        LEFT: 37,
        UP: 38,
        RIGHT: 39,
        DOWM: 40,

        init: function () {
            this._initWall();
            this._createScoreBox();
            box.tetris = this;
            this.start();
        },
        _initWall: function () {
            for (var y = 0; y < this.width; y++) {
                this.wall[y] = [];
                for (var x = 0; x < this.width; x++) {
                    this.wall[y][x] = 0;
                    if (y == 0 || y == this.width - 1) {
                        this.wall[y][x] = this.colorBlack;
                    }
                    if (x == 0 || x == this.width - 1) {
                        this.wall[y][x] = this.colorBlack;
                    }
                }
            }
            this._createWall();
            this._paintWall();
        },
        start: function () {
            this._newBox();
            document.onkeydown = applyFn(this, this._keypress);
            this.time = setInterval(applyFn(this, this._thread), this.delay);
        },
        _thread: function () {
            if (this._canMove(0, 1) && this.isMove) {
                box.move(0, 1);
            } else {
                this.isMove = false;
                if (this._isOver()) {
                    clearInterval(this.time);
                    this.scoreBox.innerHTML = "<br/>game over!";
                } else {
                    this._copyBoxToWall();
                    this._deleteLine();//消除行
                    this._paintWall();
                    this._newBox();
                    if (this.score % 2 == 0) {
                        this.delay = this.delay - this.score * this.score;
                    }
                    this.scoreBox.innerHTML = this.score;
                }
                this.isMove = true;
            }
        },
        _keypress: function (event) {
            this.isMove = false;
            event = fixEvent(event || window.event);
            event.preventDefault();
            var x = 0, y = 0;
            if (event.which == this.LEFT) {
                x = -1, y = 0;
            } else if (event.which == this.UP) {
                if (this._canRound()) {
                    box.around();
                    box.draw();
                    this.wallBox.appendChild(box.curBlock);
                }

            }
            else if (event.which == this.RIGHT) {
                x = 1, y = 0;
            }
            else if (event.which == this.DOWM) {
                x = 0, y = 1;
            }
            if (this._canMove(x, y) && event.which != this.UP) {
                box.move(x, y);
            }
            this.isMove = true;
        },
        _newBox: function () {
            box.newBlock();
            box.draw();
            this.isMove = true;
            this.wallBox.appendChild(box.curBlock);
        },
        _canMove: function (px, py) {
            var curBox = box.curStatus[box.curIndex];
            for (var y = curBox.length - 1; y >= 0; y--) {
                for (var x = 0; x < curBox[y].length; x++) {
                    var wx = (box.x + x + px), wy = (box.y + y + py);
                    if (px != 0) {
                        if (wx <= 0)  wx = 0;
                        if (wx >= this.width - 1)  wx = this.width - 1;
                        if (curBox[y][x] > 0 && wy < 0) return false;
                        if (curBox[y][x] > 0 && this.wall[wy][wx] > 0) return false;
                        continue;
                    }

                    if (py != 0) {
                        if (wy <= 0)  wy = 1;
                        if (wy >= this.width - 1)  wy = this.width - 1;
                        if (curBox[y][x] > 0 && wy >= this.width - 1) return false;
                        if (curBox[y][x] > 0 && this.wall[wy][wx] > 0) return false;
                    }
                }
            }
            return true;
        },
        _canRound: function () {
            var nextIndex = box.curIndex + 1;
            if (nextIndex >= 4) nextIndex = 0
            var nextBox = box.curStatus[nextIndex];
            for (var y = 0; y < nextBox.length; y++) {
                for (var x = 0; x < nextBox[y].length; x++) {
                    var wx = (box.x + x), wy = (box.y + y);
                    if (nextBox[y][x] > 0 && this.wall[wy] && this.wall[wy][wx] != 0) {
                        return false;
                    }
                }
            }
            return true;
        },
        _isOver: function () {
            var curBox = box.curStatus[box.curIndex];
            return box.y <= 0
        },
        _copyBoxToWall: function () {
            var curBox = box.curStatus[box.curIndex];
            for (var y = 0; y < curBox.length; y++) {
                for (var x = 0; x < curBox[y].length; x++) {
                    var wx = box.x + x;
                    var wy = box.y + y;
                    if (wy <= 0) break;
                    if (curBox[y][x] > 0 && this.wall[wy][wx] == 0) {
                        this.wall[wy][wx] = curBox[y][x]
                    }
                }
            }
        },
        _deleteLine: function () {
            //从边框内开始循环,所有减2

            var delLine = [];
            var endLine = -1;
            var isDel = true;

            for (var y = this.width - 2; y > 0; y--) {
                isDel = true;
                applyFn(this, calCol)(y);
                if (endLine != -1) {     //>endLine以上行才有方块
                    break;
                }
                else if (isDel) {  //收集消除行
                    delLine.push(y);
                }
            }

            if (endLine != -1) {
                while (delLine.length) {
                    this.score++;
                    for (var y = delLine.pop(); y >= endLine; y--) {
                        for (var x = 1; x < this.width - 1; x++) {
                            if (y - 1 <= 0) {
                                this.wall[y][x] = 0;
                            }
                            else {
                                this.wall[y][x] = this.wall[y - 1][x];
                            }
                        }
                    }
                }
            }

            function calCol(y) {
                var sum = this.width - 1;
                var count = 1;
                for (var x = 1; x < this.width - 1; x++) {
                    if (this.wall[y][x] == 0) {
                        isDel = false;
                        count++;
                    }

                }
                if (count == sum) {   //>y以上行才有方块
                    endLine = y;
                }
            }
        },
        _createWall: function () {
            var wall = document.createElement("div");
            wall.style.position = "absolute";
            wall.style.overflow = "hidden";
            wall.style.width = 20 * box.width + "px";
            wall.style.height = 20 * box.width + "px";
            wall.style.top = 100 + "px";
            wall.style.left = 100 + "px";
            document.getElementsByTagName("body")[0].appendChild(wall);
            this.wallBox = wall;

            for (var y = 0; y < this.width; y++) {
                var wallBlockX = [];
                for (var x = 0; x < this.width; x++) {
                    var wallBlock = document.createElement("div");
                    wallBlock.style.position = "absolute";
                    wallBlock.style.backgroundColor = box.color[this.wall[y][x]];
                    wallBlock.style.width = box.width + "px";
                    wallBlock.style.height = box.width + "px";
                    wallBlock.style.left = x * box.width + "px";
                    wallBlock.style.top = y * box.width + "px";
                    this.wallBox.appendChild(wallBlock);
                    wallBlockX.push(wallBlock)
                }
                this.wallBlocks.push(wallBlockX);
            }
        },
        _paintWall: function () {
            for (var y = 0; y < this.width; y++) {
                var wallBlockXs = this.wallBlocks[y];
                for (var x = 0; x < this.width; x++) {
                    wallBlockXs[x].style.backgroundColor = box.color[this.wall[y][x]];
                }
            }
        },
        _createScoreBox: function () {
            var scoreBox = document.createElement("div");
            scoreBox.style.position = "absolute";
            scoreBox.style.border = "1px solid black";
            scoreBox.style.overflow = "hidden";
            scoreBox.style.width = 100 + "px";
            scoreBox.style.height = 100 + "px";
            scoreBox.style.top = this.wallBox.style.top;
            scoreBox.style.left = 110 + parseFloat(this.wallBox.style.width) + "px";
            document.getElementsByTagName("body")[0].appendChild(scoreBox);
            this.scoreBox = scoreBox;

        }
    }

    function applyFn(obj, fn) {
        return function () {
            fn.apply(obj, arguments);
        }
    }

    function callFn(obj, fn) {
        return function () {
            fn.apply(obj);
        }
    }

    function fixEvent(event) {
        if (event.preventDefault)  event.preventDefault();
        else {
            event.preventDefault = function () {
                event.returnValue = false;
            };
        }

        if (event.which == null && (event.charCode != null || event.keyCode != null)) {
            event.which = event.charCode != null ? event.charCode : event.keyCode;
        }

        return event;
    }

    window.Tetris = Tetris;
})();

new Tetris();

</script>
</html>

你可能感兴趣的:(JS版的俄罗斯方块)