|
|
|
|
公众号矩阵

鸿蒙手机经典小游戏-俄罗斯方块

为了更好地熟练掌握鸿蒙手机应用开发,深鸿会深大学习小组将带来一款经典的鸿蒙手机小游戏——俄罗斯方块,此前更多精彩分享欢迎关注荔园Harmony基地。自研了俄罗斯方块的算法,详细讲述了俄罗斯方块在鸿蒙手机上的开发思路,内含详细注释。

作者:张诏添来源:鸿蒙社区|2021-01-12 12:16

想了解更多内容,请访问:

51CTO和华为官方战略合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

前言

为了更好地熟练掌握鸿蒙手机应用开发,深鸿会深大学习小组将带来一款经典的鸿蒙手机小游戏——俄罗斯方块,此前更多精彩分享欢迎关注荔园Harmony基地。自研了俄罗斯方块的算法,详细讲述了俄罗斯方块在鸿蒙手机上的开发思路,内含详细注释。深鸿会深大学习小组是一群热衷于学习鸿蒙相关知识和开发鸿蒙相关应用的开发者们,我们的学习项目为:荔园Harmony,同时也欢迎与各位感兴趣的开发者一起学习HarmonyOS开发,相互交流、共同进步。

概述

本个demo将从零基础开始完成鸿蒙小游戏APP在手机上的编译在项目中我们所使用到的软件为DevEco Studio,下载地址为:DevEco Studio下载、DevEco Studio安装教程,在项目中我们要实现的内容为俄罗斯方块APP的开发。

1. 运行应用时每次均会随机生成一种方块,点击“←”方块将会向左移动一格,点击“→”方块将会向右移动一格,点击“变”将会切换成该方块的其他形状。


2. 当有任一行全部填满方块时该行便会消除,该行上述的所有方块均会向下移动一格。


3. 当无法产生新的方块时便会显示游戏结束,点击“重新开始”便可以重新开始游戏。


正文

创建项目

DevEco Studio下载安装成功后,打开DevEco Studio,点击左上角的File,点击New,再选择New Project,选择Phone选项,选择默认的模板(java版),然后选择保存路径,将文件命名为MyPhoneGame2(文件名不能出现中文或者特殊字符,否则将无法成功创建项目文件),最后点击Finish。



准备工作

在entry>src>main>config.json文件中最下方"launchType": "standard"的后面添加以下代码,这样就可以实现去掉应用上方的标签栏了,并且将上方的“label”:“MyPhoneGame2”修改成"label": "俄罗斯方块",这样就可以实现将应用名称修改为俄罗斯方块了。

config.json最下面部分代码:

  1. "icon""$media:icon"
  2.      "description""$string:mainability_description"
  3.      "label""俄罗斯方块"
  4.      "type""page"
  5.      "launchType""standard"
  6.      "metaData": { 
  7.        "customizeData": [ 
  8.          { 
  9.            "name""hwc-theme"
  10.            "value""androidhwext:style/Theme.Emui.Light.NoTitleBar"
  11.            "extra""" 
  12.          } 
  13.        ] 
  14.      } 

绘制基础组件

首先我们要绘制一个15*10的方阵和“←”按钮、“→”按钮、“变”按钮、“重新开始”按钮。


在entry>src>main>java>com.example.myphoneapplication>slice>MainAbilitySlice编写代码。

