通过h5的canvas手写一个俄罗斯方块小游戏

开始自己手写一个好玩的俄罗斯方块吧,上变形,左右移动,下加速,空格瞬移等功能,无聊的时候学习下canvas,f12 修改分数,体验金手指的快乐吧

通过h5的canvas手写一个俄罗斯方块小游戏_第1张图片

1、定义界面,和按钮

2、js部分

1、先定义每个图形的形状和变化的形状,这里是使用多维数组的方式去保存它图形每个方块的位置(当然这里也可以用循环的方式)

        var data=[[[[1,0,0,0],[1,0,0,0],[1,1,0,0],[0,0,0,0]],[[1,1,1,0],[1,0,0,0],[0,0,0,0],[0,0,0,0]],[[1,1,0,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]],[[0,0,1,0],[1,1,1,0],[0,0,0,0],[0,0,0,0]]],
                   [[[1,0,0,0],[1,1,0,0],[1,0,0,0],[0,0,0,0]],[[1,1,1,0],[0,1,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,1,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],[[0,0,0,0],[0,1,0,0],[1,1,1,0],[0,0,0,0]]],
                   [[[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],[[0,1,1,0],[1,1,0,0],[0,0,0,0],[0,0,0,0]],[[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,0,0]],[[0,0,0,0],[0,1,1,0],[1,1,0,0],[0,0,0,0]]],
                   [[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]]],
                   [[[0,0,1,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]],[[1,1,0,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]],[[0,0,1,0],[0,1,1,0],[0,1,0,0],[0,0,0,0]],[[1,1,0,0],[0,1,1,0],[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],[1,1,1,1],[0,0,0,0],[0,0,0,0]]],
                   [[[1,1,0,0],[1,0,0,0],[1,0,0,0],[0,0,0,0]],[[1,1,1,0],[0,0,1,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,1,0],[0,0,1,0],[0,1,1,0]],[[0,0,0,0],[0,0,0,0],[1,0,0,0],[1,1,1,0]]]
          ];

2、定义图形的位置和每帧下落的速度

        var newX=120;//记录这个图形的左右位置
        var count=0;   //记录下落的速度
        var shape=0; //记录形状
        var finallys=new Array(); //记录落下后停止的位置
        var re=6;   //获取随机数方块
        var fat=1;  //每帧的速度
        var xyg=0;  //下一个方块
        var dfen=0;//分数
           //定义游戏界面
        var c=document.getElementById("myCanvas");
        var ctx=c.getContext("2d");
        //下个方格的画布
        var c2=document.getElementById("Canvas");
        var ctx2=c2.getContext("2d");

3、定义组成图形的方法

        //组成图形的方法
          function constitute(){
              var Arr=new Array(); // 存储当前下来的方块位置
              var y=0;   //记录每个小方块组成图形的小方块y下标--相加
              for (var i=0;i

3、判断掉落是否到底或者碰撞到上一个底部的方块

          //掉落完成后重新调用
          function anew (arr){
              var da=bottom(arr); //调用判断是否到底
              if(da==1){  //如果返回1 则已经是到底部,
                  finallys.push(arr); // 保存在底部的方块,方便碰撞判断
                  count=0;  //恢复成原来的上下位置
                  newX=120;  //恢复原来的左右位置
                  re=xyg;     //当前的方块变成上一个的下一个
                  xyg=Math.floor(Math.random()*7);  //重新随机获取当前的下一个
                  ctx2.clearRect(0, 0, c.width,c.height);  //清除画布
                  xygs();//重新绘制预知框的
              }
          }
          
          
          
          //判断是否碰到下面的障碍物
          function bottom(arr){   //判断是否掉落底部//返回1表示可以保存起来
              for (var i =0;i=c.height-20){//首先判断是否到界面的底部
                      /*console.log(arr);*/
                      return 1;
                  }
                  for (var t=0;t

4、下落到底部后的方块要保存起来,定义重新渲染的方法

          //用来组成下标已经堆积的格子
          function  ground(finallys){
              deletes();//判断是否到达顶部了, 顶部了就直接清除重新开始
              for (var i=0;i

5、当横向一行满了后就可以清楚并得到对应的分数

      //判断是否组满一行达到清除的位置
      function deletes(){
        var c=600;//当前横向的宽度
        var add=new Array;//记录宽度的每个方块
        for (var i=0;i=20){ //如果横向满了调用清除的方法
                qc(add[a]);//
                cou=0;
            }
        }
    }
      //一行满了后清除和上面的向下增加移动
      function qc(add){
          for (var t=0;t

6、碰撞检测

          //判断不能掉出围起来的范围
          function crash(count,e){ //count 下落的位置, e 表示当前是什么按钮操作
              var newCount=0;  //判断是否有下降的数据有就下降
              if(count!=0){
                  newCount=count;
              }
              var y=0;   //记录组成形状的位置--相加
              var r=0;
              var make=-1;
              for (var i=0;ic.width-20){
                              if(x+newX<0){
                                  newX=newX+20;
                                  r=1;
                              }else{
                                  newX=newX-20;
                                  r=2;
                              }
                          }
                          if(e==38){
                              if(y+count>c.height-20){
                                  if(shape!=0){
                                    shape=shape-1;
                                }else{
                                    shape=3;
                                }
                              }
                          }
                          
                          ////防止突出右边
                          if(e==39&&c.width-20c.height-20){
                              count=count-20;
                          }
                          var ys=(y+count)%20; //下落的时候可能会一直按着 速度快会直接插到下面,所以这里要求余,当到这个方块的位置的时候取整判断
                          var es=20-ys;
                          var newCount=y+count+es;
                          
                          for (var t=0;t

7、按钮操作

        $(document).keydown(function(e){  //电脑键盘的
            if(e.keyCode==39){  //右
                crash(count,e.keyCode);//判断是否可以加到右边
            }else if(e.keyCode==37){  //左
                //判断是否可以加到左边
                crash(count,e.keyCode);
            }else if(e.keyCode==40){   //下
                var i=count%10;
                count=count-i;
                fat=10;
                
            }else if(e.keyCode==38){   //上
               shape++;
               if(shape>3){
                   shape=0;
               }
               crash(count,e.keyCode);  //防止变形溢出
            }else if(e.keyCode==32){
                var i=count%20;
                count=count-i;
                for (var t=0;t<400;t++) {
                    count=count+10;
                    var arr=constitute();
                    var e=bottom(arr);
                    if(e==1){
                        break;
                    }
                }
            }
        });
        //////////////////////////// 手机端的按钮
        function under(){
              var i=count%10;
            count=count-i;
            fat=10;
            setTimeout(function(){
                fat=1;
            },100)
          }
          document.onkeyup=function(){
            fat=1;
        }
          function tops(){
             shape++;
           if(shape>3){
               shape=0;
           }
           crash(count,38);  //防止变形溢出
          }
          function lefts(){
              //判断是否可以加到左边
            crash(count,37);
          }
          function rights(){
              crash(count,39);//判断是否可以加到右边
          }

8、定义绘制预知框的方法,如上面绘制的方法一样,只是对应的canvas不同

          //预知框里面的绘制
          function xygs(){
              var y=0;   //记录组成形状的位置--相加
              for (var i=0;i

9、开始运行的方法

      function  dy(){
            ctx.clearRect(0, 0, c.width,c.height);  //清除画布
            constitute();   //调用组成画布的方法
            count=count+fat;   // 下落的速度
            ground(finallys);    //调用已经在底部的方块的方法
            ctx.font="20px 微软雅黑";
            ctx.fillText("得分:"+dfen+"",20,30);
            requestAnimationFrame(dy);   //调用循环运行
        }
        requestAnimationFrame(dy);  //开始运行每一帧
        
        if(finallys.length==0){ //获取第一个预知框
            xyg=Math.floor(Math.random()*7);//随机获取
            xygs();//调用预知框的渲染
        }
        constitute()//开始绘制

你可能感兴趣的:(javascript,前端,css,html5)