[MM32硬件] MM32SPIN27PS实现俄罗斯方块游戏

[复制链接]
1116|33
 楼主| 米多0036 发表于 2023-2-23 16:06 | 显示全部楼层 |阅读模式
大概思路
因为智能车实验室选拔需要(虽然很遗憾,今年学校实验室又不收大二的学生了),用MM32做一个俄罗斯方块的小游戏。整体方案的硬件部分由一个MM32SPIN27PS黑色芯片、五向按键开关以及1.8寸TFTLCD屏幕组成。分析下来主要实现要点有三个,游戏逻辑的实现,显示函数的实现,定时器的配置实现。

因为实验室提供了基础的调用教学和工程模板,没有配置环境等一系列问题,只需要调用工程模板里面的库函数实现上述三大功能。

画圆函数和画线函数
  1. void Gui_DrawLine(u16 x0, u16 y0,u16 x1, u16 y1,u16 Color)  

  2. {

  3. int dx,       // difference in x's

  4.   dy,       // difference in y's

  5.   dx2,      // dx,dy * 2

  6.   dy2,

  7.   x_inc,     // amount in pixel space to move during drawing

  8.   y_inc,     // amount in pixel space to move during drawing

  9.   error,     // the discriminant i.e. error i.e. decision variable

  10.   index;     // used for looping   





  11. Lcd_SetXY(x0,y0);

  12. dx = x1-x0;//计算x距离

  13. dy = y1-y0;//计算y距离



  14. if (dx>=0)

  15. {

  16. ​      x_inc = 1;

  17. }

  18. else

  19. {

  20. ​      x_inc = -1;

  21. ​      dx  = -dx;

  22. }



  23. if (dy>=0)

  24. {

  25. ​      y_inc = 1;

  26. }

  27. else

  28. {

  29. ​      y_inc = -1;

  30. ​      dy  = -dy;

  31. }



  32. dx2 = dx << 1;

  33. dy2 = dy << 1;



  34. if (dx > dy)//x距离大于y距离,那么每个x轴上只有一个点,每个y轴上有若干个点

  35. {//且线的点数等于x距离,以x轴递增画点

  36. ​      // initialize error term

  37. ​      error = dy2 - dx;



  38. ​      // draw the line

  39. ​      for (index=0; index <= dx; index++)//要画的点数不会超过x距离

  40. ​      {

  41. ​           //画点

  42. ​           Gui_DrawPoint(x0,y0,Color);

  43. ​           

  44. ​           // test if error has overflowed

  45. ​           if (error >= 0) //是否需要增加y坐标值

  46. ​           {

  47. ​                error-=dx2;



  48. ​                // move to next line

  49. ​                y0+=y_inc;//增加y坐标值

  50. ​           } // end if error overflowed



  51. ​           // adjust the error term

  52. ​           error+=dy2;



  53. ​           // move to the next pixel

  54. ​           x0+=x_inc;//x坐标值每次画点后都递增1

  55. ​      } // end for

  56. } // end if |slope| <= 1

  57. else//y轴大于x轴,则每个y轴上只有一个点,x轴若干个点

  58. {//以y轴为递增画点

  59. ​      // initialize error term

  60. ​      error = dx2 - dy;



  61. ​      // draw the line

  62. ​      for (index=0; index <= dy; index++)

  63. ​      {

  64. ​           // set the pixel

  65. ​           Gui_DrawPoint(x0,y0,Color);



  66. ​           // test if error overflowed

  67. ​           if (error >= 0)

  68. ​           {

  69. ​                error-=dy2;



  70. ​                // move to next line

  71. ​                x0+=x_inc;

  72. ​           }
  73. ​           error+=dx2;
  74. ​           y0+=y_inc;

  75. ​      }
  76. }
  77. }


————————————————


评论

