俄罗斯方块解析全过程

 

     以下是我过去做俄罗斯方块的全部思路,虽说每种语言实现的方式不一样,但是制作的思路是大体一样的

 

                                          俄罗斯方块的思路

界面的搭建:游戏区域  panel控件
   下一个方块的提示显示区域: panel 控件
   其他控件有button,label,textBox等等
游戏实现的主要步骤:
  方块的动态生成
  方块的移动
  方块的变化
  当每一行填满的时候方块的清除
  清除后方块的排列
方块动态生成的思路以及运用的知识点:
 PictureBox p=new PictureBox();//动态生成方块
 p.width=20;//设置方块的属性,对于其他方块必须的属性根据个人要求设置
 p.height=20;
 不同方块的生成:由小方块拼接而成

方块的移动:
 当方块的下一个移动区域为空的时候,可以容许方块向下移动,
 如果条件不成立,就停止方块移动

注意:没个方块的向下移动的情况都不相同,只需要根据每个方块的向下移动
 的可行区域进行判断,如果方块可以往下移动,就容许移动。


方块的左右移动
判断方块最的左边和右边的方块的座标+左右移动的位置(像素)
 y
 移动条件:如果移动的区域为空的时候,就移动方块,否则不移动方块

注意:左右移动的最大区域不可以超过游戏区域,可以根据不同的判断来限定方块越界的问题

方块的直接向下移动:
 只需要加快方块的移动速度就可以达到这个效果


方块的变化
 两种长方形的变化条件
  判断区域:变化范围=长方形的长*长方形的长的区域
   如果变化范围条件都为空的时候,就变化
 其它方块的变化条件:
  主要思路:判断要变化方块,变化后的区域是否为空,
     并且方块变化区域范围是否成立

 注意:方块变化时的条件,不要忘记如果方块已经停止移动的时候,方块就不再容许变化

判断方块如何为填满:
 可以根据不同的方法来限定:只需要判断当Y座标一行都为方块的时候,
    说明这一行方块已经填满,那么就可以清除这一行方块
 
 清除后的效果:
  清除这一行以上的方块的位置都需要往下移动一行,
  根据消除行数来判断向下移动的位置

 建议:可以将每一个小方块保存在List<>集合中,
  清除时候可以根据填满一行的下标和对象进行删除:

 对于游戏等级和游戏加分制度可以根据不同的需求来进行设置,

最后希望这个方案能给你带来思路,能给你带来帮助,祝愿能早日完成!

 


   

个人代码提供以及实现步骤:
               The First Point

 运用二维数组定义整个游戏界面,定义数组
 Int[,]  arr=new  int[21,12];
 界面赋值
For(int i=0;i<22;i++)
{
 For(int j=0;j<12;j++)
 {
  If( i==20 || j==0 || j==11)
   Arr[i,j]=-2;//代表障碍
  Else
   Arr[i,j]=-1;//代表空格
 }
}
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■□□□□□□□□■
■■■■■■■■■■
地图大小为200  *  400
  数组赋值后,值为-1的地方相对于地图界面的空白区域

    The Second Point

//动态生成方块(■■■■)
//定义方块集合
 list<PictureBox> ls=new list<PictureBox>();
 PictureBox  one =new pictureBox();
  One.width=20;
  One.height=20;
  One.image=imagelist.images[0];//给图片空间赋值图片
  One.location=new point(40,0);//给第一张图片定位
 PictureBox two=new pictureBox();
  Two.width=20;
  Two.height=20;
  Two.image=imagelist.images[0];
  Two.location=new point(60,0);
 pictureBox three =new pictureBox();
  three.widht=20;
  three.height=20;
  three.image=imagelist.images[0];
  three.location=new point(80,0);
 pictureBox four=new pictureBox();
  four.widht=20;
  four.height=20;
  four.image=imagelist.images[0];
  four.location=new point(100,0);
 //将四个设好的图片添加到游戏控件内
  This.panel.controls.add(one);
  This.panel.controls.add(two);
  This.panel.controls.add(three);               x  40
  This.panel.controls.add(four);                |      100
 //将方块添加到集合中                              |       |
  ls.add(one);                                       ■□□■■■■□□■ ——y  0
  ls.add(two);                                       ■□□□□□□□□■
  ls.add(three);                                     ■□□□□□□□□■
  ls.add(four);                                       ■□□□□□□□□■
                                                            ■□□□□□□□□■
                                                            ■□□□□□□□□■
   完成后大概图像                                ■□□□□□□□□■
  //定义变量记录方块下标                    ■□□□□□□□□■
                                                            ■□□□□□□□□■ __ y 380
                                                            ■■■■■■■■■■
  sumindex+=4;    
                 
 //方块的移动
   The Thrid Point
   //注意判断四个方块同等X座标移动的Y位置是否为空

  如:定义X和Y代表方块在panel中的座标值
 方块1    x=40, y=0;
 方块2    x=60,y=0;
 方块3    x=80,y=0;
 方块4    x=100,y=0;
  
   如果方块每移动一次,Y座标加20pX的话