先定义方格的边长length为常量100,方格的间距interval为常量2,再定义一个位置布局layout和一个表示方格颜色的二维数组grids,创建函数initializeinitialize()分别对其初始化,布局layout初始化为线性布局DirectionalLayout,二维数组grids全部赋值为0,在onStart函数中调用函数initializeinitialize()。

  1. public class MainAbilitySlice extends AbilitySlice { 
  2.     private DirectionalLayout layout; 
  3.     private static final int length=100; 
  4.     private static final int interval=2; 
  5.     private int[][] grids; 
  6.     public void onStart(Intent intent) { 
  7.         super.onStart(intent); 
  8.  
  9.         initialize(); 
  10.     } 
  11.  
  12.     public void initialize(){ 
  13.         layout = new DirectionalLayout(this); 
  14.         grids = new int[15][10]; 
  15.         for(int row = 0; row < 15; row++) 
  16.             for(int column = 0; column < 10; column++) 
  17.                 grids[row][column] = 0; 
  18.     } 

然后创建函数drawGrids(int[][] grids)用于绘制15*10的方阵,因为有七种颜色的方块,所以分别用0到7代表一种颜色。

  1. public void drawGrids(){ 
  2.         layout.setLayoutConfig((new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,ComponentContainer.LayoutConfig.MATCH_PARENT))); 
  3.  
  4.         Component.DrawTask task=new Component.DrawTask() { 
  5.             @Override 
  6.             public void onDraw(Component component, Canvas canvas) { 
  7.                 Paint paint = new Paint(); 
  8.  
  9.                 paint.setColor(Color.BLACK); 
  10.                 RectFloat rect=new RectFloat(30-20,250-20,length*10+interval*9+30+20,length*15+interval*14+250+20); 
  11.                 canvas.drawRect(rect,paint); 
  12.  
  13.                 for(int row = 0; row < 15; row++){//0表示灰色,1代表红色,2代表绿色,3代表蓝绿色,4代表品红色,5代表蓝色,6代表白色,7代表黄色 
  14.                     for(int column = 0; column < 10; column++){ 
  15.                         if(grids[row][column] == 0) 
  16.                             paint.setColor(Color.GRAY); 
  17.                         else if(grids[row][column] == 1) 
  18.                             paint.setColor(Color.RED); 
  19.                         else if(grids[row][column] == 2) 
  20.                             paint.setColor(Color.GREEN); 
  21.                         else if(grids[row][column] == 3) 
  22.                             paint.setColor(Color.CYAN); 
  23.                         else if(grids[row][column] == 4) 
  24.                             paint.setColor(Color.MAGENTA); 
  25.                         else if(grids[row][column] == 5) 
  26.                             paint.setColor(Color.BLUE); 
  27.                         else if(grids[row][column] == 6) 
  28.                             paint.setColor(Color.WHITE); 
  29.                         else if(grids[row][column] == 7) 
  30.                             paint.setColor(Color.YELLOW); 
  31.                         RectFloat rectFloat=new RectFloat(30+column*(length+interval),250+row*(length+interval),30+length+column*(length+interval),250+length+row*(length+interval)); 
  32.                         canvas.drawRect(rectFloat,paint); 
  33.                     } 
  34.                 } 
  35.             } 
  36.         }; 
  37.  
  38.         layout.addDrawTask(task); 
  39.         setUIContent(layout); 
  40.     } 

然后创建函数drawButton()用于绘制四个按钮。

  1. public void drawButton(){ 
  2.         ShapeElement background = new ShapeElement(); 
  3.         background.setRgbColor(new RgbColor(174, 158, 143)); 
  4.         background.setCornerRadius(100); 
  5.  
  6.         Button button1 = new Button(this); 
  7.         button1.setText("←"); 
  8.         button1.setTextAlignment(TextAlignment.CENTER); 
  9.         button1.setTextColor(Color.WHITE); 
  10.         button1.setTextSize(100); 
  11.         button1.setMarginTop(1800); 
  12.         button1.setMarginLeft(160); 
  13.         button1.setPadding(10,0,10,0); 
  14.         button1.setBackground(background); 
  15.         button1.setClickedListener(new Component.ClickedListener() { 
  16.             @Override 
  17.             public void onClick(Component component) { 
  18.                 leftShift(); 
  19.             } 
  20.         }); 
  21.         layout.addComponent(button1); 
  22.  
  23.         Button button2 = new Button(this); 
  24.         button2.setText("变"); 
  25.         button2.setTextAlignment(TextAlignment.CENTER); 
  26.         button2.setTextColor(Color.WHITE); 
  27.         button2.setTextSize(100); 
  28.         button2.setMarginLeft(480); 
  29.         button2.setMarginTop(-130); 
  30.         button2.setPadding(10,0,10,0); 
  31.         button2.setBackground(background); 
  32.         button2.setClickedListener(new Component.ClickedListener() { 
  33.             @Override 
  34.             public void onClick(Component component) { 
  35.                 changGrids(); 
  36.             } 
  37.         }); 
  38.         layout.addComponent(button2); 
  39.  
  40.         Button button3 = new Button(this); 
  41.         button3.setText("→"); 
  42.         button3.setTextAlignment(TextAlignment.CENTER); 
  43.         button3.setTextColor(Color.WHITE); 
  44.         button3.setTextSize(100); 
  45.         button3.setMarginLeft(780); 
  46.         button3.setMarginTop(-130); 
  47.         button3.setPadding(10,0,10,0); 
  48.         button3.setBackground(background); 
  49.         button3.setClickedListener(new Component.ClickedListener() { 
  50.             @Override 
  51.             public void onClick(Component component) { 
  52.                 rightShift(); 
  53.             } 
  54.         }); 
  55.         layout.addComponent(button3); 
  56.  
  57.         Button button = new Button(this); 
  58.         button.setText("重新开始"); 
  59.         button.setTextSize(100); 
  60.         button.setTextAlignment(TextAlignment.CENTER); 
  61.         button.setTextColor(Color.WHITE); 
  62.         button.setMarginTop(5); 
  63.         button.setMarginLeft(310); 
  64.         button.setPadding(10,10,10,10); 
  65.         button.setBackground(background); 
  66.         button.setClickedListener(new Component.ClickedListener() { 
  67.             @Override 
  68.             public void onClick(Component component) { 
  69.                 initialize(); 
  70.             } 
  71.         }); 
  72.         layout.addComponent(button); 
  73.     } 