———————————————— 版权声明:本文为CSDN博主「唔~~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_65439361/article/details/127149980  发表于 2023-2-23 16:06
 楼主| 米多0036 发表于 2023-2-23 16:07 | 显示全部楼层
  1. void Gui_Circle(u16 X,u16 Y,u16 R,u16 fc)

  2. {

  3.   unsigned short a,b;

  4.   int c;

  5.   a=0;

  6.   b=R;

  7.   c=3-2*R;

  8.   while (a<b)

  9.   {

  10. ​    Gui_DrawPoint(X+a,Y+b,fc);   //    7

  11. ​    Gui_DrawPoint(X-a,Y+b,fc);   //    6

  12. ​    Gui_DrawPoint(X+a,Y-b,fc);   //    2

  13. ​    Gui_DrawPoint(X-a,Y-b,fc);   //    3

  14. ​    Gui_DrawPoint(X+b,Y+a,fc);   //    8

  15. ​    Gui_DrawPoint(X-b,Y+a,fc);   //    5

  16. ​    Gui_DrawPoint(X+b,Y-a,fc);   //    1

  17. ​    Gui_DrawPoint(X-b,Y-a,fc);   //    4



  18. ​    if(c<0) c=c+4*a+6;

  19. ​    else

  20. ​    {

  21. ​      c=c+4*(a-b)+10;

  22. ​      b-=1;

  23. ​    }

  24. ​    a+=1;

  25.   }

  26.   if (a==b)

  27.   {

  28. ​    Gui_DrawPoint(X+a,Y+b,fc);

  29. ​    Gui_DrawPoint(X+a,Y+b,fc);

  30. ​    Gui_DrawPoint(X+a,Y-b,fc);

  31. ​    Gui_DrawPoint(X-a,Y-b,fc);

  32. ​    Gui_DrawPoint(X+b,Y+a,fc);

  33. ​    Gui_DrawPoint(X-b,Y+a,fc);

  34. ​    Gui_DrawPoint(X+b,Y-a,fc);

  35. ​    Gui_DrawPoint(X-b,Y-a,fc);

  36.   }

  37. }
 楼主| 米多0036 发表于 2023-2-23 16:07 | 显示全部楼层
方块绘制函数
TFT显示屏为128*160,选取10*10作为一个方块,游戏界面可以设置为长15格,宽12格,右侧留出一格提前显示下一个俄罗斯方块。
 楼主| 米多0036 发表于 2023-2-23 16:07 | 显示全部楼层
  1. void Draw_realbox(uint16 x,uint16 y)
  2. {
  3.         uint8 i,n;
  4.         for(i=1;i<=8;i++)//绘制小方块内填充色8*8
  5.         {
  6.                 for(n=1;n<=8;n++)
  7.                 {
  8.                         lcd_drawpoint((x+i),(y+n),RED);       
  9.                 }       
  10.         }
  11.         for(i=0;i<=9;i++)//绘制小方块轮廓10*10
  12.         {
  13.                 lcd_drawpoint((x+i),y,BLACK        );
  14.                 lcd_drawpoint((x+i),(y+9),BLACK        );               
  15.                 lcd_drawpoint(x,(y+i),BLACK        );               
  16.                 lcd_drawpoint((x+9),(y+i),BLACK        );                               
  17.         }       
  18. }

  19. void Draw_realbox1(uint16 x,uint16 y)
  20. {
  21.         uint8 i,n;
  22.         for(i=1;i<=3;i++)
  23.         {
  24.                 for(n=1;n<=3;n++)
  25.                 {
  26.                         lcd_drawpoint((x+i),(y+n),RED);       
  27.                 }       
  28.         }
  29.         for(i=0;i<=4;i++)
  30.         {
  31.                 lcd_drawpoint((x+i),y,BLACK        );
  32.                 lcd_drawpoint((x+i),(y+4),BLACK        );               
  33.                 lcd_drawpoint(x,(y+i),BLACK        );               
  34.                 lcd_drawpoint((x+4),(y+i),BLACK        );                               
  35.         }       
  36. }
 楼主| 米多0036 发表于 2023-2-23 16:07 | 显示全部楼层
  1. void Draw_realbox(uint16 x,uint16 y)
  2. {
  3.         uint8 i,n;
  4.         for(i=1;i<=8;i++)//绘制小方块内填充色8*8
  5.         {
  6.                 for(n=1;n<=8;n++)
  7.                 {
  8.                         lcd_drawpoint((x+i),(y+n),RED);       
  9.                 }       
  10.         }
  11.         for(i=0;i<=9;i++)//绘制小方块轮廓10*10
  12.         {
  13.                 lcd_drawpoint((x+i),y,BLACK        );
  14.                 lcd_drawpoint((x+i),(y+9),BLACK        );               
  15.                 lcd_drawpoint(x,(y+i),BLACK        );               
  16.                 lcd_drawpoint((x+9),(y+i),BLACK        );                               
  17.         }       
  18. }

  19. void Draw_realbox1(uint16 x,uint16 y)
  20. {
  21.         uint8 i,n;
  22.         for(i=1;i<=3;i++)
  23.         {
  24.                 for(n=1;n<=3;n++)
  25.                 {
  26.                         lcd_drawpoint((x+i),(y+n),RED);       
  27.                 }       
  28.         }
  29.         for(i=0;i<=4;i++)
  30.         {
  31.                 lcd_drawpoint((x+i),y,BLACK        );
  32.                 lcd_drawpoint((x+i),(y+4),BLACK        );               
  33.                 lcd_drawpoint(x,(y+i),BLACK        );               
  34.                 lcd_drawpoint((x+4),(y+i),BLACK        );                               
  35.         }       
  36. }
 楼主| 米多0036 发表于 2023-2-23 16:07 | 显示全部楼层
