失败且未完成的俄罗斯方块

分析设计俄罗斯方块

1、分析

对俄罗斯方块的功能和行为进行分析

  1. 操作 1、左右移动方块 2、翻转方块 3、方块急速下降;
  2. 判断 1、方块可移动区域判断 2、消除判断;
  3. 功能块 1、移动方块的功能模块 2、关联小方块的功能对象 fObj 3、给对象 fObj 的 xLength、ySpeed 赋值的赋值模块;
  4. 步骤 1、创建地图,用二维数组来存储地图,地图存储数据; 1为有小方块占用,0为空意味着小方块可以移动至该位置;

2、具体步骤

1.写个快速创建元素的方法

$.createEle=function(params){
        var tagName=params.tagName||'div';
        var id=params.id||'';
        var className=params.className||'';
        var content=params.content||'';
        var css=params.css||{};
        var dom=document.createElement(tagName);
        if(id!=''){dom.id=id};
        if(className!=''){dom.className=className};
        if(content!=''){dom.innerHTML=content};
        for(var o in css){
            dom.style[o]=css[o];
        }
        return dom;
    };

2.创建地图渲染器

var mapCtrl = (function () {
        var map=[];
        var cellWidth=20;
        var fillMap = function (mapWidth,mapHeight) {
            // 创建地图
            for (var i = 0; i < mapHeight; i++) {
                var _row = [];
                for (var j = 0; j < mapWidth;j++) {
                    _row.push(0);
                };
                map.push(_row);
            };
        };
        var createMapDom=function(){
            var _width=cellWidth*map[0].length;
            var _height=cellWidth*map.length;
            var divBox=$.createEle({tagName:'div',className:'box-div',id:'mapBox',css:{width:_width+'px',height:_height+'px'}});
            for(var i=0,len=map.length;i<len;i++){
                var rowDiv=$.createEle({tagName:'div',className:'row-div',css:{position:'absolute',display:'flex',top:i*cellWidth+'px'}});
                for(var j=0,len1=map[0].length;j<len1;j++){
                    var cellDiv=$.createEle({tagName:'div',className:'cell cell-white',css:{width:cellWidth+'px',height:cellWidth+'px'}});
                    if(i==0){cellDiv.className=cellDiv.className+' cell-top' }
                    if(j==0){cellDiv.className=cellDiv.className+' cell-left' }
                    if(i==(len-1)){cellDiv.className=cellDiv.className+' cell-bottom' }
                    if(j==(len1-1)){cellDiv.className=cellDiv.className+' cell-right' }
                    rowDiv.appendChild(cellDiv);
                }
                divBox.appendChild(rowDiv);
            }
            document.body.appendChild(divBox);
        };
        var F={};
        F.init=function(){
            fillMap(12,18);
            createMapDom();
        };
        // 根据数组来重新渲染地图,改变地图的 className
        F.renderMap=function(){
            var rowCells=$('.box-div .row-div');
            for(var i=0,len1=map.length;i<len1;i++){
                for(var j=0,len2=map[0].length;j<len2;j++){
                    var cell=rowCells[i].childNodes[j];
                    if(map[i][j]==0){
                       if(cell.className.indexOf(' cell-select')!=-1){
                           cell.className=cell.className.replace(' cell-select','');
                       }
                    }else{
                        if(cell.className.indexOf(' cell-select')==-1){
                            cell.className=cell.className+' cell-select';
                        }
                    }
                }
            }
        };
        // 获取地图
        F.getMap=function(){
            return map;
        };
        // 检测位置是否存在俄罗斯方块
        F.checkState = function (cell) {
            for(var i=0,len=cell.length;i<len;i++){
                if (map[cell[i][0]-1][cell[i][1]-1] != 0) {
                    return false;
                }else{
                    return true;
                }
            }
        };
        // 检测点位
        F.checkSingleState=function(params){
            if(params.a>map.length||params.b>map[0].length){
                return false;
            }
            return map[params.a-1][params.b-1] == 0;
        }
        // 显示俄罗斯方块
        F.showCell=function(cell,status){
            for(var i=0,len=cell.length;i<len;i++){
                F.changeState({ a: cell[i][0], b: cell[i][1], status: status });
            }
        }

        // 改变地图的显示
        F.changeState=function(params){
            // map[a][b] 代表多少a行,b列   | status:1 有小方块; 0:无小方块
            map[(params.a - 1)][(params.b - 1)] = params.status;
        };
        // 再地图上创建一个新的俄罗斯方块
        F.receiveCell = function (cell) {
            // 步骤:1、接受cell 2、计算起始偏移位置,并将新的 cell 返回,如果超出,则返回 false,游戏结束
            var _dis = Math.floor((map[0].length - cell.length) / 2);
            for (var i = 0, len = cell.length; i < len; i++) {
                cell[i][1] += _dis;
            };
            if (F.checkState(cell)) {
                for (var i = 0, len = cell.length; i < len; i++) {
                    F.changeState({ a: cell[i][0], b: cell[i][1], status: 1 });
                };
                return cell;
            } else {
                return false;
            }
        };

        return F;
    })();
    mapCtrl.init();

