tutu1973 发表于 2017-8-6 19:56

分享一个用HTML写的俄罗斯方块

源代码如下:
<!DOCTYPE html>
<html>


        <head>
                <title></title>
                <style type="text/css">
                        .c {
                                margin: 1px;
                                width: 19px;
                                height: 19px;
                                background: red;
                                position: absolute;
                        }
                       
                        .d {
                                margin: 1px;
                                width: 19px;
                                height: 19px;
                                background: gray;
                                position: absolute;
                        }
                       
                        .f {
                                top: 0px;
                                left: 0px;
                                background: black;
                                position: absolute;
                        }
                </style>
        </head>


        <body>
        </body>


</html>
<script type="text/javascript">
        var over = false,
                shapes = ("0,1,1,1,2,1,3,1;1,0,1,1,1,2,2,2;2,0,2,1,2,2,1,2;0,1,1,1,1,2,2,2;1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";");
        //shapes 中的每一个元素的各个数字意2两个一组,分别指该层移动的X,Y轴
        function create(tag, css) {
                var elm = document.createElement(tag); //创建一个tag标签
                elm.className = css; //添加一个css样式
                document.body.appendChild(elm); //把该标签添加到body标签中
                return elm;
        } //返回该标签
        function Field(w, h) { //Field整个游戏界面的对象,没跳动一次,就是一次刷新
                this.width = w ? w : 10;
                this.height = h ? h : 20;
                this.show = function() { //创建一个底层,游戏界面
                        var f = create("div", "f")
                        f.style.width = this.width * 20 + 'px';
                        f.style.height = this.height * 20 + 'px';
                }
                this.check = function(shape, x, y, d) { //判断是否到了边缘
                        var r1 = 0,
                                r2 = 'GO'; //每一次所生成的4个层绝对不会存在超出左边的同时又超出右边,故r1只有一个
                        for(var i = 0; i < 8; i += 2) {
                                //循环横坐标,查看是够超过边距
                                if(parseInt(shape) + x < 0 && parseInt(shape) + x < r1) {
                                        //若向左边移动会超出边界
                                        r1 = parseInt(shape) + x;
                                } else if(parseInt(shape) + x >= this.width && parseInt(shape) + x > r1) {
                                        //若向右移动会超出边界
                                        r1 = parseInt(shape) + x;
                                }
                                if(parseInt(shape) + y >= this.height || this) + x + (parseInt(shape) + y) * this.width]) {
                                        r2 = "NO";
                                }
                        }
                        if(d == "move" && r2 == "GO") { //当此次操作是左右移动的话,就返回移动后的横坐标,只要没有超出边界,r1就肯定不为0
                                return r1;
                        } else if(d == "upchange" && r2 == "GO") { //当此次操作是变换形状时
                                return r1 > 0 ? r1 - this.width + 1 : r1; //其实每次移动的都是该层的很坐标,以左边为准移动的
                        } else {
                                return r2;
                        }
                }
                this.findFull = function() { //判断该行是否已经满了
                        for(var h = 0; h < this.height; h++) { //循环底层的纵坐标
                                var s = 0;
                                for(var w = 0; w < this.width; w++) { //循环行坐标
                                        s += this ? 1 : 0 //确定每个坐标点上时候有元素,以便于确定改行是否满了
                                }
                                if(s == this.width) { //若改行满了,则调用removeLine方法,一处该行的每一个元素
                                        this.removeLine(h);
                                }
                        }
                }
                //清除已经填满的行
                this.removeLine = function(line) {
                        for(var w = 0; w < this.width; w++) { //因为每个元素都是根据对象的横纵坐标在存储,所以需要重新循环横坐标,以便于取出每一个元素
                                document.body.removeChild(this); //每个元素都是在body上存在着
                        }
                        //移除该行之后需要让其上的每行都向下移动一行
                        for(var l = line; l > 0; l--) {
                                for(var i = 0; i < this.width; i++) {
                                        this = this; //把上一行的元素付给下一行的元素()
                                        if(this) {
                                                this.style.top = l * 20 + 'px'; //移动
                                        }
                                }
                        }
                }
                this.fixShape = function(shape, x, y) { //生成落地的方块
                        var d = new Tetris("d", shape, x, y);
                        d.show();
                        for(var i = 0; i < 8; i += 2) { //记录每个变灰色的div层,只有成功到底底层的时候才记录
                                //parseInt(shape) + x   记录的为该层的横坐标
                                //parseInt(shape) + y    记录的为纵坐标
                                //这样是为了this[…]是唯一。
                                this) + x + (parseInt(shape) + y) * this.width] = d.divs;
                        }
                }
        }


        function Tetris(c, t, x, y) {
                var c = c ? c : "c"; //若C存在,则为C,不存在,则赋值
                this.field = null;
                this.divs = ; //调用create方法创建元素
                var ttt = t;
                this.reset = function() { //创建一个方块
                        this.x = typeof x != 'undefined' ? x : 3;
                        this.y = typeof y != 'undefined' ? y : 0;
                        this.shape = t ? t : (shapes.split(","));
                        this.show();
                        //当刚生的方块就不能再向下移动的时候,游戏结束
                        if(this.field && this.field.check(this.shape, this.x, this.y, "down") == "NO") {
                                over = true;
                                this.field.fixShape(this.shape, this.x, this.y);
                                alert('game over');
                        }
                }
                this.show = function() { //根据生成的方案,初始化方块。
                        for(var i = 0; i < this.divs.length; i++) {
                                this.divs.style.left = (this.shape * 1 + this.x) * 20 + 'px';
                                this.divs.style.top = (this.shape * 1 + this.y) * 20 + 'px';
                        }
                }
                this.vMove = function() { //该方法使方块向下移动
                        if(this.field.check(this.shape, this.x, this.y + 1, "down") == "GO") { //若还能向下移动就执行
                                this.y++;
                                this.show();
                        } else {
                                this.field.fixShape(this.shape, this.x, this.y); //不能向下移动了,就生成固定的块。
                                this.field.findFull();
                                this.reset();
                        };
                }
                this.hMove = function(moveNo) { //该方法使方块左右移动
                        var r = this.field.check(this.shape, parseInt(this.x) + moveNo, this.y, 'move');
                        if(r != 'GO' && r == 0) {
                                this.x += moveNo;
                                this.show();
                        }
                }
                this.rotate = function() { //当按动上键时,改变方块的排列方向
                        var s = this.shape;
                        var newShape = , s, 3 - s, s, 3 - s, s, 3 - s, s]; //先把坐标循环180度,然后纵横坐标互换。
                        var r = this.field.check(newShape, this.x, this.y, 'upchange'); //调用check方法,确定时候可以改变
                        if(r == "NO") { return; };
                        if(r == 0) { //若为0 ,则说明改变后的块并没有超出范围,继续执行
                                this.shape = newShape;
                                this.show();
                        } else if(this.field.check(newShape, this.x - r, this.y, 'move') == 0) { //超出后,根据返回值,让其向相应的方向移动。以保证并不会超出范围
                                this.x -= r;
                                this.shape = newShape;
                                this.show();
                        }
                }
                this.reset();
        }
        var f = new Field();
        f.show();
        var t = new Tetris();
        t.field = f;
        t.reset();
        window.setInterval("if(!over)t.vMove();", 500); //调用向下移动的方法
        document.onkeydown = function(e) { //当按上下左右键时,触发
                if(over) return;
                var e = window.event ? window.event : e;
                switch(e.keyCode) {
                        case 38: //up当按下上键时
                                t.rotate();
                                break;
                        case 40: //down
                                t.vMove();
                                break;
                        case 37: //left
                                t.hMove(-1);
                                break;
                        case 39: //right
                                t.hMove(1);
                                break;
                }
        }
</script>

zaqw0001 发表于 2017-8-6 20:46

按那个都不行。。。page up page down都不行。。。

chaobai666 发表于 2017-8-6 20:13

谢谢分享,我去玩玩

zhangjy_12 发表于 2017-8-6 20:31

厉害!!!

寂寞知己 发表于 2017-8-6 20:33

这个还行吧

web3399 发表于 2017-8-6 20:35

感谢分享。

心之所向便是光 发表于 2017-8-6 20:41

感谢分享,厉害厉害!

one486 发表于 2017-8-6 21:14

shadowxjp 发表于 2017-8-6 21:27


谢谢分享

天宫太祖 发表于 2017-8-6 21:37

学习一下,谢谢楼主!
页: [1] 2 3 4 5 6 7
查看完整版本: 分享一个用HTML写的俄罗斯方块