删除方块实现方法是绘制成白色
  1. void Del_realbox(uint16 x,uint16 y)
  2. {
  3.         uint8 i,n;
  4.         for(i=0;i<=9;i++)
  5.         {
  6.                 for(n=0;n<=9;n++)
  7.                 {
  8.                         lcd_drawpoint((x+i),(y+n),WHITE);       
  9.                 }       
  10.         }
  11. }


  12. void Del_realbox1(uint16 x,uint16 y)
  13. {
  14.         uint8 i,n;
  15.         for(i=0;i<=4;i++)
  16.         {
  17.                 for(n=0;n<=4;n++)
  18.                 {
  19.                         lcd_drawpoint((x+i),(y+n),WHITE);       
  20.                 }       
  21.         }
  22. }

 楼主| 米多0036 发表于 2023-2-23 16:07 | 显示全部楼层
删除方块实现方法是绘制成白色
  1. void Del_realbox(uint16 x,uint16 y)
  2. {
  3.         uint8 i,n;
  4.         for(i=0;i<=9;i++)
  5.         {
  6.                 for(n=0;n<=9;n++)
  7.                 {
  8.                         lcd_drawpoint((x+i),(y+n),WHITE);       
  9.                 }       
  10.         }
  11. }


  12. void Del_realbox1(uint16 x,uint16 y)
  13. {
  14.         uint8 i,n;
  15.         for(i=0;i<=4;i++)
  16.         {
  17.                 for(n=0;n<=4;n++)
  18.                 {
  19.                         lcd_drawpoint((x+i),(y+n),WHITE);       
  20.                 }       
  21.         }
  22. }

 楼主| 米多0036 发表于 2023-2-23 16:08 | 显示全部楼层