最后在initialize()函数中调用drawButton()函数和drawGrids()函数。

  1. public void initialize(){//部分代码没有贴出,欢迎自行下载附件查看源代码 
  2.         drawButton(); 
  3.         drawGrids(); 
  4.     } 

随机产生方块

然后我们要实现随机产生一种形状的方块。


首先说明一下本人研究出来表示不同方块的算法:用一个常量二维数组去存储不同颜色的不同形状的方块所在的位置,如{{0,3},{0,4},{1,4},{1,5}}中的{0,3}就表示该方块的第一个方格在grids[0][3]的位置,{0,4}就表示该方块的第二个方格在grids[0][4的]位置,以此类推,这样连起来就可以得到一种颜色的一种形状的方块了。

然后先定义各种表示方块的常量二维数组,定义方块所占方格的数量grids_number为常量4,二维数组NowGrids表示当前方块的形状,row_number表示方块的总行数,column_number表示方块的总列数,Grids表示方块的颜色,column_start表示方块第一个方格所在二维数组grids的列数。

  1. private static final int[][] RedGrids1={{0,3},{0,4},{1,4},{1,5}}; 
  2. private static final int[][] RedGrids2={{0,5},{1,5},{1,4},{2,4}}; 
  3. private static final int[][] GreenGrids1={{0,5},{0,4},{1,4},{1,3}}; 
  4. private static final int[][] GreenGrids2={{0,4},{1,4},{1,5},{2,5}}; 
  5. private static final int[][] CyanGrids1={{0,4},{1,4},{2,4},{3,4}}; 
  6. private static final int[][] CyanGrids2={{0,3},{0,4},{0,5},{0,6}}; 
  7. private static final int[][] MagentaGrids1={{0,4},{1,3},{1,4},{1,5}}; 
  8. private static final int[][] MagentaGrids2={{0,4},{1,4},{1,5},{2,4}}; 
  9. private static final int[][] MagentaGrids3={{0,3},{0,4},{0,5},{1,4}}; 
  10. private static final int[][] MagentaGrids4={{0,5},{1,5},{1,4},{2,5}}; 
  11. private static final int[][] BlueGrids1={{0,3},{1,3},{1,4},{1,5}}; 
  12. private static final int[][] BlueGrids2={{0,5},{0,4},{1,4},{2,4}}; 
  13. private static final int[][] BlueGrids3={{0,3},{0,4},{0,5},{1,5}}; 
  14. private static final int[][] BlueGrids4={{0,5},{1,5},{2,5},{2,4}}; 
  15. private static final int[][] WhiteGrids1={{0,5},{1,5},{1,4},{1,3}}; 
  16. private static final int[][] WhiteGrids2={{0,4},{1,4},{2,4},{2,5}}; 
  17. private static final int[][] WhiteGrids3={{0,5},{0,4},{0,3},{1,3}}; 
  18. private static final int[][] WhiteGrids4={{0,4},{0,5},{1,5},{2,5}}; 
  19. private static final int[][] YellowGrids={{0,4},{0,5},{1,5},{1,4}}; 
  20. private static final int grids_number=4; 
  21. private int[][] NowGrids; 
  22. private int row_number; 
  23. private int column_number; 
  24. private int Grids; 
  25. private int column_start; 