四个方块的向下移动条件是
   每个方块同等X座标下Y+20的地方等于空
   二维数组中行和列所对应的就是panel中的X和Y座标
 只需判断数组中的相应位置来控件方块的移动
  移动后的图解

   ■□□□□□□□□■                       ■□□□□□□□□■   
   ■□□□□□□□□■                       ■□□□□□□□□■   
   ■□□□□□□□□■                       ■□□□□□□□□■   
   ■□□□□□□□□■                       ■□□□□□□□□■    
   ■□□□□□□□□■                       ■□□□□□□□□■  
   ■□□□□□□□□■赋值后index值■□□□□□□□□■    
   ■□□□□□□□□■                       ■□□□□□□□□■    
   ■□□□□□□□□■                       ■□□□□□□□□■  
   ■□□■■■■□□■ __y 380        ■□□ 0 1 2 3□□■   
   ■■■■■■■■■■                       ■■■■■■■■■■  
           
        
         |
         x 40

   arr[19,4]=indexsum-4;
   arr[19,5]=indexsum-3;
   arr[19,6]=indexsum-2;
   arr[19,7]=indexsum-1;
   
     The Fourth Point
左移动
   判断方块X座标减移动的20Px的地方是否为空,条件成立
  向左移动4个方块
 如图                      x
                                  | □■□ ------ y
                                □■■■□
   x=20;
   y=0;
   //如果两个白正方块的地方为空的时候,方块可以向左移动一格,x+20,y不变
    arr[1,1]=-1   对于的座标 x=0,y=20;
    arr[0,3]=-1             x=40,y=0;
      x
      |
      □■—y
    □■■■
 右则反之
                   x-1  x
变化            |  |                   x
                   □■□--y            |
           y+1--□■□               ■■■  ---y
                   □■■  变化后   ■

   The Fifth Point

 当一行填满的时候
   清除这一行方块
 
      for (int i =1; i <20; i++)   //判断是哪一行已经填满         ■□□□□□□□□■
                   {                                                                       ■□□□□□□□□■
                     string see="已满";                                          ■□□□□□□□□■
                   for (int j = 1; j < 11; j++)                                   ■■■■■■■■■■
                   {                                                                       ■□□□□□□□□■
                        if (arr[i, j] == -1)//判断是否有空格               ■□□■■■□■□■
                              {
                            see = "未满";
                            break;
                                  }
                           }
                        if (see == "已满")  //判断如果一行填满的时候
                        {               
                            int start = lp.Count;

                            for (int b = 1; b < 11; b++)//隐藏消除该行
                            {
                                   int index = arr[i, b];//得到消除方块在数组中的下标
                                   lp.RemoveAt(index);//从数组中移除方块
    this.panel.Controls.RamoveAt(index);//清除控件中的方块
                                for (int iy = 1; iy < 20; iy++)//消除后根据集合的动态维护进行相应的数组改变
                                 {
                                     for (int ix = 1; ix < 11; ix++)
                                      {
                                          if (GameHelp.Yarr[iy, ix] != -1 && GameHelp.Yarr[iy, ix] > index)
                                          {
                                              GameHelp.Yarr[iy, ix] = GameHelp.Yarr[iy, ix] - 1;
                                          }
                                      }
                                  }
                            }
//注动态维护
 {0,1,2,3,4,5,6,7}  删除 0 时候  1,2,3,4,5,6,7  index 为  0,1,2,3,4,5,6,

      删除为2的时候 0,1,3,4,5,6,7, index 0,1,2,3,4,5,6
` 1
                         indexsum-= 10;//由于集合动态维护,将indexsum-消除行控件的个数

                            for (int b = 1; b < 11; b++)//将隐藏方块的区域赋值为空
                                GameHelp.Yarr[i, b] = -1;//将数组中消除的区域赋值
                            int indexof = 0;
                           this.panel1.Controls.Clear();//清除游戏区域的控件,可以不清除
      x               
      |                 foreach (PictureBox pb in lp)//循环遍历整个集合,将集合中的控件重新确定位置
  ■□□□□□□□□■      {
  ■□□□□□□■□■         int lx = pb.Location.X;//获取方块的X座标
  ■□□□■□□□□■         int ly = pb.Location.Y;//获取方块的Y座标 
  ■□■□■□□□□■           if (ly < i*20 )//如果方块小于消除行的Y座标,将方块Y+20,往下移动
  ■□□□□□□□□■  —y      {
                                   ly += 20;
                                   pb.Location = new Point(lx, ly);       2
       ■2                         this.panel1.Controls.Add(pb);          3
       ■3                         int nexty=0;
                                   int nextx=0; 
     移动2的时候                if (indexof > 0)//当是数组中第二个方块的时候
       -1                         {
       2                             nexty = lp[indexof - 1].Location.Y;//获取上一个方块的XY座标
     移动3的时候                     nextx = lp[indexof - 1].Location.X;
       -1                        }
       2                         if (lx == nextx && ly == nexty + 20)//如果上一个方块和这一个方块X相同,并且Y相差20的话
       3                         {
                                     GameHelp.Yarr[ly / 20, lx / 20 + 1] = indexof;//将方块移动到的地方赋值为集合下标值
                                  }
     ■2                        else
                                 {
     □2  index -1                    GameHelp.Yarr[ly / 20, lx / 20 + 1] = indexof;//方块移动的地方赋值为集合下标值
     ■3        2                     GameHelp.Yarr[ly / 20 - 1, lx / 20 + 1] = -1;//方块的原始位置赋值为空
                                 }
     ■3 //集合中3             }
                             else  //消除方块一下的方块位置不变
     ■3  arr index 2         {
     □-1                          this.panel1.Controls.Add(pb);
     移动后                       GameHelp.Yarr[ly / 20, lx / 20 + 1] = indexof;
     ■2  arr index 2         }
     ■3  arr index 3          indexof = indexof + 1;//集合数组下标加
                       }
                        i -= 1;//判断向下移动一格后,需要I-1重新判断
                  }
              }

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章