有了以上两个函数,我们只需要在规定的坐标处调用四次小方块绘制或删除函数。即可得到或消除一块完整的俄罗斯方块,利用random产生随机数,加上switch语句进行选择需要何种方块,总方块在switch中设计了19种。
图形绘制函数如下(部分):
  1. void Del_tuxing(uint16 x,uint16 y,uint8 what)
  2. {
  3.         switch (what)
  4.         {
  5.                 case 1:
  6.                 {
  7.                 Del_realbox(x,y);
  8.                 Del_realbox(x+10,y);
  9.                 Del_realbox(x,y+10);
  10.                 Del_realbox(x+10,y+10);
  11.                 }
  12.                 break;
  13.                
  14.                 case 2:
  15.                 {
  16.                 Del_realbox(x,y);
  17.                 Del_realbox(x+10,y);
  18.                 Del_realbox(x+20,y);
  19.                 Del_realbox(x+30,y);
  20.                 }
  21.                 break;
  22.                
  23.                 case 3:
  24.                 {
  25.                 Del_realbox(x,y);
  26.                 Del_realbox(x,y+10);
  27.                 Del_realbox(x,y+20);
  28.                 Del_realbox(x,y+30);
  29.                 }
  30.                 break;
  31.                
  32.                 case 4:
  33.                 {
  34.                 Del_realbox(x+10,y);
  35.                 Del_realbox(x,y+10);
  36.                 Del_realbox(x+10,y+10);
  37.                 Del_realbox(x+20,y+10);
  38.                 }
  39.                 break;
  40.                
  41.                 case 5:
  42.                 {
  43.                 Del_realbox(x+10,y+10);
  44.                 Del_realbox(x,y);
  45.                 Del_realbox(x,y+10);
  46.                 Del_realbox(x,y+20);
  47.                 }
  48.                 break;

  49.                 case 6:
  50.                 {
  51.                 Del_realbox(x,y+10);
  52.                 Del_realbox(x+10,y);
  53.                 Del_realbox(x+10,y+10);
  54.                 Del_realbox(x+10,y+20);
  55.                 }
  56.                 break;
  57.                
  58.                 case 7:
  59.                 {
  60.                 Del_realbox(x+10,y+10);
  61.                 Del_realbox(x,y);
  62.                 Del_realbox(x+10,y);
  63.                 Del_realbox(x+20,y);
  64.                 }
  65.                 break;
  66.        
  67.                 case 8:
  68.                 {
  69.                 Del_realbox(x,y);
  70.                 Del_realbox(x,y+10);
  71.                 Del_realbox(x,y+20);
  72.                 Del_realbox(x+10,y+20);
  73.                 }
  74.                 break;
  75.                
  76.                 case 9:
  77.                 {
  78.                 Del_realbox(x,y);
  79.                 Del_realbox(x,y+10);
  80.                 Del_realbox(x+10,y);
  81.                 Del_realbox(x+20,y);
  82.                 }
  83.                 break;
  84.                
  85.                 case 10:
  86.                 {
  87.                 Del_realbox(x,y);
  88.                 Del_realbox(x+10,y);
  89.                 Del_realbox(x+10,y+10);
  90.                 Del_realbox(x+10,y+20);
  91.                 }
  92.                 break;
  93.                
  94.                 case 11:
  95.                 {
  96.                 Del_realbox(x,y+10);
  97.                 Del_realbox(x+10,y+10);
  98.                 Del_realbox(x+20,y+10);
  99.                 Del_realbox(x+20,y);
  100.                 }
  101.                 break;
  102.                
  103.                 case 12:
  104.                 {
  105.                 Del_realbox(x+10,y);
  106.                 Del_realbox(x+10,y+10);
  107.                 Del_realbox(x+10,y+20);
  108.                 Del_realbox(x,y+20);
  109.                 }
  110.                 break;
  111.                
  112.                 case 13:
  113.                 {
  114.                 Del_realbox(x,y);
  115.                 Del_realbox(x+10,y);
  116.                 Del_realbox(x+20,y);
  117.                 Del_realbox(x+20,y+10);
  118.                 }
  119.                 break;
  120.                
  121.                 case 14:
  122.                 {
  123.                 Del_realbox(x,y);
  124.                 Del_realbox(x+10,y);
  125.                 Del_realbox(x,y+10);
  126.                 Del_realbox(x,y+20);
  127.                 }
  128.                 break;
  129.                
  130.                 case 15:
  131.                 {
  132.                 Del_realbox(x,y);
  133.                 Del_realbox(x,y+10);
  134.                 Del_realbox(x+10,y+10);
  135.                 Del_realbox(x+20,y+10);
  136.                 }
  137.                 break;
  138.                
  139.                
  140.                 case 16:
  141.                 {
  142.                 Del_realbox(x+10,y);
  143.                 Del_realbox(x,y+10);
  144.                 Del_realbox(x+10,y+10);
  145.                 Del_realbox(x,y+20);
  146.                 }
  147.                 break;
  148.                
  149.                 case 17:
  150.                 {
  151.                 Del_realbox(x,y);
  152.                 Del_realbox(x+10,y);
  153.                 Del_realbox(x+10,y+10);
  154.                 Del_realbox(x+20,y+10);
  155.                 }
  156.                 break;
  157.                
  158.                 case 18:
  159.                 {
  160.                 Del_realbox(x,y);
  161.                 Del_realbox(x,y+10);
  162.                 Del_realbox(x+10,y+10);
  163.                 Del_realbox(x+10,y+20);
  164.                 }
  165.                 break;
  166.                
  167.                 case 19:
  168.                 {
  169.                 Del_realbox(x,y+10);
  170.                 Del_realbox(x+10,y+10);
  171.                 Del_realbox(x+10,y);
  172.                 Del_realbox(x+20,y);
  173.                 }
  174.                 break;
  175.        
  176.        
  177.        
  178.        
  179.         }

  180. }


  181. void Del_tuxing1(uint16 x,uint16 y,uint8 what)
  182. {
  183.         switch (what)
  184.         {
  185.                 case 1:
  186.                 {
  187.                 Del_realbox1(x,y);
  188.                 Del_realbox1(x+5,y);
  189.                 Del_realbox1(x,y+5);
  190.                 Del_realbox1(x+5,y+5);
  191.                 }
  192.                 break;
  193.                
  194.                 case 2:
  195.                 {
  196.                 Del_realbox1(x,y);
  197.                 Del_realbox1(x+5,y);
  198.                 Del_realbox1(x+10,y);
  199.                 Del_realbox1(x+15,y);
  200.                 }
  201.                 break;
  202.                
  203.                 case 3:
  204.                 {
  205.                 Del_realbox1(x,y);
  206.                 Del_realbox1(x,y+5);
  207.                 Del_realbox1(x,y+10);
  208.                 Del_realbox1(x,y+15);
  209.                 }
  210.                 break;
  211.                
  212.                 case 4:
  213.                 {
  214.                 Del_realbox1(x+5,y);
  215.                 Del_realbox1(x,y+5);
  216.                 Del_realbox1(x+5,y+5);
  217.                 Del_realbox1(x+10,y+5);
  218.                 }
  219.                 break;
  220.                
  221.                 case 5:
  222.                 {
  223.                 Del_realbox1(x+5,y+5);
  224.                 Del_realbox1(x,y);
  225.                 Del_realbox1(x,y+5);
  226.                 Del_realbox1(x,y+10);
  227.                 }
  228.                 break;

  229.                 case 6:
  230.                 {
  231.                 Del_realbox1(x,y+5);
  232.                 Del_realbox1(x+5,y);
  233.                 Del_realbox1(x+5,y+5);
  234.                 Del_realbox1(x+5,y+10);
  235.                 }
  236.                 break;
  237.                
  238.                 case 7:
  239.                 {
  240.                 Del_realbox1(x+5,y+5);
  241.                 Del_realbox1(x,y);
  242.                 Del_realbox1(x+5,y);
  243.                 Del_realbox1(x+10,y);
  244.                 }
  245.                 break;
  246.        
  247.                 case 8:
  248.                 {
  249.                 Del_realbox1(x,y);
  250.                 Del_realbox1(x,y+5);
  251.                 Del_realbox1(x,y+10);
  252.                 Del_realbox1(x+5,y+10);
  253.                 }
  254.                 break;
  255.                
  256.                 case 9:
  257.                 {
  258.                 Del_realbox1(x,y);
  259.                 Del_realbox1(x,y+5);
  260.                 Del_realbox1(x+5,y);
  261.                 Del_realbox1(x+10,y);
  262.                 }
  263.                 break;
  264.                
  265.                 case 10:
  266.                 {
  267.                 Del_realbox1(x,y);
  268.                 Del_realbox1(x+5,y);
  269.                 Del_realbox1(x+5,y+5);
  270.                 Del_realbox1(x+5,y+10);
  271.                 }
  272.                 break;
  273.                
  274.                 case 11:
  275.                 {
  276.                 Del_realbox1(x,y+5);
  277.                 Del_realbox1(x+5,y+5);
  278.                 Del_realbox1(x+10,y+5);
  279.                 Del_realbox1(x+10,y);
  280.                 }
  281.                 break;
  282.                
  283.                 case 12:
  284.                 {
  285.                 Del_realbox1(x+5,y);
  286.                 Del_realbox1(x+5,y+5);
  287.                 Del_realbox1(x+5,y+10);
  288.                 Del_realbox1(x,y+10);
  289.                 }
  290.                 break;
  291.                
  292.                 case 13:
  293.                 {
  294.                 Del_realbox1(x,y);
  295.                 Del_realbox1(x+5,y);
  296.                 Del_realbox1(x+10,y);
  297.                 Del_realbox1(x+10,y+5);
  298.                 }
  299.                 break;
  300.                
  301.                 case 14:
  302.                 {
  303.                 Del_realbox1(x,y);
  304.                 Del_realbox1(x+5,y);
  305.                 Del_realbox1(x,y+5);
  306.                 Del_realbox1(x,y+10);
  307.                 }
  308.                 break;
  309.                
  310.                 case 15:
  311.                 {
  312.                 Del_realbox1(x,y);
  313.                 Del_realbox1(x,y+5);
  314.                 Del_realbox1(x+5,y+5);
  315.                 Del_realbox1(x+10,y+5);
  316.                 }
  317.                 break;
  318.                
  319.                
  320.                 case 16:
  321.                 {
  322.                 Del_realbox1(x+5,y);
  323.                 Del_realbox1(x,y+5);
  324.                 Del_realbox1(x+5,y+5);
  325.                 Del_realbox1(x,y+10);
  326.                 }
  327.                 break;
  328.                
  329.                 case 17:
  330.                 {
  331.                 Del_realbox1(x,y);
  332.                 Del_realbox1(x+5,y);
  333.                 Del_realbox1(x+5,y+5);
  334.                 Del_realbox1(x+10,y+5);
  335.                 }
  336.                 break;
  337.                
  338.                 case 18:
  339.                 {
  340.                 Del_realbox1(x,y);
  341.                 Del_realbox1(x,y+5);
  342.                 Del_realbox1(x+5,y+5);
  343.                 Del_realbox1(x+5,y+10);
  344.                 }
  345.                 break;
  346.                
  347.                 case 19:
  348.                 {
  349.                 Del_realbox1(x,y+5);
  350.                 Del_realbox1(x+5,y+5);
  351.                 Del_realbox1(x+5,y);
  352.                 Del_realbox1(x+10,y);
  353.                 }
  354.                 break;
  355.         }

  356. }

 楼主| 米多0036 发表于 2023-2-23 16:08 | 显示全部楼层