创建函数“create+Color+Grids”为各种颜色各种形状的方块赋予对应的NowGrids、row_number、column_numbr、Grids、column_start的值。

  1. public void createRedGrids1(){ 
  2.      NowGrids=RedGrids1; 
  3.      row_number=2; 
  4.      column_number=3; 
  5.      Grids=1; 
  6.      column_start=3; 
  7.  } 
  8.  
  9.  public void createRedGrids2(){ 
  10.      NowGrids=RedGrids2; 
  11.      row_number=3; 
  12.      column_number=2; 
  13.      Grids=1; 
  14.      column_start=4; 
  15.  } 
  16.  
  17.  public void createGreenGrids1(){ 
  18.      NowGrids=GreenGrids1; 
  19.      row_number=2; 
  20.      column_number=3; 
  21.      Grids=2; 
  22.      column_start=3; 
  23.  } 
  24.  
  25.  public void createGreenGrids2(){ 
  26.      NowGrids=GreenGrids2; 
  27.      row_number=3; 
  28.      column_number=2; 
  29.      Grids=2; 
  30.      column_start=4; 
  31.  } 
  32.  
  33.  public void createCyanGrids1(){ 
  34.      NowGrids=CyanGrids1; 
  35.      row_number=4; 
  36.      column_number=1; 
  37.      Grids=3; 
  38.      column_start=4; 
  39.  } 
  40.  
  41.  public void createCyanGrids2(){ 
  42.      NowGrids=CyanGrids2; 
  43.      row_number=1; 
  44.      column_number=4; 
  45.      Grids=3; 
  46.      column_start=3; 
  47.  } 
  48.  
  49.  public void createMagentaGrids1(){ 
  50.      NowGrids=MagentaGrids1; 
  51.      row_number=2; 
  52.      column_number=3; 
  53.      Grids=4; 
  54.      column_start=3; 
  55.  } 
  56.  
  57.  public void createMagentaGrids2(){ 
  58.      NowGrids=MagentaGrids2; 
  59.      row_number=3; 
  60.      column_number=2; 
  61.      Grids=4; 
  62.      column_start=4; 
  63.  } 
  64.  
  65.  public void createMagentaGrids3(){ 
  66.      NowGrids=MagentaGrids3; 
  67.      row_number=2; 
  68.      column_number=3; 
  69.      Grids=4; 
  70.      column_start=3; 
  71.  } 
  72.  
  73.  public void createMagentaGrids4(){ 
  74.      NowGrids=MagentaGrids4; 
  75.      row_number=3; 
  76.      column_number=2; 
  77.      Grids=4; 
  78.      column_start=4; 
  79.  } 
  80.  
  81.  public void createBlueGrids1(){ 
  82.      NowGrids=BlueGrids1; 
  83.      row_number=2; 
  84.      column_number=3; 
  85.      Grids=5; 
  86.      column_start=3; 
  87.  } 
  88.  
  89.  public void createBlueGrids2(){ 
  90.      NowGrids=BlueGrids2; 
  91.      row_number=3; 
  92.      column_number=2; 
  93.      Grids=5; 
  94.      column_start=4; 
  95.  } 
  96.  
  97.  public void createBlueGrids3(){ 
  98.      NowGrids=BlueGrids3; 
  99.      row_number=2; 
  100.      column_number=3; 
  101.      Grids=5; 
  102.      column_start=3; 
  103.  } 
  104.  
  105.  public void createBlueGrids4(){ 
  106.      NowGrids=BlueGrids4; 
  107.      row_number=3; 
  108.      column_number=2; 
  109.      Grids=5; 
  110.      column_start=4; 
  111.  } 
  112.  
  113.  public void createWhiteGrids1(){ 
  114.      NowGrids=WhiteGrids1; 
  115.      row_number=2; 
  116.      column_number=3; 
  117.      Grids=6; 
  118.      column_start=3; 
  119.  } 
  120.  
  121.  public void createWhiteGrids2(){ 
  122.      NowGrids=WhiteGrids2; 
  123.      row_number=3; 
  124.      column_number=2; 
  125.      Grids=6; 
  126.      column_start=4; 
  127.  } 
  128.  
  129.  public void createWhiteGrids3(){ 
  130.      NowGrids=WhiteGrids3; 
  131.      row_number=2; 
  132.      column_number=3; 
  133.      Grids=6; 
  134.      column_start=3; 
  135.  } 
  136.  
  137.  public void createWhiteGrids4(){ 
  138.      NowGrids=WhiteGrids4; 
  139.      row_number=3; 
  140.      column_number=2; 
  141.      Grids=6; 
  142.      column_start=4; 
  143.  } 
  144.  
  145.  public void createYellowGrids(){ 
  146.      NowGrids=YellowGrids; 
  147.      row_number=2; 
  148.      column_number=2; 
  149.      Grids=7; 
  150.      column_start=4; 
  151.  } 