3.创建一个控制俄罗斯方块下落、方向等操作的控制器

 var cellCtrl=(function(){
        var cell=[];
        // 方块形体集合
        var cells=[
            [[1,1],[1,2],[1,3],[1,4]]   // 长条 ----
            ,[[1,1],[1,2],[2,1],[2,2]]  // 方块 ==
            ,[[1,1],[2,1],[2,2],[2,3]]  // 左7 =_ _
            ,[[2,1],[2,2],[1,3],[2,3]]  // 右7 _ _= 
            ,[[1,1],[1,2],[2,2],[2,3]]   // -=_
            ,[[2,1],[1,2],[2,2],[1,3]]   // _=-
        ];
        

        var F={};
        F.random=function(){
            var index=Math.floor(Math.random()*6+1);
            for(var i=0,len=cells[(index-1)].length;i<len;i++){
                cell.push(cells[(index-1)][i]);
            }
            cell=mapCtrl.receiveCell(cell);
            if(!cell||cell==[]){
                alert('游戏结束');
            }
            mapCtrl.renderMap();
        }
        F.left = function () {
            var newCell = [];
            for(var i=0,len=cell.length;i<len;i++){
                var a=cell[i][0],b=cell[i][1]-1;
                var f=true;
                for(var j=0,len2=cell.length;j<len2;j++){
                    if(a==cell[j][0]&&b==cell[j][1]){
                        f=false;break;
                    }
                }
                if(f){
                    var obj={};obj.a=a;obj.b=b;
                    newCell.push(obj);
                }
            }
            var ff=true;
            for(var i=0,len=newCell.length;i<len;i++){
                if(!mapCtrl.checkSingleState(newCell[i])){
                    ff=false;
                    break;
                }
            }
            if(ff){
                mapCtrl.showCell(cell,0);
                for(var i=0,len=cell.length;i<len;i++){
                    cell[i][1]-=1;
                };
                mapCtrl.showCell(cell,1);
                mapCtrl.renderMap();
            }
        };
        F.right=function(){
            var newCell = [];
            for(var i=0,len=cell.length;i<len;i++){
                var a=cell[i][0],b=cell[i][1]+1;
                var f=true;
                for(var j=0,len2=cell.length;j<len2;j++){
                    if(a==cell[j][0]&&b==cell[j][1]){
                        f=false;break;
                    }
                }
                if(f){
                    var obj={};obj.a=a;obj.b=b;
                    newCell.push(obj);
                }
            }
            var ff=true;
            for(var i=0,len=newCell.length;i<len;i++){
                if(!mapCtrl.checkSingleState(newCell[i])){
                    ff=false;
                    break;
                }
            }
            if(ff){
                mapCtrl.showCell(cell,0);
                for(var i=0,len=cell.length;i<len;i++){
                    cell[i][1]+=1;
                };
                mapCtrl.showCell(cell,1);
                mapCtrl.renderMap();
            }
        };
        F.top = function () { };
        F.down = function () {
            if (F.isDown()) {
                mapCtrl.showCell(cell, 0);
                for (var i = 0, len = cell.length; i < len; i++) {
                    cell[i][0] += 1;
                };
                mapCtrl.showCell(cell, 1);
            }
            if (F.isDown()) {
                mapCtrl.showCell(cell, 0);
                for (var i = 0, len = cell.length; i < len; i++) {
                    cell[i][0] += 1;
                };
                mapCtrl.showCell(cell, 1);
            }
            mapCtrl.renderMap();
        };
        F.isDown=function(){
            var newCell = [];
            for(var i=0,len=cell.length;i<len;i++){
                var a=cell[i][0]+1,b=cell[i][1];
                var f=true;
                for(var j=0,len2=cell.length;j<len2;j++){
                    if(a==cell[j][0]&&b==cell[j][1]){
                        f=false;break;
                    }
                }
                if(f){
                    var obj={};obj.a=a;obj.b=b;
                    newCell.push(obj);
                }
            }
            var ff=true;
            for(var i=0,len=newCell.length;i<len;i++){
                if(!mapCtrl.checkSingleState(newCell[i])){
                    ff=false;
                    break;
                }
            }
            return ff;
        };
        F.init = function () {
            F.random();
            setInterval(function(){
                if (F.isDown()) {
                    mapCtrl.showCell(cell, 0);
                    for (var i = 0, len = cell.length; i < len; i++) {
                        cell[i][0] += 1;
                    };
                    mapCtrl.showCell(cell, 1);
                    mapCtrl.renderMap();
                }else{
                    F.random();
                }
            },500);
        }
        return F;
    })();

