俄罗斯方块 js javascript jquery 实现

介绍

俄罗斯方块的实现
有问题 或者 有建议 评论区见
代码没有很好优化,可能存在冗余;

代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>俄罗斯方块</title>
    <!--修改成你自己jquery的地址-->
    <script src="js/jquery-3.6.0.js"></script>
    <!--

    一个方块是20px
    每个方块间距2px

    宽 20*12+2*11 = 262
    20--20--20--2020*20+2*19 = 438
    20
    |
    20
    |
    20

    -->


    <style>
        * {
            margin: 0;
            padding: 0;
        }

        li {
            list-style: none;
            margin: 0 auto;
            height: 40px;
            text-align: center;
            line-height: 40px;
            list-style: none;
        }

        .score {
            color: #ec6565;
        }

        .background {
            position: relative;
            left: 50%;
            transform: translateX(-50%);
            margin-top: 10px;
            width: 262px;
            height: 438px;
            border: 2px solid #2a2a2a;
            background-color: #828282;
        }

        .atom {
            position: absolute;
            width: 20px;
            height: 20px;
            background-color: #d6d6d6;
        }
    </style>
</head>
<body>
<div>
    <li class=" score">0</li>
    <li class=""><a id="start" href="#">开始</a></li>
    <li class=""><a href="">重新开始</a></li>
    <li>A:逆时针旋转 上键:顺时针旋转 空格:暂停 方向键左右移动 下键加速</li>
</div>


<div class="background">

</div>