再创建函数createGrids()随机调用上述函数,再将存储不同颜色的不同形状的方块所在的位置赋予对应的Grids值。

  1. public void createGrids(){ 
  2.         double random = Math.random(); 
  3.         if(random >= 0 && random < 0.2){ 
  4.             if(random >= 0 && random < 0.1) 
  5.                 createRedGrids1(); 
  6.             else 
  7.                 createRedGrids2(); 
  8.         } 
  9.         else if(random >= 0.2 && random < 0.4){ 
  10.             if(random >= 0.2 && random < 0.3) 
  11.                 createGreenGrids1(); 
  12.             else 
  13.                 createGreenGrids2(); 
  14.         } 
  15.         else if(random >= 0.4 && random < 0.45){ 
  16.             if(random >= 0.4 &&random < 0.43) 
  17.                 createCyanGrids1(); 
  18.             else 
  19.                 createCyanGrids2(); 
  20.         } 
  21.         else if(random >= 0.45 && random < 0.6){ 
  22.             if(random >= 0.45 && random < 0.48) 
  23.                 createMagentaGrids1(); 
  24.             else if(random >= 0.48 && random < 0.52) 
  25.                 createMagentaGrids2(); 
  26.             else if(random >= 0.52 && random < 0.56) 
  27.                 createMagentaGrids3(); 
  28.             else 
  29.                 createMagentaGrids4(); 
  30.         } 
  31.         else if(random >= 0.6 && random < 0.75){ 
  32.             if(random >= 0.6 && random < 0.63) 
  33.                 createBlueGrids1(); 
  34.             else if(random >= 0.63 && random < 0.67) 
  35.                 createBlueGrids2(); 
  36.             else if(random >= 0.67 && random < 0.71) 
  37.                 createBlueGrids3(); 
  38.             else 
  39.                 createBlueGrids4(); 
  40.         } 
  41.         else if(random >= 0.75 && random < 0.9){ 
  42.             if(random >= 0.75 && random < 0.78) 
  43.                 createWhiteGrids1(); 
  44.             else if(random >=0.78 && random < 0.82) 
  45.                 createWhiteGrids2(); 
  46.             else if(random >=0.82 && random < 0.86) 
  47.                 createWhiteGrids3(); 
  48.             else 
  49.                 createWhiteGrids4(); 
  50.         } 
  51.         else { 
  52.             createYellowGrids(); 
  53.         } 
  54.  
  55.         for(int row = 0; row < grids_number; row++){ 
  56.                 grids[NowGrids[row][0]][NowGrids[row][1]] = Grids; 
  57.         } 
  58.     } 

最后在initialize()函数中调用createGrids()函数。

  1. public void initialize(){//部分代码没有贴出,欢迎自行下载附件查看源代码 
  2.         createGrids(); 
  3.         drawButton(); 
  4.         drawGrids(); 
  5.     } 

方块自动下落

然后我们还要实现方块能自动向下移动并且能再次产生一种形状的方块。


首先定义一个时间变量timer,再定义当前下落的行数Nowrow,当前左右移动的列数Nowcolumn,在函数createGrids()中对Nowrow和Nowcolumn赋值为0。

  1. private int Nowrow; 
  2.     private int Nowcolumn; 
  3.     private Timer timer; 
  4.  
  5.     public void createGrids(){//部分代码没有贴出,欢迎自行下载附件查看源代码 
  6.             Nowcolumn = 0; 
  7.             Nowrow = 0; 
  8.     } 

然后创建函数down()判断方块能否再次下移,判断方法为当方块下移到下边界时或方块下方有其他方块时,则不能继续下移了,返回false,否则返回true。

  1. public boolean down(){ 
  2.         boolean k; 
  3.         if(Nowrow + row_number == 15){ 
  4.             return false
  5.         } 
  6.  
  7.         for(int row = 0; row < grids_number; row++){ 
  8.             k = true
  9.             for(int i = 0; i < grids_number; i++){ 
  10.                 if(NowGrids[row][0] + 1 == NowGrids[i][0] && NowGrids[row][1] == NowGrids[i][1]){ 
  11.                     k = false
  12.                 } 
  13.             } 
  14.             if(k){ 
  15.                 if(grids[NowGrids[row][0] + Nowrow + 1][NowGrids[row][1] + Nowcolumn] != 0) 
  16.                     return false
  17.             } 
  18.         } 
  19.  
  20.         return true
  21.     } 

再创建函数run(),初始化timer,增加时间事件,判断当方块能继续下移时则清除当前方块,Nowrow加1,再在下一格的位置绘制刚才的方块,实现方块的下移,当方块不能下移时则产生新的方块。

  1. public void run(){ 
  2.         timer=new Timer(); 
  3.         timer.schedule(new TimerTask() { 
  4.             @Override 
  5.             public void run() { 
  6.                 getUITaskDispatcher().asyncDispatch(()->{ 
  7.                     if(down()){ 
  8.                         for(int row = 0; row < grids_number; row++){ 
  9.                             grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = 0; 
  10.                         } 
  11.                         Nowrow++; 
  12.                         for(int row = 0; row < grids_number; row++){ 
  13.                             grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = Grids; 
  14.                         } 
  15.                     } 
  16.                     else
  17.                         createGrids(); 
  18.                     } 
  19.                     drawGrids(); 
  20.                 }); 
  21.             } 
  22.         },0,750); 
  23.     } 

