JS版的俄罗斯方块

原创 2013年12月01日 23:04:19

上班偷懒写了个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拖拽俄罗斯方块小游戏(一)

这是一个拖拽类游戏,拖拽元素使用的是类俄罗斯方块。
  • u012601195
  • u012601195
  • 2016年08月07日 09:53
  • 799

js版俄罗斯方块设计思想及实现

俄罗斯方块方块是小时候的一个回忆,从最开始的掌上的黑白游戏机,到电视游戏机,到电脑,无不有它的痕迹,今天我们来一起重温它的一种实现方法,也算是整理一下我的思路吧...... 1.以中心点坐标代替整个...
  • luqin1988
  • luqin1988
  • 2013年01月18日 09:50
  • 4160

带AI的俄罗斯方块源码

好久没写俄罗斯方块的游戏了。从学习编程到现在,相继用Win32 API、MFC、C、C#、JS、iOS写过大约二十款左右的俄罗斯方块游戏。最近用Cocos2d-x写了一下,第一次完全将游戏逻辑与UI层...
  • yjh4866
  • yjh4866
  • 2015年05月12日 22:27
  • 4986

俄罗斯方块的源码实现

介绍俄罗斯方块(Tetris, 俄文:Тетрис)是一款电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之...
  • u011889952
  • u011889952
  • 2015年03月24日 20:13
  • 967

纯js实现俄罗斯方块详解与源码

对于小白来说用js实现俄罗斯方块还是有难度的,网上找了很多代码看,有的很长难懂,有的短小精悍,但不只用到了js还用到了框架,对于还未接触框架的小白宝宝,也只能无奈自己是小白了,自己写不出来那就找一篇纯...
  • d1105260363
  • d1105260363
  • 2017年08月23日 17:54
  • 471

JS写俄罗斯方块完美注释版

JS写俄罗斯方块完美注释版/************************************************************* JS俄罗斯方块完美注释版 v 1.01* 作者:...
  • sunxing007
  • sunxing007
  • 2008年11月19日 00:35
  • 14549

VC/MFC 俄罗斯方块双人版(基于MFC单文档)

游戏最终界面如图:题目要求参考VC++程序设计实验指导书,将上次编写的dos版双人俄罗斯方块改写成VC界面版。功能需求①实现双人俄罗斯方块 ②隐藏菜单栏、工具栏、状态栏 ③实现难度可以选择 ④实...
  • u012339743
  • u012339743
  • 2017年01月05日 15:58
  • 999

[前端 3]纯Js制作俄罗斯方块游戏

导读:在别人文章里看到了,然后写了一遍。结果出错了,然后调出来了,然后理解了一下,加了点注释,有一些想法。忘了在 哪一篇上面看的了,就贴不出来链接地址。原谅。呃,真没自己的东西,权当练打字了吧。其实,...
  • u013034889
  • u013034889
  • 2016年04月10日 00:08
  • 2027

原生JS代码编写网页版俄罗斯方块小游戏——方块旋转

原理部分:旋转方法是根据方块的数据结构来确定的。一个俄罗斯方块是由四个小方块在平面上组合得到的。法一:一维数组旋转(本人使用方法)使用长度为16或长度为9的一维数组来表示。由于长度固定,可以提前预设旋...
  • wutingyehe
  • wutingyehe
  • 2017年05月07日 17:18
  • 350

俄罗斯方块中方块的旋转变形

本文针对用js编写俄罗斯方块的时候,方块的旋转变形算法,以逆时针旋转为例,下图为旋转的说明图 第一次用visio画图,画的很不好,坐标(x,y)绕(x0,y0)逆时针旋转90度后的坐标为(x0+y...
  • hanxueyu666
  • hanxueyu666
  • 2016年05月07日 16:30
  • 2007
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JS版的俄罗斯方块
举报原因:
原因补充:

(最多只允许输入30个字)