4.剩余的css,js,html

<style> 
    .box-div{
        border: 2px double #333;
        position: relative;
    }
    .cell{
        box-sizing: border-box;
    }
    .cell-white{
        /* border: 1px dotted #333; */
        border-right: 1px dotted #333;
        border-bottom: 1px dotted #333;
    }
    .cell-bottom{
        border-bottom: none;
    }
    .cell-top{
        border-top:none;
    }
    .cell-left{
        border-left: none;
    }
    .cell-right{
        border-right:none;
    }
    .cell-select{
        background: red;
        border: 1px solid #fff;
    }
    </style>
    <body>
    <div>
        <button id="start">开始</button>
        <button class="ctrl-btn" id="ctrlBtn1"></button>
        <button class="ctrl-btn" id="ctrlBtn2"></button>
        <button class="ctrl-btn" id="ctrlBtn3"></button>
        <button class="ctrl-btn" id="ctrlBtn4"></button>
    </div>
   <script src="../js/jquery-3.3.1.min.js"></script>
   <script>
    $('#start').click(function(){
        cellCtrl.random();
    });
    $('#ctrlBtn1').click(function(){
        cellCtrl.left();
    });
    $('#ctrlBtn2').click(function(){
        cellCtrl.right();
    });
    $('#ctrlBtn4').click(function(){
        cellCtrl.down();
    });
    
   </script>
   ...
   </body>

控制台输入:cellCtrl.init();进行调试。

3、现象

1、连续出现两次相同的方块直接游戏结束;
由于未使用对象的属性来存储方块的坐标,而是使用了数组存储的。导致了,数组坐标变化的时候,方块模板亦随着变化。
在这里插入图片描述

总结

1、使用数组存储坐标太容易出错了,尤其是我这种数组中的元素还是数组的情况。其值太容易在不经意间改变。
2、明天使用对象来记录值变化应该就可以完成俄罗斯方块
3、然后再比较网上的实现方法再总结下

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值