最后在函数onStart(Intent intent)中调用函数run()。

  1. public void onStart(Intent intent) {//部分代码没有贴出,欢迎自行下载附件查看源代码 
  2.         initialize(); 
  3.         run(); 
  4.     } 

方块左右移动

点击“←”方块将会向左移动一格,点击“→”方块将会向右移动一格。


首先创建函数left()判断方块能否再次左移,判断方法为当方块左移到左边界时或方块左方有其他方块时,则不能继续左移了,返回false,否则返回true。

  1. public boolean left(){ 
  2.         boolean k; 
  3.         if(Nowcolumn + column_start == 0){ 
  4.             return false
  5.         } 
  6.  
  7.         for(int column = 0; column < grids_number; column++){ 
  8.             k = true
  9.             for(int j = 0; j < grids_number; j++){ 
  10.                 if(NowGrids[column][0] == NowGrids[j][0] && NowGrids[column][1] - 1 == NowGrids[j][1]){ 
  11.                     k = false
  12.                 } 
  13.             } 
  14.             if(k){ 
  15.                 if(grids[NowGrids[column][0] + Nowrow][NowGrids[column][1] + Nowcolumn - 1] != 0) 
  16.                     return false
  17.             } 
  18.         } 
  19.  
  20.         return true
  21.     } 

然后创建函数leftShift(),判断当方块能继续左移时则清除当前方块,Nowcolumn减1,再在左一格的位置绘制刚才的方块,实现方块的左移。

  1. public void leftShift(){ 
  2.         if(left()){ 
  3.             for(int row = 0; row < grids_number; row++){ 
  4.                 grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = 0; 
  5.             } 
  6.             Nowcolumn--; 
  7.             for(int row = 0; row < grids_number; row++){ 
  8.                 grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = Grids; 
  9.             } 
  10.         } 
  11.         drawGrids(); 
  12.     } 

方块的右移与左移类似,就不过多叙述了,直接上代码:

  1. public void rightShift(){ 
  2.         if(right()){ 
  3.             for(int row = 0; row < grids_number; row++){ 
  4.                 grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = 0; 
  5.             } 
  6.             Nowcolumn++; 
  7.             for(int row = 0; row < grids_number; row++){ 
  8.                 grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = Grids; 
  9.             } 
  10.         } 
  11.         drawGrids(); 
  12.     } 
  13.  
  14.     public boolean right(){ 
  15.         boolean k; 
  16.         if(Nowcolumn + column_number + column_start==10){ 
  17.             return false
  18.         } 
  19.  
  20.         for(int column = 0; column < grids_number; column++){ 
  21.             k = true
  22.             for(int j = 0; j < grids_number; j++){ 
  23.                 if(NowGrids[column][0] == NowGrids[j][0] && NowGrids[column][1] + 1 == NowGrids[j][1]){ 
  24.                     k = false
  25.                 } 
  26.             } 
  27.             if(k){ 
  28.                 if(grids[NowGrids[column][0] + Nowrow][NowGrids[column][1] + Nowcolumn + 1] != 0) 
  29.                     return false
  30.             } 
  31.         } 
  32.  
  33.         return true
  34.     } 

最后在函数drawButton()中的"←"按钮和"→"按钮增加点击事件,分别调用上述的函数。

  1. public void drawButton(){//绘制按钮 
  2.       button1.setClickedListener(new Component.ClickedListener() { 
  3.           @Override 
  4.           public void onClick(Component component) { 
  5.               leftShift(); 
  6.           } 
  7.       }); 
  8.  
  9.       button3.setClickedListener(new Component.ClickedListener() { 
  10.           @Override 
  11.           public void onClick(Component component) { 
  12.               rightShift(); 
  13.           } 
  14.       }); 
  15.   } 

改变方块形状

点击“变”将会切换成该方块的其他形状。


