久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3455|回復: 0
打印 上一主題 下一主題
收起左側

12864 屏幕應用 鍵盤 貪吃蛇 俄羅斯方塊

[復制鏈接]
跳轉到指定樓層
樓主
ID:168624 發(fā)表于 2017-5-1 10:15 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式

下載:
蛇.rar (86 KB, 下載次數(shù): 25)



單片機源程序:
  1. //12864并行接口參考程序,控制器st7920  
  2. #include "reg52.h"
  3. #include "Lcd12864.h"
  4. #include "Key.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int

  7. static unsigned long Seed = 1;
  8. #define A 48271L
  9. #define M 2147483647L
  10. #define Q (M / A)
  11. #define R (M % A)
  12. /************************************
  13. 偽隨機數(shù)發(fā)生器
  14. *************************************/
  15. double Random(void)
  16. {
  17.         long TmpSeed;
  18.         TmpSeed=A*(Seed%Q)-R*(Seed/Q);
  19.         if(TmpSeed>=0)
  20.                 Seed=TmpSeed;
  21.         else
  22.                 Seed=TmpSeed+M;
  23.         return (double)Seed/M;
  24. }

  25. /**************************************
  26. 為偽隨機數(shù)發(fā)生器播種
  27. ***************************************/
  28. void InitRandom(unsigned long InitVal)
  29. {
  30.         Seed=InitVal;
  31. }

  32. //延時子程序
  33. void Delay(unsigned int t)
  34. {  
  35.         unsigned int i,j;
  36.         for(i=0;i<t;i++)
  37.                 for(j=0;j<10;j++);   
  38. }

  39. #define LGOU 0
  40. #define RGOU 1
  41. #define RZ        2
  42. #define LZ        3
  43. #define T        4
  44. #define GUN 5
  45. #define BOX 6
  46. unsigned int idata num[19+2]={
  47. 0xfff,//第1行,最下面
  48. 0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,
  49. 0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,//第2行到第20行共19行
  50. 0xfff//第21行,最上面

  51. };//定義共21行,其中num[0]為下墻壁行,num[20]為上墻壁行,每行12格,最左一格為左墻壁列,最右一格為右墻壁列
  52. unsigned char code Block[28][2]={
  53. /*
  54. *   口     口口口   口口
  55. *   口     口         口      口
  56. *   口口              口  口口口      
  57. */
  58. {0x88,0xc0},{0xe8,0x00},{0x62,0x20},{0x02,0xe0},
  59. /*
  60. *   口        口口 口口口
  61. *   口 口     口       口
  62. * 口口 口口口 口   
  63. */
  64. {0x22,0x60},{0x08,0xe0},{0xc8,0x80},{0xe2,0x00},  
  65. /*
  66. *   口
  67. *   口口         口口
  68. *     口       口口
  69. */
  70. {0x8c,0x40},{0x6c,0x00},{0x8c,0x40},{0x6c,0x00},
  71. /*
  72. *   口        口口
  73. * 口口          口口
  74. * 口
  75. */
  76. {0x4c,0x80},{0xc6,0x00},{0x4c,0x80},{0xc6,0x00},  
  77. /*
  78. *          口                口
  79. *   口     口口   口口口   口口
  80. * 口口口   口       口       口
  81. */
  82. {0x04,0xe0},{0x8c,0x80},{0xe4,0x00},{0x26,0x20},
  83. /*口
  84. * 口
  85. * 口       口口口口
  86. * 口
  87. */
  88. {0x44,0x44},{0x0f,0x00},{0x44,0x44},{0x0f,0x00},  
  89. /*
  90. * 口口
  91. * 口口
  92. */  
  93. {0x06,0x60},{0x06,0x60},{0x06,0x60},{0x06,0x60}
  94. };

  95. #define PASSSCORE 20
  96. struct Jimu
  97. {
  98.         unsigned int dat;
  99.         char x;
  100.         unsigned char y;
  101.         unsigned char type;
  102.         unsigned char change;
  103. }Sign[3];//積木結構體

  104. unsigned char SysFlag=0;
  105. #define NEWSIGNFLAG 0
  106. #define DEADFLAG 1
  107. #define PAUSEFLAG 2

  108. unsigned char Score=0;
  109. unsigned char Level=1;
  110. unsigned char DelayCnt=5;
  111. unsigned char KeyBuffer=0;
  112. #define RESEVER 1
  113. #define CHANGE 2
  114. #define DOWN 3
  115. #define LEFT 4
  116. #define RIGHT 5
  117. #define PAUSE 6

  118. /*********************************
  119. 初始化MPU
  120. **********************************/
  121. void InitCpu(void)
  122. {
  123.         TMOD=0x0;
  124.         TH0=0;
  125.         TL0=0;
  126.         TR0=1;
  127.         ET0=1;
  128.         EA=1;
  129. }

  130. /*****************************
  131. 定時中斷服務子程序
  132. ******************************/
  133. void Timer0Int(void) interrupt 1
  134. {
  135.         switch(OSReadKey())
  136.         {
  137.                 case 9:
  138.                                 KeyBuffer=PAUSE;
  139.                                 break;
  140.                 case 13:
  141.                                 KeyBuffer=CHANGE;
  142.                                 break;
  143.                 case 17:
  144.                                 KeyBuffer=DOWN;
  145.                                 break;
  146.                 case 21:
  147.                                 KeyBuffer=RIGHT;
  148.                                 break;
  149.                    case 25:
  150.                                 KeyBuffer=LEFT;
  151.                                 break;
  152.                 default:
  153.                                 break;
  154.         }
  155. }

  156. /******************************
  157. 畫墻壁,初始化界面
  158. *******************************/
  159. void DrawBoard(void)
  160. {
  161.         unsigned char n;
  162.         for(n=0;n<12;n++)
  163.         {
  164.                 Lcd_Rectangle(3*n,0,3*n+2,2,1);
  165.                 Lcd_Rectangle(3*n,60,3*n+2,62,1);
  166.         }
  167.         for(n=0;n<20;n++)
  168.         {
  169.                 Lcd_Rectangle(0,3*n,2,3*n+2,1);
  170.                 Lcd_Rectangle(33,3*n,35,3*n+2,1);               
  171.         }
  172.         Lcd_WriteStr(4,0,"TOTO原創(chuàng)");
  173.         Lcd_WriteStr(3,2,"Score:");
  174.         Lcd_WriteStr(3,3,"Level:");
  175. }

  176. /***********************************
  177. 游戲結束處理
  178. ************************************/
  179. void GameOver(void)
  180. {
  181.         if((SysFlag&(1<<DEADFLAG))!=0)
  182.                 Lcd_WriteStr(3,1,"You Fail");
  183.         else
  184.                 Lcd_WriteStr(3,1,"You Pass");
  185. }

  186. unsigned int code MaskTab[16]={
  187. 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
  188. 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000
  189. };

  190. /**********************************
  191. 根據(jù)積木圖標左下坐標X,Y來畫出積木圖標
  192. ***********************************/
  193. void DrawSign(struct Jimu Temp,unsigned char DrawMode)
  194. {
  195.         unsigned char m,n;
  196.         for(m=0;m<4;m++)
  197.                 for(n=0;n<4;n++)
  198.                 {
  199.                         if((Temp.dat&MaskTab[4*m+n])!=0)
  200.                                 Lcd_Rectangle(Temp.x+n*3,Temp.y-2-3*m,Temp.x+n*3+2,Temp.y-3*m,DrawMode);
  201.                 }
  202. }

  203. /********************************
  204. 將積木圖標值融入num數(shù)據(jù)中
  205. 也即把積木圖標固定,無法再下降
  206. *********************************/
  207. FixSign(void)
  208. {
  209.         unsigned char m,n;
  210.         for(m=0;m<4;m++)//行循環(huán)
  211.                 for(n=0;n<4;n++)//列循環(huán)
  212.                 {
  213.                         if((Sign[0].dat&MaskTab[4*m+n])!=0)
  214.                         {
  215.                                 num[20-(Sign[0].y-2)/3+m]|=MaskTab[11-Sign[0].x/3-n];
  216.                         }
  217.                 }
  218. }

  219. /********************************
  220. 判斷積木圖標中方塊是否與障礙方塊重合
  221. *********************************/
  222. unsigned char CheckIf(void)
  223. {
  224.         unsigned char m,n;
  225.         for(m=0;m<4;m++)//行循環(huán)
  226.                 for(n=0;n<4;n++)//列循環(huán)
  227.                 {
  228.                         if((Sign[1].dat&MaskTab[4*m+n])!=0)
  229.                         {
  230.                                 if((num[20-(Sign[1].y-2)/3+m]&MaskTab[11-Sign[1].x/3-n])!=0)
  231.                                         return 0;
  232.                         }
  233.                 }
  234.         return 1;
  235. }

  236. /********************************
  237. 判斷積木圖標是否可以繼續(xù)下降一格
  238. ********************************/
  239. unsigned char CheckIfDown(void)
  240. {
  241.         Sign[1]=Sign[0];//
  242.         Sign[1].y+=3;//假設下降一格       
  243.         return CheckIf();
  244.        
  245. }

  246. /********************************
  247. 判斷積木圖標是否可以向左移動
  248. *********************************/
  249. unsigned char CheckIfLeft(void)
  250. {
  251.         Sign[1]=Sign[0];
  252.         Sign[1].x-=3;       
  253.         return CheckIf();
  254. }

  255. /********************************
  256. 判斷積木圖標是否可以向右移動
  257. *********************************/
  258. unsigned char CheckIfRight(void)
  259. {
  260.         Sign[1]=Sign[0];
  261.         Sign[1].x+=3;       
  262.         return CheckIf();
  263. }

  264. /********************************
  265. 判斷是否可以旋轉
  266. *********************************/
  267. unsigned char CheckIfRoll(void)
  268. {
  269.         unsigned char i;
  270.         unsigned int Temp;
  271.         Sign[1]=Sign[0];
  272.         if(++Sign[1].change>3)
  273.                 Sign[1].change=0;
  274.            i=Sign[1].type*4+Sign[1].change;
  275.         Temp=(unsigned int)Block[i][0]<<8;
  276.         Temp=Temp|Block[i][1];
  277.         Sign[1].dat=Temp;
  278.        
  279.         return CheckIf();
  280. }

  281. /********************************
  282. 尋找滿格的行并做消除處理
  283. 最多尋找4個滿行并做消除
  284. *********************************/
  285. void DelFull(void)
  286. {
  287.         unsigned char m,n;
  288.         unsigned char Temp;
  289.         unsigned char Flag=0;
  290.         Temp=(Sign[0].y-2)/3;
  291.         if(Temp>=20)//防止越過了下邊界
  292.                 Temp=1;
  293.         else
  294.                 Temp=20-Temp;
  295.         for(n=Temp+3;n>=Temp;n--)//積木圖標的最頂行開始尋找滿行比較有利于運算
  296.         {
  297.                 if(num[n]==0xfff)
  298.                 {
  299.                         Flag=1;
  300.                         for(m=n+1;m<=19;m++)
  301.                         {
  302.                                 num[m-1]=num[m];
  303.                         }
  304.                         num[m]=0x801;
  305.                         Score++;//每找到一個滿行,則分數(shù)加1
  306.                 }
  307.         }
  308.         if(Flag)//為加速而設置并判斷的標志,有已固定的積木有滿格消行變化則重畫積木界面
  309.         {
  310.                 for(m=Temp;m<=19;m++)//為加速,不必要重第一行重畫起,只需要從積木圖標最下行開始往上的重畫
  311.                         for(n=1;n<=10;n++)
  312.                         {
  313.                                 if((num[m]&MaskTab[n])==0)
  314.                                 {       
  315.                                         if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)!=0)//為加速而做的讀象素操作
  316.                                         {
  317.                                                 Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,0);
  318.                                         }
  319.                                 }
  320.                                    else
  321.                                 {
  322.                                         if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)==0)//為加速而做的讀象素操作
  323.                                         {
  324.                                                 Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,1);
  325.                                         }
  326.                                 }
  327.                         }
  328.         }
  329. }


  330. /*******************************
  331. 隨機產(chǎn)生一個積木圖標放到預產(chǎn)生區(qū)域并顯示出來
  332. ********************************/
  333. void CreatSign(void)
  334. {
  335.         unsigned char n;
  336.         unsigned int Temp;

  337.         DrawSign(Sign[2],0);//先清除

  338.         n=Random()*28;
  339.         Temp=(unsigned int)Block[n][0]<<8;
  340.         Temp=Temp|Block[n][1];
  341.         Sign[2].dat=Temp;
  342.         Sign[2].x=45;
  343.         Sign[2].y=4*3+2;
  344.         Sign[2].type=n/4;
  345.         Sign[2].change=n%4;
  346.         DrawSign(Sign[2],1);//后畫出
  347. }

  348. void PrintScore(void)
  349. {
  350.         unsigned char Str[3];
  351.         Str[0]=(Score/10)|0x30;
  352.         Str[1]=(Score%10)|0x30;
  353.         Str[2]=0;
  354.         Lcd_WriteStr(6,2,Str);
  355. }

  356. void PrintLevel(void)
  357. {
  358.         unsigned char Str[3];
  359.         Str[0]=(Level/10)|0x30;
  360.         Str[1]=(Level%10)|0x30;
  361.         Str[2]=0;
  362.         Lcd_WriteStr(6,3,Str);
  363. }

  364. /********************************
  365. 游戲的具體過程,也是貪吃蛇算法的關鍵部分
  366. *********************************/
  367. void GamePlay(void)
  368. {
  369.         unsigned char m,n;
  370.         unsigned int Temp;
  371.         SysFlag|=1<<NEWSIGNFLAG;//剛開始初始化為需要產(chǎn)生新的積木圖標
  372.         InitRandom(TL0);
  373.         Lcd_WriteStr(3,1,"Playing");
  374.         PrintScore();
  375.         PrintLevel();
  376.         CreatSign();
  377.         while(1)
  378.         {       
  379.                 if((SysFlag&(1<<NEWSIGNFLAG))==1)//判是否需要產(chǎn)生新的積木圖標
  380.                 {
  381.                         SysFlag&=~(1<<NEWSIGNFLAG);
  382.                         Sign[0]=Sign[2];
  383.                         CreatSign();
  384.                         Sign[0].x=12;
  385.                         Sign[0].y=14;

  386.                         for(m=0;m<4;m++)//行循環(huán)
  387.                         {
  388.                                 for(n=0;n<4;n++)//列循環(huán)
  389.                                 {
  390.                                         if((Sign[0].dat&MaskTab[15-m*4-n])==0)
  391.                                                 break;
  392.                                 }
  393.                                 if(n==4)
  394.                                         Sign[0].y-=3;
  395.                         }//將積木圖標出現(xiàn)置頂
  396.                        
  397.                         for(m=0;m<4;m++)//行循環(huán)
  398.                                 for(n=0;n<4;n++)//列循環(huán)
  399.                                 {
  400.                                         if((Sign[0].dat&MaskTab[4*m+n])!=0)
  401.                                         {
  402.                                                 if((num[20-(Sign[0].y-2)/3+m]&MaskTab[11-Sign[0].x/3-n])!=0)
  403.                                                         SysFlag|=1<<DEADFLAG;
  404.                                         }
  405.                                 }
  406.                         if((SysFlag&(1<<DEADFLAG))!=0)
  407.                                 break;//如果產(chǎn)生新的積木圖標中的方塊與已固定好的方塊重合,則死亡。游戲結束
  408.                         DrawSign(Sign[0],1);       
  409.                 }
  410.                 switch(KeyBuffer)
  411.                 {
  412.                         case LEFT:
  413.                                         KeyBuffer=0;
  414.                                         if((SysFlag&(1<<PAUSEFLAG))==0)
  415.                                         {
  416.                                                 if(CheckIfLeft())
  417.                                                 {
  418.                                                         DrawSign(Sign[0],0);
  419.                                                         Sign[0].x-=3;
  420.                                                         DrawSign(Sign[0],1);
  421.                                                 }
  422.                                         }
  423.                                         else
  424.                                         {
  425.                                                 if(++Level>=10)
  426.                                                         Level=1;
  427.                                                 PrintLevel();
  428.                                         }
  429.                                         break;
  430.                         case RIGHT:
  431.                                         KeyBuffer=0;
  432.                                         if((SysFlag&(1<<PAUSEFLAG))==0)
  433.                                         {
  434.                                                 if(CheckIfRight())
  435.                                                 {
  436.                                                         DrawSign(Sign[0],0);
  437.                                                         Sign[0].x+=3;
  438.                                                         DrawSign(Sign[0],1);       
  439.                                                 }
  440.                                         }
  441.                                         else
  442.                                         {
  443.                                                 if(++Level>=10)
  444.                                                         Level=1;
  445.                                                 PrintLevel();
  446.                                         }
  447.                                         break;
  448.                         case DOWN:
  449.                                         KeyBuffer=0;
  450.                                         if((SysFlag&(1<<PAUSEFLAG))==0)
  451.                                         {
  452.                                                 if(CheckIfDown())//判斷是否能繼續(xù)下降一格
  453.                                                 {
  454.                                                         DrawSign(Sign[0],0);
  455.                                                         Sign[0].y+=3;
  456.                                                         DrawSign(Sign[0],1);       
  457.                                                 }
  458.                                         }
  459.                                         break;
  460.                         case CHANGE:
  461.                                         KeyBuffer=0;
  462.                                         if((SysFlag&(1<<PAUSEFLAG))==0)
  463.                                         {
  464.                                                 if(CheckIfRoll())
  465.                                                 {
  466.                                                         DrawSign(Sign[0],0);
  467.                                                         if(++Sign[0].change>3)
  468.                                                                 Sign[0].change=0;
  469.                                                            m=Sign[0].type*4+Sign[0].change;
  470.                                                         Temp=(unsigned int)Block[m][0]<<8;
  471.                                                         Temp=Temp|Block[m][1];
  472.                                                         Sign[0].dat=Temp;
  473.                                                         DrawSign(Sign[0],1);
  474.                                                 }
  475.                                         }
  476.                                         break;
  477.                            case PAUSE:
  478.                                         KeyBuffer=0;
  479.                                         SysFlag^=1<<PAUSEFLAG;
  480.                                         if((SysFlag&(1<<PAUSEFLAG))==0)
  481.                                         {
  482.                                                 Lcd_WriteStr(3,1,"          ");
  483.                                                 Lcd_WriteStr(3,1,"Playing");
  484.                                         }
  485.                                         else
  486.                                         {
  487.                                                 Lcd_WriteStr(3,1,"          ");
  488.                                                 Lcd_WriteStr(3,1,"Pause");       
  489.                                         }
  490.                                         break;
  491.                     default:
  492.                                         break;
  493.                 }
  494.                 if((SysFlag&(1<<PAUSEFLAG))!=0)
  495.                         continue;
  496.                 Delay(500);
  497.                 if(++DelayCnt>=2*(11-Level))
  498.                 {
  499.                         DelayCnt=0;
  500.                         if(CheckIfDown())//判斷是否能繼續(xù)下降一格
  501.                         {
  502.                                 DrawSign(Sign[0],0);
  503.                                 Sign[0].y+=3;
  504.                                 DrawSign(Sign[0],1);
  505.                         }
  506.                         else
  507.                         {
  508.                                 FixSign();
  509.                                 DelFull();
  510.                                 PrintScore();
  511.                                 if(Score>=PASSSCORE)
  512.                                 {
  513.                                         SysFlag&=~(1<<DEADFLAG);
  514.                                         break;//跳出玩游戲過程
  515.                                 }
  516.                                 SysFlag|=1<<NEWSIGNFLAG;//新的積木圖標產(chǎn)生標志置1
  517.                         }
  518.                 }
  519.         }
  520. }

  521. void Main()
  522. {  
  523.         InitCpu();//初始化CPU
  524.         Lcd_Reset(); //初始化LCD屏
  525.         Lcd_Clear(0);//清屏
  526.         DrawBoard();//畫界面
  527.         GamePlay();//玩游戲
  528.         GameOver();//游戲結束
  529.         while(1);//要想重玩,只能重啟,可繼續(xù)完善該游戲
  530. }

復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av国产精品 | 午夜影院普通用户体验区 | 成人免费视频 | 一级在线免费观看 | 久久夜夜 | 精品国产乱码久久久久久88av | 国产成人免费视频网站高清观看视频 | 久草福利| 女人牲交视频一级毛片 | 成人网av | 国产成人一区二区三区电影 | 三级视频网站 | 成人免费福利视频 | www.精品一区| 亚洲精品免费视频 | 国产成人精品久久 | 国产精品一级 | 日韩av在线免费 | 成人网av| 99婷婷| a a毛片| 国产精品久久在线观看 | 午夜影院黄 | 日本高清视频在线播放 | 99久久精品国产毛片 | 日韩成人中文字幕 | 凹凸日日摸日日碰夜夜 | 成年人在线视频 | 亚洲永久精品国产 | 在线免费观看黄色av | 中文字幕av一区 | 国产福利视频网站 | 日韩电影一区二区三区 | 中文字幕亚洲欧美 | 日韩免费毛片 | 日韩欧美电影在线 | 日韩在线观看网站 | 免费a v网站 | 欧美a级成人淫片免费看 | 亚洲欧洲综合av | 成人午夜精品一区二区三区 |