数组实现逻辑
使用了15*12的数组来记录方块的位置,用0,1对当前方块进行标记,逻辑上可以进行后续的碰撞,方块消除的判断。需要区分改变数组状态并不等于直接显示,改变数组状态之后还需要调用相关的显示函数才可以实现实现相关的显示功能。
绘制一个状态
  1. void Draw_a_zhuangtai(uint16 x,uint16 y)
  2. {
  3.           zhuangtai[y/10][x/10+1]=1;
  4. }
 楼主| 米多0036 发表于 2023-2-23 16:08 | 显示全部楼层
删除一个状态
  1. void Del_a_zhuangtai(uint16 x,uint16 y)
  2. {
  3.           zhuangtai[y/10][x/10+1]=0;
  4. }
 楼主| 米多0036 发表于 2023-2-23 16:08 | 显示全部楼层
碰撞判断
使用求和的方式找出碰撞的方块。在方块没发生碰撞之前,对该数组求和的值为把目前数组扫一遍的值。当方块发生碰撞,两个方块之间的交集会使得方块占的值变化(变小),与原值比较后可得出方块是否碰撞,碰撞则返回一个值。

  1. int panduan(uint16 x,uint16 y,uint8 what,uint8 fangxiang)//碰撞检测
  2. {
  3.         uint16 sum1=0,sum2=0;
  4.         uint8 i,n;
  5.         uint8 sbuff[A][B];
  6.         x=x/10+1;//得到换算后的真实坐标
  7.         y=y/10;
  8.         for(i=0;i<A;i++)
  9.         {
  10.                 for(n=0;n<B;n++)
  11.                 {
  12.                         sbuff[i][n]=zhuangtai[i][n];
  13.                         sum1=sum1+zhuangtai[i][n];       
  14.                 }  
  15.         }
  16.         switch(fangxiang)
  17.         {
  18.                 case 1:Left_zhuangtai_move((x-1)*10,10*y,what);break;
  19.                 case 2:Down_zhuangtai_move((x-1)*10,10*y,what);break;
  20.                 case 3:Right_zhuangtai_move((x-1)*10,10*y,what);break;
  21.                 case 4:change_zhuangtai();break;
  22.                
  23.         }
  24.                 for(i=0;i<A;i++)
  25.         {
  26.                
  27.                 for(n=0;n<B;n++)
  28.                 {
  29.                         sum2=sum2+zhuangtai[i][n];       
  30.                         zhuangtai[i][n]=sbuff[i][n];                       
  31.     }
  32.         }       
  33.                 return !(sum1==sum2);
  34. }
 楼主| 米多0036 发表于 2023-2-23 16:09 | 显示全部楼层