首先创建函数"chang+Color+Grids"用于调用新方块的"create+Color+Grids"函数,实现在同一种颜色的方块中变换到其他形状的方块。

  1. public void changRedGrids(){ 
  2.      if(NowGrids==RedGrids1){ 
  3.          createRedGrids2(); 
  4.      } 
  5.      else if(NowGrids==RedGrids2){ 
  6.          createRedGrids1(); 
  7.      } 
  8.  } 
  9.  
  10.  public void changeGreenGrids(){ 
  11.      if(NowGrids==GreenGrids1){ 
  12.          createGreenGrids2(); 
  13.      } 
  14.      else if(NowGrids==GreenGrids2){ 
  15.          createGreenGrids1(); 
  16.      } 
  17.  } 
  18.  
  19.  public void changeCyanGrids(){ 
  20.      if(NowGrids==CyanGrids1){ 
  21.          createCyanGrids2(); 
  22.      } 
  23.      else if(NowGrids==CyanGrids2){ 
  24.          createCyanGrids1(); 
  25.      } 
  26.  } 
  27.  
  28.  public void changeMagentaGrids(){ 
  29.      if(NowGrids==MagentaGrids1){ 
  30.          createMagentaGrids2(); 
  31.      } 
  32.      else if(NowGrids==MagentaGrids2){ 
  33.          createMagentaGrids3(); 
  34.      } 
  35.      else if(NowGrids==MagentaGrids3){ 
  36.          createMagentaGrids4(); 
  37.      } 
  38.      else if(NowGrids==MagentaGrids4){ 
  39.          createMagentaGrids1(); 
  40.      } 
  41.  } 
  42.  
  43.  public void changeBlueGrids(){ 
  44.      if(NowGrids==BlueGrids1){ 
  45.          createBlueGrids2(); 
  46.      } 
  47.      else if(NowGrids==BlueGrids2){ 
  48.          createBlueGrids3(); 
  49.      } 
  50.      else if(NowGrids==BlueGrids3){ 
  51.          createBlueGrids4(); 
  52.      } 
  53.      else if(NowGrids==BlueGrids4){ 
  54.          createBlueGrids1(); 
  55.      } 
  56.  } 
  57.  
  58.  public void changeWhiteGrids(){ 
  59.      if(NowGrids==WhiteGrids1){ 
  60.          createWhiteGrids2(); 
  61.      } 
  62.      else if(NowGrids==WhiteGrids2){ 
  63.          createWhiteGrids3(); 
  64.      } 
  65.      else if(NowGrids==WhiteGrids3){ 
  66.          createWhiteGrids4(); 
  67.      } 
  68.      else if(NowGrids==WhiteGrids4){ 
  69.          createWhiteGrids1(); 
  70.      } 
  71.  } 

然后创建函数changGrids()用于判断当前方块的颜色,接着调用对应的改变方块形状的"chang+Color+Grids"函数。

  1. public void changGrids(){ 
  2.     for(int row = 0; row < grids_number; row++){ 
  3.         grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = 0; 
  4.     } 
  5.     if(column_number == 2 && Nowcolumn + column_start == 0){ 
  6.         Nowcolumn++; 
  7.     } 
  8.  
  9.     if(Grids==1){ 
  10.         changRedGrids(); 
  11.     } 
  12.     else if(Grids==2){ 
  13.         changeGreenGrids(); 
  14.     } 
  15.     else if(Grids==3){ 
  16.         changeCyanGrids(); 
  17.     } 
  18.     else if(Grids==4){ 
  19.         changeMagentaGrids(); 
  20.     } 
  21.     else if(Grids==5){ 
  22.         changeBlueGrids(); 
  23.     } 
  24.     else if(Grids==6){ 
  25.         changeWhiteGrids(); 
  26.     } 
  27.  
  28.     for(int row = 0; row < grids_number; row++){ 
  29.         grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = Grids; 
  30.     } 
  31.  
  32.     drawGrids(); 

最后在函数drawButton()中的"变"按钮增加点击事件,调用函数changGrids()。

  1. public void drawButton(){//绘制按钮 
  2.  
  3.       button2.setClickedListener(new Component.ClickedListener() { 
  4.           @Override 
  5.           public void onClick(Component component) { 
  6.               changGrids(); 
  7.           } 
  8.       }); 
  9.   } 

方块消除

当有任一行全部填满方块时该行便会消除,该行上述的所有方块均会向下移动一格。


首先创建函数eliminateGrids()用于判断是否有任一行全部填满方块,当存在时则消除该行,并且该行上述的所有方块均会向下移动一格。

  1. public void eliminateGrids() { 
  2.      boolean k; 
  3.      for (int row = 14; row >= 0; row--) { 
  4.          k = true
  5.          for (int column = 0; column < 10; column++) { 
  6.              if (grids[row][column] == 0) 
  7.                  k = false
  8.          } 
  9.          if (k) { 
  10.              for (int i = row - 1; i >= 0; i--) { 
  11.                  for (int j = 0; j < 10; j++) { 
  12.                      grids[i + 1][j] = grids[i][j]; 
  13.                  } 
  14.              } 
  15.              for (int n = 0; n < 10; n++) { 
  16.                  grids[0][n] = 0; 
  17.              } 
  18.          } 
  19.      } 
  20.      drawGrids(); 
  21.  } 

最后在函数createGrids()中调用函数eliminateGrids()。

  1. public void createGrids(){//部分代码没有贴出,欢迎自行下载附件查看源代码 
  2.       Nowcolumn = 0; 
  3.       Nowrow = 0; 
  4.  
  5.       eliminateGrids(); 
  6.  
  7.       double random = Math.random(); 
  8.   } 

游戏结束与重新开始

当无法产生新的方块时便会显示游戏结束,点击“重新开始”便可以重新开始游戏。


首先创建函数drawText()用于绘制游戏结束文本。

  1. public void drawText(){ 
  2.         Text text=new Text(this); 
  3.         text.setText("游戏结束"); 
  4.         text.setTextSize(100); 
  5.         text.setTextColor(Color.BLUE); 
  6.         text.setTextAlignment(TextAlignment.CENTER); 
  7.         text.setMarginsTopAndBottom(-2000,0); 
  8.         text.setMarginsLeftAndRight(350,0); 
  9.         layout.addComponent(text); 
  10.         setUIContent(layout); 
  11.     } 

然后创建函数gameover()用于判断能否再次产生新的方块,判断方法为当产生新的方块原有的位置存在不为0的数字则无法产生新的方块,返回true。

  1. public boolean gameover(){ 
  2.         for(int row = 0; row < grids_number; row++){ 
  3.             if(grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] != 0){ 
  4.                 return true
  5.             } 
  6.         } 
  7.         return false
  8.     } 