</body>
<script>
    var elements = ['I', 'o', 'Z', 'z', 'L', 'l', 'T']
    var gameOver = true;
    var gamePause = false;

    var grid = new Map();
    reGrid();

    //刷新grid
    function reGrid() {
        for (var i = 0; i <= 418; i += 22) {
            grid.set(i, new Array());
        }
    }

    //将方块存入grid中
    function addGrid(atom) {
        var top = parseInt($(atom).css('top'));
        var left = parseInt($(atom).css('left'));
        //已存在的方块存入grid
        grid.get(top).push(left);
    }

    //移动
    function move(speed) {
        var atoms = $('.atom:lt(4)')
        moveDown = setInterval(function () {
            var flag = true;
            //判断是否移动
            $(atoms).each(function () {
                var top = parseInt($(this).css('top'));
                var left = parseInt($(this).css('left'));
                //判断是否到底 到底结束移动
                if (top != 418) {
                    //判断是否有方块
                    if (grid.get(top + 22).includes(left)) {
                        flag = false;
                    }
                } else {
                    flag = false;
                }
            })

            //true可以移动
            if (flag) {
                $(atoms).each(function () {
                    var top = parseInt($(this).css('top'));
                    top += 22;
                    $(this).css('top', top + 'px');
                })
            } else {
                //结束移动 存入grid中
                $('.atom:lt(4)').each(function () {
                    addGrid($(this));
                });
                clearInterval(moveDown);
                //判断是否得分
                score();
            }
        }, speed)
    }

    //随机数
    function random() {
        return Math.floor(Math.random() * 7);
    }

    //随机创建元素
    function create() {
        if (!gameOver) {
            return;
        }
        var element = elements[random()];
        $('.background').prepend("<div class=\"atom\"></div>\n" +
            "    <div class=\"atom\"></div>\n" +
            "    <div class=\"atom\"></div>\n" +
            "    <div class=\"atom\"></div>")
        //创建元素
        switch (element) {
            case 'I':
                I();
                break;
            case 'o':
                o();
                break;
            case 'Z':
                Z();
                break;
            case 'z':
                z();
                break;
            case 'L':
                L();
                break;
            case 'l':
                l();
                break;
            case 'T':
                T();
                break;
        }
        move(300);
    }

    //判断是否得分
    function score() {
        var flag = false;
        //遍历grid若其中一个value的长度为12 得分
        grid.forEach(function (value, key) {
            if (value.length === 12) {
                console.log(value);
                $('.score').text(parseInt($('.score').text()) + 10)
                deleteRow(key)
                flag = true;
            }
        })
        create();
    }

    //删除得分行
    function deleteRow(row) {
        //遍历所有.atom 将得分行的div删除
        $('.atom').each(function () {
            var top = parseInt($(this).css('top'));
            if (top === row) {
                $(this).remove();
            }
        })
        //遍历所有.atom 小于row的行数下移一格
        $('.atom').each(function () {
            var top = parseInt($(this).css('top'));
            if (top < row) {
                $(this).css('top', top + 22);
            }
        })
        //刷新grid
        reGrid();
        $('.atom').each(function () {
            addGrid($(this));
        });
    }

    //判断生成的是否已经顶到顶部
    function judge(atoms) {
        $(atoms).each(function () {
            var top = parseInt($(this).css('top'));
            var left = parseInt($(this).css('left'));
            if (grid.get(top).includes(left)) {
                over();
            }
        })
    }

    //游戏结束
    function over() {
        gameOver = false;
        alert("游戏结束!得分:" + $('.score').text())
    }

    //键盘监听
    //左右移动
    $(window).keydown(function (event) {
        //判断是否已经游戏结束
        if (!gameOver) {
            return;
        }
        //游戏暂停
        if (event.which === 32) {
            if (gamePause) {
                move(200);
                gamePause = false;
            } else {
                clearInterval(moveDown);
                gamePause = true;
            }
        } else if (gamePause) {
            return;
        }

        //左移动
        if (event.which === 37) {
            var flag = false
            $('.atom:lt(4)').each(function () {
                var left = parseInt($(this).css('left'));
                var top = parseInt($(this).css('top'));
                //判断左边是否有方块
                if (grid.get(top).includes(left - 22)) {
                    flag = true;
                }
                if (left <= 0) {
                    flag = true;
                }
            })
            if (flag) {
                return;
            }

            $('.atom:lt(4)').each(function () {
                var left = parseInt($(this).css('left'));
                left -= 22;
                $(this).css('left', left + 'px');
            })
        }
        //右移动
        if (event.which === 39) {
            var flag = false
            $('.atom:lt(4)').each(function () {
                var left = parseInt($(this).css('left'));
                var top = parseInt($(this).css('top'));
                //判断左边是否有方块
                if (grid.get(top).includes(left + 22)) {
                    flag = true;
                }
                if (left >= 242) {
                    flag = true;
                }
            })
            if (flag) {
                return;
            }

            $('.atom:lt(4)').each(function () {
                var left = parseInt($(this).css('left'));
                left += 22;

                $(this).css('left', left + 'px');
            })
        }

        //变换
        //a:65 b:68
        var ccw = 65;
        var cw = 38;
        if (event.which === ccw || event.which === cw) {
            var sumT = 0;
            var sumL = 0;
            var top = parseInt($('.atom:eq(0)').css('top'));
            var left = parseInt($('.atom:eq(0)').css('left'));
            var atoms = $('.atom:lt(4)');
            //判断如果是o直接退出 无需变换
            if ($('.atom:eq(0)').attr('id') === 'o') {
                return;
            }
            //计算top left的和
            $('.atom:lt(4)').each(function () {
                sumT += parseInt($(this).css("top"));
                sumL += parseInt($(this).css("left"));
            })
            //I 变换
            if (top * 4 === sumT && $('.atom:eq(0)').attr('id') === 'I') {
                if (top < 396) {
                    if(grid.get(top-22).includes(left)){
                        return;
                    }else if(grid.get(top+22).includes(left)){
                        return;
                    }else if(grid.get(top+44).includes(left)){
                        return;
                    }
                    $(atoms[1]).css({'top': top - 22, 'left': left});
                    $(atoms[2]).css({'top': top + 22, 'left': left});
                    $(atoms[3]).css({'top': top + 44, 'left': left});
                }
                return;
            } else if (left * 4 === sumL && $('.atom:eq(0)').attr('id') === 'I') {
                //如果是贴墙变换 向墙的反向移动一格
                if (left === 0) {
                    left += 22;
                } else if (left === 242) {
                    left -= 44;
                }
                if(grid.get(top).includes(left-22)){
                    return;
                }else if(grid.get(top).includes(left+22)){
                    return;
                }else if(grid.get(top).includes(left+44)){
                    return
                }
                $(atoms[0]).css({'top': top, 'left': left});
                $(atoms[1]).css({'top': top, 'left': left - 22});
                $(atoms[2]).css({'top': top, 'left': left + 22});
                $(atoms[3]).css({'top': top, 'left': left + 44});
                return;
            }

            //变换前九宫数组
            var a = [
                [top - 22, left - 22], [top - 22, left], [top - 22, left + 22],
                [top, left - 22], [top, left], [top, left + 22],
                [top + 22, left - 22], [top + 22, left], [top + 22, left + 22],
            ];

            //判断是否可以变换
            for (var i = 0; i < 9; i++) {
                var key = a[i][0];
                var value = a[i][1];
                var gridValue = grid.get(key);
                if (gridValue.includes(value)) {
                    return;
                }
            }

            //各atom在a中的位置
            var c = new Array();
            //记录atom在a中的位置 并记录索引 index:atom索引 i:a中位置索引
            $('.atom:lt(4)').each(function (index, element) {
                var top = parseInt($(element).css('top'));
                var left = parseInt($(element).css('left'));
                for (var i = 0; i < 9; i++) {
                    if (top === a[i][0] && left === a[i][1]) {
                        c.push([index, i]);
                    }
                }
            })
            var b = new Array();
            //判断逆时针 还是顺时针旋转
            if (event.which === ccw) {
                b = [
                    6, 3, 0,
                    7, 4, 1,
                    8, 5, 2
                ];
            } else {
                //顺时针旋转九宫数组所对应的索引
                b = [
                    2, 5, 8,
                    1, 4, 7,
                    0, 3, 6
                ];
            }

            //变换后的九宫数组
            var d = new Array();
            for (var i = 0; i < 9; i++) {
                d[i] = a[b[i]]
            }

            //判断是否挨墙
            if (left === 0) {
                for (var i = 0; i < 4; i++) {
                    var index = c[i][0];
                    //var atoms = $('.atom:lt(4)');
                    $(atoms[index]).css({'top': d[c[i][1]][0], 'left': d[c[i][1]][1] + 22})
                }
            } else if (left === 242) {
                for (var i = 0; i < 4; i++) {
                    var index = c[i][0];
                    $(atoms[index]).css({'top': d[c[i][1]][0], 'left': d[c[i][1]][1] - 22})
                }
            } else {
                for (var i = 0; i < 4; i++) {
                    var index = c[i][0];
                    $(atoms[index]).css({'top': d[c[i][1]][0] + 'px', 'left': d[c[i][1]][1]})
                }
            }
        }
        //加速
        if (event.which === 40) {
            clearInterval(moveDown)
            move(1);
        }
    })

    //监听开始 开始后隐藏
    $('#start').click(function () {
        create();
        $(this).hide();
    })

    //创建元素
    function I() {
        let atoms = $('.atom:lt(4)');
        $(atoms[1]).css({top: '0px', 'left': "88px"});
        $(atoms[0]).css({top: '0px', 'left': "110px"});
        $(atoms[2]).css({top: '0px', 'left': "132px"});
        $(atoms[3]).css({top: '0px', 'left': "154px"});
        $('.atom:lt(4)').each(function () {
            $(this).attr('id', 'I');
        })
        judge(atoms);
    }

    function o() {
        let atoms = $('.atom:lt(4)');
        $(atoms[0]).css({top: '0px', 'left': "88px"});
        $(atoms[1]).css({top: '0px', 'left': "110px"});
        $(atoms[2]).css({top: '22px', 'left': "88px"});
        $(atoms[3]).css({top: '22px', 'left': "110px"});
        $('.atom:lt(4)').each(function () {
            $(this).attr('id', 'o');
        })
        judge(atoms);
    }

    function Z() {
        let atoms = $('.atom:lt(4)');
        $(atoms[2]).css({top: '0px', 'left': "88px"});
        $(atoms[1]).css({top: '0px', 'left': "110px"});
        $(atoms[0]).css({top: '22px', 'left': "110px"});
        $(atoms[3]).css({top: '22px', 'left': "132px"});
        judge(atoms);
    }

    function z() {
        let atoms = $('.atom:lt(4)');
        $(atoms[0]).css({top: '0px', 'left': "110px"});
        $(atoms[1]).css({top: '0px', 'left': "132px"});
        $(atoms[2]).css({top: '22px', 'left': "88px"});
        $(atoms[3]).css({top: '22px', 'left': "110px"});
        judge(atoms);
    }

    function L() {
        let atoms = $('.atom:lt(4)');
        $(atoms[2]).css({top: '0px', 'left': "132px"});
        $(atoms[1]).css({top: '22px', 'left': "88px"});
        $(atoms[0]).css({top: '22px', 'left': "110px"});
        $(atoms[3]).css({top: '22px', 'left': "132px"});
        judge(atoms);
    }

    function l() {
        let atoms = $('.atom:lt(4)');
        $(atoms[2]).css({top: '0px', 'left': "88px"});
        $(atoms[1]).css({top: '22px', 'left': "88px"});
        $(atoms[0]).css({top: '22px', 'left': "110px"});
        $(atoms[3]).css({top: '22px', 'left': "132px"});
        judge(atoms);
    }

    function T() {
        let atoms = $('.atom:lt(4)');
        $(atoms[2]).css({top: '0px', 'left': "110px"});
        $(atoms[1]).css({top: '22px', 'left': "88px"});
        $(atoms[0]).css({top: '22px', 'left': "110px"});
        $(atoms[3]).css({top: '22px', 'left': "132px"});
        judge(atoms);
    }


</script>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值