物理消除
由函数xiaochu()实现,每发生一次碰撞就检测一次是否满足消除条件
  1. void xiaochu()
  2. {
  3.         uint8 n;
  4.         for(n=12;n>0;n--)
  5.         {
  6.                 if(n>=12)
  7.                 {
  8.                         n=12;
  9.                 }
  10.                 if(        (
  11.                                         zhuangtai[n+1][1]&&zhuangtai[n+1][2]&&zhuangtai[n+1][3]&&zhuangtai[n+1][4]&&zhuangtai[n+1][5]&&zhuangtai[n+1][6]&&zhuangtai[n+1][7]&&zhuangtai[n+1][8]&&zhuangtai[n+1][9]&&zhuangtai[n+1][10]&&zhuangtai[n+1][11]
  12.                                 )
  13.                                  &&
  14.                                 !(
  15.                                         zhuangtai[n][1]&&zhuangtai[n][2]&&zhuangtai[n][3]&&zhuangtai[n][4]&&zhuangtai[n][5]&&zhuangtai[n][6]&&zhuangtai[n][7]&&zhuangtai[n][8]&&zhuangtai[n][9]&&zhuangtai[n][10]&&zhuangtai[n][11]
  16.                                         )
  17.                    )//描述:
  18.                   
  19.                 {
  20.                         lie_move(10*n);//将被消除行于其上一行交换
  21.                         n=n+2;
  22.                 }
  23.                
  24.                 if((
  25.                                 !zhuangtai[n][1]&&!zhuangtai[n][2]&&!zhuangtai[n][3]&&!zhuangtai[n][4]&&!zhuangtai[n][5]&&!zhuangtai[n][6]&&!zhuangtai[n][7]&&!zhuangtai[n][8]&&!zhuangtai[n][9]&&!zhuangtai[n][10]&&!zhuangtai[n][11]
  26.                                 )//该条件用于判断换行是否完成(因为换行瞬间两行是清空的,即均为0)
  27.                   )
  28.                 {
  29.                         for(n=0;n<12 ;n++){
  30.                                 if(
  31.                                                 (
  32.                                                 zhuangtai[n][1]&&zhuangtai[n][2]&&zhuangtai[n][3]&&zhuangtai[n][4]&&zhuangtai[n][5]&&zhuangtai[n][6]&&zhuangtai[n][7]&&zhuangtai[n][8]&&zhuangtai[n][9]&&zhuangtai[n][10]&&zhuangtai[n][11]
  33.                                                 )
  34.                                         ){
  35.                                                 Del_lie(n*10);
  36.                                                 fengshu++;
  37.                                                 display_fengshu();
  38.                                         if(fengshu%10==0)
  39.                                         {
  40.                                                 speed=speed-10;
  41.                                                 leave++;
  42.                                                 display_leave();                               
  43.                                         }
  44.                                 }       
  45.                         }
  46.         break;               
  47.                 }
  48.         }
  49. }

 楼主| 米多0036 发表于 2023-2-23 16:09 | 显示全部楼层