再在函数createGrids()中增加判断,当游戏未有结束时继续产生新的方块,当游戏结束时停止时间和调用函数drawText()用于显示游戏结束文本。

  1. public void createGrids(){//部分代码没有贴出,欢迎自行下载附件查看源代码 
  2.       if(gameover() == false){ 
  3.           for(int row = 0; row < grids_number; row++){ 
  4.               grids[NowGrids[row][0] + Nowrow][NowGrids[row][1] + Nowcolumn] = Grids; 
  5.           } 
  6.       } 
  7.       else
  8.           timer.cancel(); 
  9.           drawText(); 
  10.       } 
  11.   } 

最后在函数drawButton()中的"重新开始"按钮增加点击事件,调用函数initialize()和函数run()。

  1. public void drawButton(){//部分代码没有贴出,欢迎自行下载附件查看源代码 
  2.       button.setClickedListener(new Component.ClickedListener() { 
  3.           @Override 
  4.           public void onClick(Component component) { 
  5.               initialize(); 
  6.               run(); 
  7.           } 
  8.       }); 
  9.   } 

到此,大功告成啦!

结语

以上就是俄罗斯方块小游戏在手机的主要编写思路以及代码,源码将放在附件中,内含详细注释,欢迎大家下载查看学习。更多深鸿会深大小组学习项目可以查看荔园Harmony,也欢迎各位关注我的专栏【荔园Harmony基地】:荔园Harmony基地,鸿蒙开发者的学习分享,更多精彩内容会持续更新,如果有遇到什么问题,或者查找出其中的错误之处,或者能够优化代码和界面,也欢迎各位在评论区留言讨论,让我们一起学习进步!


©著作权归作者和HarmonyOS技术社区共同所有,如需转载,请注明出处,否则将追究法律责任

想了解更多内容,请访问:

51CTO和华为官方战略合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

【编辑推荐】

  1. 一文教你探测虚拟环境是物理机、虚拟机还是容器?
  2. 比较9款代码质量工具,看看哪款更好用
  3. 推荐十个好用的程序员摸鱼网站,现在就给我玩起来!
  4. 2021年网络安全趋势:更高的预算,重点终端和云安全
  5. 为什么码农不应该在面试中同意进行编程测试
【责任编辑:jianghua TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

数据湖与数据仓库的分析实践攻略

数据湖与数据仓库的分析实践攻略

助力现代化数据管理:数据湖与数据仓库的分析实践攻略
共3章 | 创世达人

1人订阅学习

云原生架构实践

云原生架构实践

新技术引领移动互联网进入急速赛道
共3章 | KaliArch

30人订阅学习

数据中心和VPDN网络建设案例

数据中心和VPDN网络建设案例

漫画+案例
共20章 | 捷哥CCIE

209人订阅学习

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微