找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10423|回复: 4
打印 上一主题 下一主题
收起左侧

MSP430单片机俄罗斯方块游戏程序设计

[复制链接]
跳转到指定楼层
楼主
MSP430单片机游戏程序,俄罗斯方块,采用TI公司官方MSP430F5529开发板.TI公司的官方开发板,原理图网上都有,TI官网也有下的



源码:
  1. /*基于MSP430F5529俄罗斯方块游戏程序*/
  2. //作者:        詹磊
  3. //功能:        基于MSP430F5529俄罗斯方块游戏程序
  4. //说明:        运行环境:TI官方MSP-EXP5529开发板(外接4个带上拉电阻独立按键)
  5. //                非原创,思路是从51单片机上移植过来的
  6. //                底层液晶驱动是TI官方提供的LCD API
  7. //                游戏算法部分的底层程序多处已经修改,与原版会有较大的差别
  8. //版本:        测试版 V1.0(基本能流畅运行,但需要进一步的美化和优化)
  9. #include "MSP430F5529.h"
  10. #include "LCD_102x64.h"
  11. #include "main.h"
  12. #include "Key.h"
  13. #define MAXHANG 20                                                //游戏显示行数
  14. #define MAXLIE  16                                                //游戏显示列数
  15. #define MapWide        48                                                //地图宽
  16. #define MapHigh        60                                                //地图高
  17. #define ON                0
  18. #define OFF                1

  19. #define BIT(n)                (1<<(n))
  20. volatile uint cubeMap[MAXHANG];                           //地图显示存存
  21. typedef struct{
  22.                uchar const * box;                   //方块图形字模数据指针
  23.                            uchar cube : 4;                           //方块形态(占用4个位域)
  24.                            uchar state : 4;                           //方块状态(占用4个位域)
  25.                            char row;                                   //方块所在行
  26.                            char column;                                   //方块所在列
  27.                            } block;
  28. block this;
  29. uchar liang=1;
  30. uchar Speed=1,Score=0;
  31. uint timeA=0;
  32. uchar downflag=0;
  33. uchar randomNumber=0;
  34. const uchar cube[]=
  35. {
  36. /* ■
  37.   ■■■
  38. */
  39. 0,4,0xe,0,  0,2,6,2,     0,7,2,0,     4,6,4,0,

  40. /*■
  41.   ■■■
  42. */
  43. 0,8,0xe,0,  0,4,4,0xc,   0,0,0xe,2,   0,6,4,4,
  44. /*■■■
  45.   ■
  46. */
  47. 0,0xe,8,0,  0,4,4,6,     0,1,7,0,     6,2,2,0,
  48. /*■■
  49.     ■■
  50. */
  51. 0,0xc,6,0,  0,2,6,4,     0,6,3,0,     2,6,4,0,
  52. /*  ■■
  53.   ■■
  54. */
  55. 0,6,0xc,0,  0,4,6,2,     0,3,6,0,     4,6,2,0,
  56. /*■■■■
  57. */
  58. 0,0xf,0,0,  4,4,4,4,     0,0,0xf,0,   2,2,2,2,
  59. /*■■
  60.   ■■
  61. */
  62. 0,6,6,0,    0,6,6,0,     0,6,6,0,     0,6,6,0
  63. };
  64. void delay_ms(uint z)//毫秒级延时函数
  65. {
  66.         uint i,m;
  67.         for(i=z;i>0;i--)
  68.                 for(m=4500;m>0;m--)
  69.                 {
  70.                         _NOP();
  71.                 }
  72. }
  73. //-------------------------------------------//
  74. //函数名:八位LED灯控制函数
  75. //入口:Number:Number哪位为一则哪位LED点亮
  76. //出口:Void
  77. //功能:
  78. //-------------------------------------------//
  79. void DigitalLedControl(uchar Number)
  80. {
  81.         if(Number&BIT7)
  82.                 P1OUT|=BIT0;
  83.         else
  84.                 P1OUT&=~BIT0;
  85.         if(Number&BIT6)
  86.                 P8OUT|=BIT1;
  87.         else
  88.                 P8OUT&=~BIT1;
  89.         if(Number&BIT5)
  90.                 P8OUT|=BIT2;
  91.         else
  92.                 P8OUT&=~BIT2;
  93.         if(Number&BIT4)
  94.                 P1OUT|=BIT1;
  95.         else
  96.                 P1OUT&=~BIT1;
  97.         if(Number&BIT3)
  98.                 P1OUT|=BIT2;
  99.         else
  100.                 P1OUT&=~BIT2;
  101.         if(Number&BIT2)
  102.                 P1OUT|=BIT3;
  103.         else
  104.                 P1OUT&=~BIT3;
  105.         if(Number&BIT1)
  106.                 P1OUT|=BIT4;
  107.         else
  108.                 P1OUT&=~BIT4;
  109.         if(Number&BIT0)
  110.                 P1OUT|=BIT5;
  111.         else
  112.                 P1OUT&=~BIT5;
  113. }
  114. //-------------------------------------------//
  115. //函数名:显存清空函数
  116. //入口:Void
  117. //出口:Void
  118. //功能:清空显存
  119. //-------------------------------------------//
  120. void DisplayRamClear()
  121. {
  122.         uchar i;
  123.         for(i=0;i<20;i++)
  124.         {
  125.                 cubeMap[i]=0x0;
  126.         }
  127. }
  128. //-------------------------------------------//
  129. //函数名:两位十进制数字显示函数
  130. //入口:        Row:显示的行数
  131. //                Column:显示的列数
  132. //                Number:需要显示的数字<100 && >=0
  133. //出口:Void
  134. //功能:
  135. //-------------------------------------------//
  136. void Number2BitDisplay(uchar Row,uchar Column,uchar Number)
  137. {
  138.         uchar tempShi,tempGe;
  139.         tempShi=Number/10;
  140.         tempGe=Number%10;
  141.         Dogs102x6_charDraw(Row, Column,tempShi+'0',ON);
  142.         Dogs102x6_charDraw(Row, Column+6,tempGe+'0',ON);
  143. }
  144. //-------------------------------------------//
  145. //函数名:游戏背景函数
  146. //入口:Void
  147. //出口:Void
  148. //功能:绘制游戏背景地图
  149. //-------------------------------------------//
  150. void GameBackground()
  151. {
  152.         uchar i;
  153.         for(i=0;i<MapHigh+1;i++)
  154.         {
  155.                 Dogs102x6_pixelDraw(0, i, ON);
  156.                 Dogs102x6_pixelDraw(MapWide+1, i, ON);
  157.         }
  158.         for(i=0;i<MapWide+2;i++)
  159.         {
  160.                 Dogs102x6_pixelDraw(i, 0, ON);
  161.                 Dogs102x6_pixelDraw(i, MapHigh+1, ON);
  162.         }
  163.         DisplayRamClear();
  164.         Dogs102x6_stringDraw(3, 10, "START",ON);
  165.         Dogs102x6_stringDraw(1, 51, "NEXT:",ON);
  166.         Dogs102x6_stringDraw(3, 51, "SPEED:--",ON);
  167.         Dogs102x6_stringDraw(5, 51, "SCORE:--",ON);
  168.         Number2BitDisplay(3,87,Speed);
  169.         Number2BitDisplay(5,87,Score);
  170. }
  171. //-------------------------------------------//
  172. //函数名:游戏Map清空
  173. //入口:Void
  174. //出口:Void
  175. //功能:清空游戏背景地图(不清空显存)
  176. //-------------------------------------------//
  177. void GameMapClear()
  178. {
  179.         uchar i,j;
  180.         for(i=0;i<MapHigh;i++)
  181.         {
  182.                 for(j=0;j<MapWide;j++)
  183.                 {
  184.                         Dogs102x6_pixelDraw(j+1, i+1, OFF);
  185.                 }
  186.         }
  187. }
  188. //-------------------------------------------//
  189. //函数名:系统初始化
  190. //入口:Void
  191. //出口:Void
  192. //功能:
  193. //-------------------------------------------//
  194. void SystemInit()
  195. {
  196.         WDTCTL = WDTPW + WDTHOLD;
  197.         P8DIR|=BIT1+BIT2;
  198.         P8OUT|=BIT1+BIT2;
  199.         P1DIR|=BIT0+BIT1+BIT2+BIT3+BIT4+BIT5;
  200.         P1OUT|=BIT0+BIT1+BIT2+BIT3+BIT4+BIT5;
  201.         InitKey();

  202.         UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO
  203.         UCSCTL4 |= SELA_2;                        // Set ACLK = REFO

  204.         __bis_SR_register(SCG0);                  // Disable the FLL control loop
  205.         UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  206.         UCSCTL1 = DCORSEL_7;                      // Select DCO range 50MHz operation
  207.         UCSCTL2 = FLLD_1 + 609;                   // Set DCO Multiplier for 25MHz(这里设置为20MHz适应液晶的SPI通信)
  208.                                                   // (N + 1) * FLLRef = Fdco
  209.                                                   // (762 + 1) * 32768 = 25MHz
  210.                                                   // Set FLL Div = fDCOCLK/2
  211.         __bic_SR_register(SCG0);                  // Enable the FLL control loop
  212.         TA1CCTL0 = CCIE;                          // CCR0 interrupt enabled
  213.         TA1CCR0 = 328-1;
  214.         TA1CTL = TASSEL_1 + MC_1 + TACLR;         // ACLK, upmode, clear TAR
  215.         _BIS_SR(GIE);
  216.         Dogs102x6_init();
  217.         Dogs102x6_clearScreen();
  218.         Dogs102x6_backlightInit();
  219.         Dogs102x6_setContrast(11);
  220.         Dogs102x6_setBacklight(liang);
  221. }
  222. //-------------------------------------------//
  223. //函数名:3x3点显示函数
  224. //入口:        x:x轴坐标
  225. //                y:y轴坐标
  226. //                mode:ON 打点;OFF 消点
  227. //出口:Void
  228. //功能:
  229. //-------------------------------------------//
  230. void Display3x3Pixels(uchar x,uchar y,uchar mode)
  231. {
  232.         x=3*x+1;
  233.         y=3*y+1;
  234.         Dogs102x6_pixelDraw(x, y, mode);
  235.         Dogs102x6_pixelDraw(x+1, y, mode);
  236.         Dogs102x6_pixelDraw(x+2, y, mode);
  237.         Dogs102x6_pixelDraw(x, y+1, mode);
  238.         Dogs102x6_pixelDraw(x+1, y+1, mode);
  239.         Dogs102x6_pixelDraw(x+2, y+1, mode);
  240.         Dogs102x6_pixelDraw(x, y+2, mode);
  241.         Dogs102x6_pixelDraw(x+1, y+2, mode);
  242.         Dogs102x6_pixelDraw(x+2, y+2, mode);
  243. }
  244. //-------------------------------------------//
  245. //函数名:显示像素点更改函数
  246. //入口:        Row:行数
  247. //                Column:列数
  248. //                mode:ON 打点;OFF 消点
  249. //出口:Void
  250. //功能:
  251. //-------------------------------------------//
  252. void ChangeRamBit(uchar Row,uchar Column,uchar mode)
  253. {
  254.         uint tempData;
  255.         tempData=(0x8000>>(Column%16));
  256.         if(mode==ON)
  257.                 cubeMap[Row]|=tempData;
  258.         else
  259.                 cubeMap[Row]&=~tempData;
  260. }
  261. //-------------------------------------------//
  262. //函数名:读取某个显示像素点位值函数
  263. //入口:        Row:行数
  264. //                Column:列数
  265. //出口:uchar 1:所选点位1,0:所选的点位0
  266. //功能:
  267. //-------------------------------------------//
  268. uchar ReadDisplayRamBit(uchar Row,uchar Column)
  269. {
  270.         uint tempData;
  271.         tempData=(0x8000>>(Column%16));
  272.         if(cubeMap[Row]&tempData)
  273.                 return 1;
  274.         else
  275.                 return 0;
  276. }
  277. //-------------------------------------------//
  278. //函数名:下一个方块显示函数
  279. //入口:        x:x轴坐标
  280. //                y:y轴坐标
  281. //                *p:图形字模数据指针
  282. //出口:Void
  283. //功能:
  284. //-------------------------------------------//
  285. void showNextCube(uchar const * p,uchar x,uchar y)
  286. #define NexPoinX        27                                                        //下一个图形显示的X坐标
  287. #define NexPoinY        2                                                        //下一个图形显示的Y坐标
  288. {
  289. uchar i,j,temp;
  290.   for(i=0;i<4;i++)
  291.    {
  292.       temp=0x08;
  293.       for(j=0;j<4;j++)
  294.       {
  295.         if(p[i] & temp)
  296.                 Display3x3Pixels(x+j,y+i,ON);
  297.         else
  298.                 Display3x3Pixels(x+j,y+i,OFF);
  299.         temp>>=1;
  300.       }
  301.    }
  302. }
  303. //-------------------------------------------//
  304. //函数名:显示函数
  305. //入口:Void
  306. //出口:Void
  307. //功能:将显存的内容写入显示器显示
  308. //-------------------------------------------//
  309. void showCubeMap(void)
  310. {
  311. uchar hang,lie;
  312. for(hang=0;hang<MAXHANG;hang++)
  313.   {
  314.    if(cubeMap[hang]!=0)                                                        //跳过某行全为零的地方
  315.    for(lie=0;lie<MAXLIE;lie++)
  316.     {
  317.            if(cubeMap[hang]&(0x8000>>(lie%16)))
  318.                    Display3x3Pixels(lie,hang,ON);
  319.     }
  320.   }
  321. }
  322. //-------------------------------------------//
  323. //函数名:产生新方块函数
  324. //入口:Void
  325. //出口:Void
  326. //功能:
  327. //-------------------------------------------//
  328. void createCube(void)
  329. {
  330.   static uchar next=0;
  331.   this.cube=next;
  332.   next=randomNumber%7;                                                          //产生随机数
  333.   this.row=0;                                                                          //初始行为0
  334.   this.column=6;                                                                  //初始列为6
  335.   this.state=0;                                                                          //初始状态为0
  336.   this.box=cube+16*this.cube;                                          //设定方块指针起始地址
  337.   showNextCube(cube+16*next,NexPoinX,NexPoinY);        //提示区显示下一个方块
  338.   timeA=0;
  339.   downflag=0;
  340. }
  341. //-------------------------------------------//
  342. //函数名:写显存函数
  343. //入口:mode:ON 打点;OFF 消点
  344. //出口:Void
  345. //功能:将数据写入显存,同时写入显示器显示
  346. //-------------------------------------------//
  347. void writeCubeToMap(uchar mode)
  348. {
  349.         uchar tempData,tempRow,tempColumn,i,j,k=0;
  350.         for(i=0;i<4;i++)
  351.         {
  352.                 tempData=this.box[i];
  353.                 if(tempData==0)
  354.                         continue;
  355.                 for(j=0;j<4;j++)
  356.                 {
  357.                         if(tempData&0x08)
  358.                         {
  359.                                 tempRow=this.row+k;
  360.                                 tempColumn=this.column+j;
  361.                                 ChangeRamBit(tempRow,tempColumn,mode);
  362.                                 Display3x3Pixels(tempColumn,tempRow,mode);
  363.                         }
  364.                         tempData<<=1;
  365.                 }
  366.                 k++;
  367.         }
  368. }
  369. //-------------------------------------------//
  370. //函数名:方块边沿检测函数
  371. //入口:Void
  372. //出口:uchar 0:可以继续移动        1:到底,停止移动
  373. //功能:
  374. //-------------------------------------------//
  375. uchar checkClask(void)
  376. {
  377.         uchar tempData,tempRow,tempColumn,i,j,k=0;
  378.         for(i=0;i<4;i++)
  379.         {
  380.                 tempData=this.box[i];
  381.                 if(tempData==0)                                                                                        //跳过全为零的行
  382.                         continue;
  383.                 for(j=0;j<4;j++)
  384.                 {
  385.                         if(tempData&0x08)
  386.                         {
  387.                                 tempRow=this.row+k;
  388.                                 tempColumn=this.column+j;
  389.                                 if        (
  390.                                                 ReadDisplayRamBit(tempRow,tempColumn)        //与边上的方块接触
  391.                                                 ||(tempRow>=MAXHANG)                                        //到了最底部
  392.                                                 ||(tempColumn>=MAXLIE)                                        //到了最右边
  393.                                                 ||(tempColumn==255)                                                //到了最左边
  394.                                         )
  395.                                         return 1;                                                                        //返回1,停止移动
  396.                         }
  397.                         tempData<<=1;
  398.                 }
  399.                 k++;
  400.         }
  401.         return 0;                                                                                                //返回0,可以继续移动
  402. }
  403. //-------------------------------------------//
  404. //函数名:地图检测函数
  405. //入口:Void
  406. //出口:Void
  407. //功能:检测地图中是否有满行,有的话就消行,加分,一定分后加速,同时刷一次屏
  408. //-------------------------------------------//
  409. void CheckMap()
  410. {
  411.         uchar fullFlag=0;
  412.         static uchar tempScore=0,tempSpeed=0;
  413.         char i,j;
  414.         for(i=MAXHANG-1;i>0;i--)
  415.         {
  416.                 if(cubeMap[i]==0xffff)
  417.                 {
  418.                         fullFlag++;
  419.                         for(j=i;j>0;j--)
  420.                         {
  421.                                 if(j>0)
  422.                                         cubeMap[j]=cubeMap[j-1];
  423.                                 else
  424.                                         cubeMap[j]=0;
  425.                         }
  426.                         i++;
  427.                 }
  428.         }
  429.         tempScore=Score;
  430.         tempSpeed=Speed;
  431.         switch(fullFlag)
  432.         {
  433.         case 1:Score++;break;
  434.         case 2:Score+=2;break;
  435.         case 3:Score+=4;break;
  436.         case 4:Score+=6;break;
  437.         default:break;
  438.         }
  439.         if(Score>99)
  440.         {
  441.                 Speed++;
  442.                 if(Speed>9)
  443.                         Speed=1;
  444.                 Score=0;
  445.         }
  446.         if(tempScore!=Score)
  447.                 Number2BitDisplay(5,87,Score);
  448.         if(tempSpeed!=Speed)
  449.                 Number2BitDisplay(3,87,Speed);
  450.         if(fullFlag)
  451.         {
  452.                 GameMapClear();
  453.                 showCubeMap();
  454.         }
  455. }
  456. //-------------------------------------------//
  457. //函数名:方块左移函数
  458. //入口:Void
  459. //出口:Void
  460. //功能:
  461. //-------------------------------------------//
  462. void moveLeft(void)
  463. {
  464.         writeCubeToMap(OFF);
  465.           this.column--;
  466.           if(checkClask())
  467.                   this.column++;
  468.           writeCubeToMap(ON);
  469. }
  470. //-------------------------------------------//
  471. //函数名:方块右移函数
  472. //入口:Void
  473. //出口:Void
  474. //功能:
  475. //-------------------------------------------//
  476. void moveRigh(void)
  477. {
  478.         writeCubeToMap(OFF);
  479.         this.column++;
  480.         if(checkClask())
  481.                 this.column--;
  482.         writeCubeToMap(ON);
  483. }
  484. //-------------------------------------------//
  485. //函数名:方块下移函数
  486. //入口:Void
  487. //出口:uchar 到底返回1,否则返回0;
  488. //功能:
  489. //-------------------------------------------//
  490. uchar moveDown(void)
  491. {
  492.         writeCubeToMap(OFF);
  493.         this.row++;
  494.         if(checkClask())                                //到底
  495.         {
  496.                 this.row--;
  497.                 writeCubeToMap(ON);
  498.                 CheckMap();                                        //是否消行
  499.                 return 1;
  500.         }
  501.         else
  502.         {
  503.                 writeCubeToMap(ON);
  504.                 return 0;
  505.         }
  506. }
  507. //-------------------------------------------//
  508. //函数名:方块翻转函数
  509. //入口:Void
  510. //出口:Void
  511. //功能:
  512. //-------------------------------------------//
  513. void cubeRotation(void)
  514. {
  515.         uchar temp;
  516.         temp=this.state;
  517.         writeCubeToMap(OFF);
  518.         this.state=++this.state%4;
  519.         this.box=cube+16*this.cube+4*this.state;
  520.         if(checkClask())
  521.         {
  522.                 this.state=temp;
  523.                 this.box=cube+16*this.cube+4*this.state;
  524.         }
  525.         writeCubeToMap(ON);
  526. }
  527. //-------------------------------------------//
  528. //函数名:俄罗斯方块结束界面函数
  529. //入口:Void
  530. //出口:Void
  531. //功能:
  532. //-------------------------------------------//
  533. void TetrisGameOver()
  534. {
  535.         DisplayRamClear();
  536.         GameMapClear();
  537.         Score=0;
  538.         Speed=1;
  539.         Number2BitDisplay(5,87,Score);
  540.         Number2BitDisplay(3,87,Speed);
  541.         Dogs102x6_stringDraw(3, 13, "GAME",ON);
  542.         Dogs102x6_stringDraw(4, 13, "OVER",ON);
  543. }
  544. //-------------------------------------------//
  545. //函数名:俄罗斯方块游戏运行函数
  546. //入口:Void
  547. //出口:Void
  548. //功能:不阻塞CPU
  549. //-------------------------------------------//
  550. void TetrisGame()
  551. {
  552.         uchar temp=0;
  553.         static uchar Flag=0;
  554.         if(Flag==0)
  555.         {
  556.                 createCube();
  557.                 if(checkClask())
  558.                 {
  559.                         TetrisGameOver();
  560.                         delay_ms(1000);
  561.                         GameMapClear();
  562.                 }
  563.                 else
  564.                         writeCubeToMap(ON);
  565.                 Flag=1;
  566.         }
  567.         if(downflag&&Flag)
  568.         {
  569.                 downflag=0;
  570.                 if(moveDown())
  571.                 {
  572.                         Flag=0;
  573.                 }
  574.         }
  575.         temp=GetKey();
  576.         switch(temp)
  577.         {
  578.                 case KeyUP:cubeRotation();DigitalLedControl(0);
  579.                         break;
  580.                 case KeyDOWN:while(moveDown()==0);Flag=0;DigitalLedControl(1);
  581.                         break;
  582.                 case KeyLEFT:moveLeft();DigitalLedControl(2);
  583.                         break;
  584.                 case KeyRIGHT:moveRigh();DigitalLedControl(3);
  585.                         break;
  586.                 case KeyBACK:DigitalLedControl(4);liang=++liang%12;Dogs102x6_setBacklight(liang);
  587.                         break;
  588.                 case KeyMEU:DigitalLedControl(5);
  589.                         break;
  590.                 case 0:
  591.                         break;
  592.                 default:
  593.                         break;
  594.         }
  595. }
  596. void main(void)
  597. {
  598.         SystemInit();
  599.         GameBackground();
  600.         DisplayRamClear();
  601.         GameMapClear();
  602.         showCubeMap();
  603.         while(1)
  604.         {
  605.                 TetrisGame();
  606.         }
  607. }
  608. #pragma vector=TIMER1_A0_VECTOR
  609. __interrupt void TIMER1_A0_ISR(void)
  610. {
  611.         randomNumber=++randomNumber%100;
  612.         if(downflag==0)
  613.                 timeA++;
  614.         if(timeA==(10-Speed)*10)
  615.         {
  616.                 timeA=0;
  617.                 downflag=1;
  618.         }
  619. }
复制代码




全部源码打包下载:
俄罗斯方块游戏.rar (75.65 KB, 下载次数: 85)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:445441 发表于 2018-12-13 21:54 | 只看该作者
这个我拿来用不了啊 一直显示文件路径有问题
program “make” not found in PATH
回复

使用道具 举报

板凳
ID:189966 发表于 2020-3-30 15:58 | 只看该作者
你好,电路图怎么找、
回复

使用道具 举报

地板
ID:1016682 发表于 2022-4-8 12:05 | 只看该作者
四个独立按键怎么装呀
回复

使用道具 举报

5#
ID:1092538 发表于 2023-9-3 16:20 | 只看该作者
15538053902 发表于 2020-3-30 15:58
你好,电路图怎么找、

电路图可以在德州仪器的单片机上找产品信息
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表