其中,消除函数的“消除”功能是由调用换行函数lie_move()和删行函数Del_lie()实现的
  1. void lie_move(uint16 y)//交换上下两行的缓存值
  2. {
  3.         uint8 i;
  4.         y=y/10;
  5.         for(i=1;i<15;i++)
  6.         {
  7.                 if(zhuangtai[y][i]==1)
  8.                 {
  9.                         zhuangtai[y][i]=zhuangtai[y+1][i];
  10.                         zhuangtai[y+1][i]=1;
  11.                        
  12.                                 Del_realbox((i-1)*10,y*10);
  13.                         Draw_realbox((i-1)*10,(y+1)*10);
  14.                 }
  15.                 else if(zhuangtai[y][i]==0)
  16.                 {
  17.                         zhuangtai[y][i]=zhuangtai[y+1][i];
  18.                         zhuangtai[y+1][i]=0;
  19.                        
  20.                                 Del_realbox((i-1)*10,y*10);
  21.                         Del_realbox((i-1)*10,(y+1)*10);
  22.                 }
  23.         }
  24. }
 楼主| 米多0036 发表于 2023-2-23 16:09 | 显示全部楼层
  1. void Del_lie(uint16 y)//删除一行
  2. {
  3.         uint8 i;
  4.         y=y/10;
  5.         for(i=1;i<15;i++)
  6.         {
  7.                 zhuangtai[y][i]=0;
  8.                 Del_realbox((i-1)*10,y*10);
  9.         }
  10. }
 楼主| 米多0036 发表于 2023-2-23 16:09 | 显示全部楼层
形状控制函数
绘制出规定形状的俄罗斯方块的函数,一共有两个,change()函数用于绘制LCD上的,change_Zhuangtai()函数用于改变状态数组中的。
  1. void change()
  2. {
  3.         switch(what)
  4.         {
  5.                 case 1:break;
  6.                
  7.                 case 2:Del(x,y,2);Draw(x,y,3);what=3;break;
  8.                 case 3:Del(x,y,3);Draw(x,y,2);what=2;break;
  9.                
  10.                 case 4:Del(x,y,4);Draw(x,y,5);what=5;break;
  11.                 case 5:Del(x,y,5);Draw(x,y,7);what=7;break;
  12.                 case 6:Del(x,y,6);Draw(x,y,4);what=4;break;
  13.                 case 7:Del(x,y,7);Draw(x,y,6);what=6;break;
  14.                
  15.                 case 8:Del(x,y,8);Draw(x,y,9);what=9;break;
  16.                 case 9:Del(x,y,9);Draw(x,y,10);what=10;break;
  17.                 case 10:Del(x,y,10);Draw(x,y,11);what=11;break;
  18.                 case 11:Del(x,y,11);Draw(x,y,8);what=8;break;
  19.                
  20.                 case 12:Del(x,y,12);Draw(x,y,15);what=15;break;
  21.                 case 13:Del(x,y,13);Draw(x,y,12);what=12;break;
  22.                 case 14:Del(x,y,14);Draw(x,y,13);what=13;break;
  23.                 case 15:Del(x,y,15);Draw(x,y,14);what=14;break;
  24.                
  25.                 case 16:Del(x,y,16);Draw(x,y,17);what=17;break;
  26.                 case 17:Del(x,y,17);Draw(x,y,16);what=16;break;
  27.                
  28.                 case 18:Del(x,y,18);Draw(x,y,19);what=19;break;
  29.                 case 19:Del(x,y,19);Draw(x,y,18);what=18;break;
  30.        
  31.         }
  32. }

  1. void change_zhuangtai()
  2. {
  3.         switch(what)
  4.         {
  5.                 case 1:break;
  6.                 case 2:Del_zhuangtai_tuxing(x,y,2);Draw_zhuangtai_tuxing(x,y,3);break;
  7.                 case 3:Del_zhuangtai_tuxing(x,y,3);Draw_zhuangtai_tuxing(x,y,2);break;
  8.                 case 4:Del_zhuangtai_tuxing(x,y,4);Draw_zhuangtai_tuxing(x,y,5);break;
  9.                 case 5:Del_zhuangtai_tuxing(x,y,5);Draw_zhuangtai_tuxing(x,y,7);break;
  10.                 case 6:Del_zhuangtai_tuxing(x,y,6);Draw_zhuangtai_tuxing(x,y,4);break;
  11.                 case 7:Del_zhuangtai_tuxing(x,y,7);Draw_zhuangtai_tuxing(x,y,6);break;
  12.                 case 8:Del_zhuangtai_tuxing(x,y,8);Draw_zhuangtai_tuxing(x,y,9);break;
  13.                 case 9:Del_zhuangtai_tuxing(x,y,9);Draw_zhuangtai_tuxing(x,y,10);break;
  14.                 case 10:Del_zhuangtai_tuxing(x,y,10);Draw_zhuangtai_tuxing(x,y,11);break;
  15.                 case 11:Del_zhuangtai_tuxing(x,y,11);Draw_zhuangtai_tuxing(x,y,8);break;
  16.                 case 12:Del_zhuangtai_tuxing(x,y,12);Draw_zhuangtai_tuxing(x,y,15);break;
  17.                 case 13:Del_zhuangtai_tuxing(x,y,13);Draw_zhuangtai_tuxing(x,y,12);break;
  18.                 case 14:Del_zhuangtai_tuxing(x,y,14);Draw_zhuangtai_tuxing(x,y,13);break;
  19.                 case 15:Del_zhuangtai_tuxing(x,y,15);Draw_zhuangtai_tuxing(x,y,14);break;
  20.                 case 16:Del_zhuangtai_tuxing(x,y,16);Draw_zhuangtai_tuxing(x,y,17);break;
  21.                 case 17:Del_zhuangtai_tuxing(x,y,17);Draw_zhuangtai_tuxing(x,y,16);break;
  22.                 case 18:Del_zhuangtai_tuxing(x,y,18);Draw_zhuangtai_tuxing(x,y,19);break;
  23.                 case 19:Del_zhuangtai_tuxing(x,y,19);Draw_zhuangtai_tuxing(x,y,18);break;
  24.        
  25.         }
  26. }
  27.        
 楼主| 米多0036 发表于 2023-2-23 16:10 | 显示全部楼层
随机数的生成
  1. what=rand()%19+1;//what代表着不同俄罗斯方块
 楼主| 米多0036 发表于 2023-2-23 16:10 | 显示全部楼层
方向控制
方块可进行左、右、下的移动,因此我们需要在接到指令后再对应坐标画出完整的俄罗斯方块并将原坐标处的图形消除,只需调用之前定义的图形调用/删除函数即可。值得注意的是,在移动图像的同时,我们也需要对状态数组中的数据进行相应的移动,为此我们需要一些整合后的函数如Down(),Left(),Right(),Del().

  1. void Down(uint16 x,uint16 y,uint8 what)//调用方向移动函数
  2. {
  3.         Down_zhuangtai_move(x,y,what);
  4.         Down_tuxing_move(x,y,what);                       
  5. }```

  6. ```c
  7. void Left(uint16 x,uint16 y,uint8 what)
  8. {
  9.         Left_zhuangtai_move(x,y,what);
  10.         Left_tuxing_move(x,y,what);                       
  11. }
 楼主| 米多0036 发表于 2023-2-23 16:10 | 显示全部楼层
2
  1. void Right(uint16 x,uint16 y,uint8 what)
  2. {
  3.         Right_zhuangtai_move(x,y,what);
  4.         Right_tuxing_move(x,y,what);                       
  5. }

 楼主| 米多0036 发表于 2023-2-23 16:11 | 显示全部楼层
3

  1. void Del(uint16 x,uint16 y,uint8 what)
  2. {
  3.         Del_tuxing(x,y,what);
  4.         Del_zhuangtai_tuxing(x,y,what);                       
  5. }
 楼主| 米多0036 发表于 2023-2-23 16:11 | 显示全部楼层
配合KEY_Scan()就可以实现方向判断。
  1. #define KEY_UP 1
  2. #define KEY_DOWN 2
  3. #define KEY_LEFT 3
  4. #define KEY_RIGHT 4  
  5. #define KEY_MID 5  
  6. u8 Key_Scan(void)
  7. {

  8.        
  9.         if(key_up&&(KB1||KB2||KB3||KB4||KB5))
  10.         {

  11.                 systick_delay_ms(10);//去抖动//
  12.                 key_up=0;
  13.                 if     (KB1)       
  14.                         return KEY_UP;
  15.                 else if(KB2)
  16.                         return KEY_DOWN;
  17.                 else if(KB3)
  18.                         return KEY_LEFT;
  19.                 else if(KB4)
  20.                         return KEY_RIGHT;
  21.                 else if(KB5)
  22.                         return KEY_MID;
  23.         }
  24.         else if(!KB1&&!KB2&&!KB3&&!KB4&&!KB5)
  25.         {
  26.                 key_up=1;
  27.         }
  28.         return 0;// 无按键按下       
  29. }

  30.                
您需要登录后才可以回帖 登录 | 注册

本版积分规则

138

主题

1431

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部