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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

原創51單片機俄羅斯方塊程序 12864屏顯示 代碼有詳細注釋

  [復制鏈接]
跳轉到指定樓層
樓主
給51黑電子論壇的朋友們分享一個很優秀的俄羅斯方塊程序,lcd12864屏幕 是用普通的51單片機做的,P3.4口,短按就可以開始運行了。效果如下圖所示:

完整的源碼下載:
俄羅斯方塊全部源碼.zip (147.88 KB, 下載次數: 599)



Tetris.c源程序文件內容:
  1. /*******************************************************
  2. * 文件名稱:Tetris.c
  3. * 單 片 機:STC89C52RC
  4. * 簡    述:使用LCD12864顯示的俄羅斯方塊程序
  5. * 功    能:計分,下一個方塊預覽,歡迎結束界面,長按連續左右移,暫停(按鍵Left+Turn)
  6. * 作    者:劉琦
  7. * 完成日期:4月21日
  8. * IO口設定:按鍵
  9.                         sbit key_sr_left=P3^7;
  10.                         sbit key_sr_turn=P3^6;
  11.                         sbit key_sr_right=P3^5;
  12.                         sbit key_sr_down=P3^4;
  13.                         LCD12864
  14.                         sbit RS_Port=P1^0;
  15.                         sbit RW_Port=P1^1;
  16.                         sbit E_Port=P2^5;
  17.                         sbit PSB_Port=P1^2;
  18.                         sbit RST_Port=P1^4;
  19.                         數碼管鎖存器
  20.                         sbit dula=P2^6;
  21.                         sbit wela=P2^7;

  22. *******************************************************/

  23. /*****************************頭文件區*****************************************************/
  24. #include<reg52.h>
  25. //#include"STC15F2K60S2.h"
  26. #include"task_key.h"
  27. #include"task_activation.h"
  28. #include"12864b.h"
  29. #include"TaskBlock.h"
  30. #include"Block.h"
  31. /*****************************宏定義區*****************************************************/

  32. //需要判斷是否刷新的任務總數
  33. //1KeyLeft,2KeyTurn,3KeyRight,4KeyDown,5TaskGoingDown,6KeyPause
  34. #define NUM_TASK_FLAG 7
  35. //需要定時刷新的任務總數
  36. //1TaskGoingDown,2KeyService
  37. #define NUM_TASK_REFRESH 3
  38. //刷新頻率
  39. #define TIME_PER_SEC 200                                                        //每次進入中斷的頻率,200Hz
  40. #define TIME_CLOCK 11059200                                                        //晶振頻率
  41. #define TIME_KEY_SERVICE_50HZ  TIME_PER_SEC/50          //按鍵服務頻率,0.02s
  42. #define TIME_TASKGOINGDOWN_2HZ  TIME_PER_SEC/2          //下落頻率,0.5s

  43. /******************************子函數聲明區***********************************************/

  44. void initial_myself(void);   
  45. void initial_peripheral(void);
  46. void delay100ms(void);        

  47. /******************************全局變量定義區***********************************************/
  48. unsigned char uc_state=1;//狀態標示:1歡迎界面,2等待開始界面,3下落界面,4死亡界面,5暫停界面
  49. enum Block{S1,S2,Z1,Z2,L1,L2,L3,L4,J1,J2,J3,J4,I1,I2,O1,T_1,T_2,T_3,T_4}enumBlock;//方塊編號
  50. unsigned char ucBlockNow=0;//當前方塊
  51. unsigned char ucBlockNext=0;//下一個方塊

  52. unsigned char ucFlagScreenChange=1;//界面變更標志,界面更改時置1,激活task_activation

  53. unsigned char ucCoordinate[2];//方塊的旋轉點坐標,橫H,豎S
  54. unsigned char xdata ucxMap[10][20];//整張屏幕的標記地圖,用來記錄未消除方塊位置,有方塊則為1
  55. unsigned char ucxBlockPosition[4][2];//方塊的4個小方塊坐標,[0][0],[0][1]為旋轉點坐標H,S

  56. unsigned int uc_delay_task_cnt[NUM_TASK_REFRESH];//任務刷新延遲
  57. unsigned char uc_flag_taskrefresh[NUM_TASK_FLAG];//任務刷新標志

  58. unsigned long int ucScore=0;//得分

  59. /******************************主函數開始***********************************************/
  60. void main(void)
  61. {
  62.         unsigned char i=0;
  63.         initial_myself();
  64.         delay100ms();   
  65.     initial_peripheral();


  66.         while(1)
  67.         {
  68.                 if(ucFlagScreenChange==1)//界面變更標志為1時,進行任務激活,防止一直刷新界面
  69.                 {
  70.                         task_activation(uc_state);
  71.                         ucFlagScreenChange=0;
  72.                 }
  73.                 if(uc_delay_task_cnt[2]==0)//20HZ頻率刷新key_service
  74.                 {
  75.                         task_key_service();
  76.                         ET0=0;//在中斷中也有可能變化的變量在更改前時先關閉中斷
  77.                         uc_delay_task_cnt[2]=TIME_KEY_SERVICE_50HZ;//延遲重置
  78.                         ET0=1;
  79.                 }
  80.                 if(uc_flag_taskrefresh[5]&&uc_delay_task_cnt[1]==0)//需要時,2HZ頻率刷新TaskGoingDown
  81.                 {
  82.                         if(!TaskGoingDown())//下落失敗
  83.                         {
  84.                                 //將當前方塊位置寫入Map
  85.                                 for(i=0;i<4;i++)
  86.                                 {
  87.                                         ucxMap[ ucxBlockPosition[i][0] ][ ucxBlockPosition[i][1] ]=1;
  88.                                 }
  89.                                 //調用消除方塊函數
  90.                                 TaskClear();
  91.                         }
  92.                         ET0=0;//在中斷中也有可能變化的變量在更改前時先關閉中斷
  93.                         uc_delay_task_cnt[1]=TIME_TASKGOINGDOWN_2HZ;//延遲重置
  94.                         ET0=1;
  95.                 }

  96.         }
  97. }

  98. //中斷函數
  99. void timer0(void) interrupt 1
  100. {
  101.         unsigned char i;
  102.         TR0=0;
  103.         TH0=255-TIME_CLOCK/TIME_PER_SEC/12/256;
  104.         TL0=255-TIME_CLOCK/TIME_PER_SEC/12%256;
  105.         //task_delay[]減到0時,相應的函數準備就緒
  106.         for(i=0;i<NUM_TASK_REFRESH;i++)
  107.         {
  108.                 if(uc_delay_task_cnt[i]!=0)//延遲不為0時才減
  109.                         {uc_delay_task_cnt[i]--;};
  110.         }
  111.         task_key_scan();//按鍵掃描函數,放在中斷中,保證準時掃描
  112.         TR0=1;
  113. }

  114. //初始化區
  115. void initial_myself(void)//第一區 初始化單片機
  116. {
  117.         unsigned char i;
  118.         for(i=0;i<NUM_TASK_REFRESH;i++)uc_delay_task_cnt[i]=0;//初始化讓所有任務就緒
  119.         TMOD=0X21; //定時器0為16位不自動重裝,用來定時;定時器1為8位自動重裝,用來產生隨機數
  120.         TH0=255-TIME_CLOCK/TIME_PER_SEC/12/256;
  121.         TL0=255-TIME_CLOCK/TIME_PER_SEC/12%256;
  122.         TH1=0;
  123.         TL1=0;
  124. }

  125. void initial_peripheral(void) //第二區 初始化外圍
  126. {
  127.         Lcd_Init();//初始化12864
  128.         EA=1;     //開總中斷
  129.         ET0=1;    //允許定時器0中斷,定時器1無需開啟中斷
  130.     TR0=1;    //啟動定時器0
  131.     TR1=1;         //啟動定時器1
  132. }

  133. void delay100ms(void)                //@11.0592MHz
  134. {
  135.         unsigned char i, j, k;

  136.         ;
  137.         ;
  138.         i = 5;
  139.         j = 52;
  140.         k = 195;
  141.         do
  142.         {
  143.                 do
  144.                 {
  145.                         while (--k);
  146.                 } while (--j);
  147.         } while (--i);
  148. }
復制代碼
  1. /*******************************************************
  2. * 文件名稱:task_activation.c
  3. * 單 片 機:STC89C52RC
  4. * 簡    述:任務激活子程序,uc_state:1歡迎界面,2等待界面,3下落界面,4死亡界面
  5. * 作    者:劉琦
  6. * 完成日期:2015年5月1日
  7. *******************************************************/
  8. #include"reg52.h"
  9. #include"12864b.h"
  10. #include"tetris.h"
  11. #include"TaskBlock.h"
  12. #include"Score.h"
  13. //#include"STC15F2K60S2.h"

  14. #define  xchar unsigned char code

  15. //歡迎詞
  16. xchar CorpInf[]=
  17. {
  18.         "來玩俄羅斯方塊!"
  19. };
  20. //死亡詞
  21. xchar CorpInf1[]=
  22. {
  23.         "不好意思你死了!"
  24. };

  25. void task_activation(unsigned char state)        
  26. {
  27.         unsigned char i=0,j=0;
  28.         switch(state)
  29.         {
  30.                 case 1: //歡迎界面
  31.                                 DisGBStr(CorpInf);                                //寫入歡迎詞
  32.                         //當前界面需要刷新的任務
  33.                                 //1KeyLeft,2KeyTurn,3KeyRight,4KeyDown,5TaskGoingDown,6KeyPause
  34.                                 uc_flag_taskrefresh[1]=0;               
  35.                             uc_flag_taskrefresh[2]=0;
  36.                             uc_flag_taskrefresh[3]=0;
  37.                             uc_flag_taskrefresh[4]=1;
  38.                             uc_flag_taskrefresh[5]=0;
  39.                             uc_flag_taskrefresh[6]=0;
  40.                             break;
  41.                 case 2:        //等待界面
  42.                                 //清空所有顯示
  43.                                 Cram_Off();                //清空文本顯示
  44.                                 Clr_GDRAM();        //清空繪圖顯示
  45.                                 //畫出邊框
  46.                                 DrawLineY(7,1,62,1);
  47.                                 DrawLineX(7,127,1,1);
  48.                                 DrawLineX(7,127,62,1);

  49.                                 //將地圖數據清空
  50.                                 for(i=0;i<10;i++)
  51.                                 {
  52.                                         for(j=0;j<20;j++)
  53.                                         {
  54.                                                 ucxMap[i][j]=0;
  55.                                         }
  56.                                 }

  57.                                 ucScore=0;//計分清0

  58.                         //當前界面需要刷新的任務
  59.                                 //1KeyLeft,2KeyTurn,3KeyRight,4KeyDown,5TaskGoingDown,6KeyPause
  60.                         uc_flag_taskrefresh[1]=0;
  61.                             uc_flag_taskrefresh[2]=0;
  62.                             uc_flag_taskrefresh[3]=0;
  63.                             uc_flag_taskrefresh[4]=1;
  64.                             uc_flag_taskrefresh[5]=0;
  65.                             uc_flag_taskrefresh[6]=0;
  66.                             break;
  67.                 case 3:        //下落界面
  68.                                 TaskScore ();                //寫分,刷新最開始的0000000
  69.                                 TaskComingNew();        //出新方塊
  70.                         //當前界面需要刷新的任務
  71.                                 //1KeyLeft,2KeyTurn,3KeyRight,4KeyDown,5TaskGoingDown,6KeyPause
  72.                                 uc_flag_taskrefresh[1]=1;
  73.                             uc_flag_taskrefresh[2]=1;
  74.                             uc_flag_taskrefresh[3]=1;
  75.                             uc_flag_taskrefresh[4]=1;
  76.                             uc_flag_taskrefresh[5]=1;
  77.                             uc_flag_taskrefresh[6]=1;
  78.                             break;
  79.                 case 4:        //死亡界面
  80.                                 Cram_Off();                //清空文本顯示
  81.                                 Clr_GDRAM();        //清空繪圖顯示
  82.                                 DisGBStr(CorpInf1);
  83.                         //當前界面需要刷新的任務
  84.                                 //1KeyLeft,2KeyTurn,3KeyRight,4KeyDown,5TaskGoingDown,6KeyPause
  85.                         uc_flag_taskrefresh[1]=0;
  86.                             uc_flag_taskrefresh[2]=0;
  87.                             uc_flag_taskrefresh[3]=0;
  88.                             uc_flag_taskrefresh[4]=1;
  89.                             uc_flag_taskrefresh[5]=0;
  90.                             uc_flag_taskrefresh[6]=0;
  91.                             break;
  92.                 case 5:        //暫停界面
  93.                         //當前界面需要刷新的任務
  94.                                 //1KeyLeft,2KeyTurn,3KeyRight,4KeyDown,5TaskGoingDown,6KeyPause
  95.                         uc_flag_taskrefresh[1]=0;
  96.                             uc_flag_taskrefresh[2]=0;
  97.                             uc_flag_taskrefresh[3]=0;
  98.                             uc_flag_taskrefresh[4]=1;
  99.                             uc_flag_taskrefresh[5]=0;
  100.                             uc_flag_taskrefresh[6]=0;
  101.                             break;
  102.                 default:
  103.                             break;
  104.         }
  105. }
復制代碼
  1. #include"reg52.h"
  2. //#include"STC15F2K60S2.h"
  3. #include"tetris.h"
  4. #include"Block.h"
  5. #include"TaskBlock.h"

  6. #define CONST_KEY_TIME 10    //按鍵去抖動延時的時間

  7. //#define const_time_0_25s  111   //0.25秒鐘的時間需要的定時中斷次數
  8. //#define const_time_0_5s     222   //0.5秒鐘的時間需要的定時中斷次數

  9. #define const_time_0_25s  60   //0.125秒鐘的時間需要的定時中斷次數
  10. #define const_time_0_5s     60   //0.125秒鐘的時間需要的定時中斷次數


  11. sbit key_sr_left=P3^7;
  12. sbit key_sr_turn=P3^6;
  13. sbit key_sr_right=P3^5;
  14. sbit key_sr_down=P3^4;

  15. unsigned char ucKeySec=0;   //被觸發的按鍵編號

  16. unsigned int  uiKeyTimeCnt_left=0; //按鍵去抖動延時計數器
  17. unsigned int  uiKeyCtntyCnt_left=0; //按鍵連續觸發的間隔延時計數器
  18. unsigned char ucKeyLock_left=0; //按鍵觸發后自鎖的變量標志

  19. unsigned int  uiKeyTimeCnt_turn=0; //按鍵去抖動延時計數器
  20. //unsigned int  uiKeyCtntyCnt_turn=0; //按鍵連續觸發的間隔延時計數器
  21. unsigned char ucKeyLock_turn=0; //按鍵觸發后自鎖的變量標志

  22. unsigned int  uiKeyTimeCnt_right=0; //按鍵去抖動延時計數器
  23. unsigned int  uiKeyCtntyCnt_right=0; //按鍵連續觸發的間隔延時計數器
  24. unsigned char ucKeyLock_right=0; //按鍵觸發后自鎖的變量標志

  25. unsigned int  uiKeyTimeCnt_down=0; //按鍵去抖動延時計數器
  26. unsigned char ucKeyLock_down=0; //按鍵觸發后自鎖的變量標志

  27. unsigned int  uiKeyTimeCnt_pause=0; //按鍵去抖動延時計數器
  28. unsigned char ucKeyLock_pause=0; //按鍵觸發后自鎖的變量標志

  29. //放在中斷中,其中的每個按鍵的標志位為1時才刷新
  30. void task_key_scan(void)
  31. {
  32.         if(uc_flag_taskrefresh[1])
  33.         {
  34.                 if(key_sr_left==1)//left
  35.                   {
  36.                      ucKeyLock_left=0;
  37.                      uiKeyTimeCnt_left=0;
  38.                          uiKeyCtntyCnt_left=0;   
  39.                  }
  40.             else if(ucKeyLock_left==0)
  41.                  {
  42.                      uiKeyTimeCnt_left++;
  43.                      if(uiKeyTimeCnt_left>CONST_KEY_TIME)
  44.                      {
  45.                         uiKeyTimeCnt_left=0;
  46.                         ucKeyLock_left=1;  
  47.                         ucKeySec=1;    //觸發1號鍵,left
  48.                      }
  49.             }
  50.                 else if(uiKeyTimeCnt_left<const_time_0_5s)
  51.                 {
  52.                          uiKeyTimeCnt_left++;
  53.                 }
  54.                 else
  55.                 {
  56.                          uiKeyCtntyCnt_left++;
  57.                          if(uiKeyCtntyCnt_left>const_time_0_25s)
  58.                          {
  59.                                  uiKeyCtntyCnt_left=0;
  60.                                 ucKeySec=1;    //觸發1號鍵,left
  61.                          }
  62.                 }
  63.         }

  64.         if(uc_flag_taskrefresh[2])
  65.         {
  66.                 if(key_sr_turn==1)//turn
  67.                   {
  68.                      ucKeyLock_turn=0;
  69.                      uiKeyTimeCnt_turn=0;
  70. //                         uiKeyCtntyCnt_turn=0;   
  71.                  }
  72.             else if(ucKeyLock_turn==0)
  73.                  {
  74.                      uiKeyTimeCnt_turn++;
  75.                      if(uiKeyTimeCnt_turn>CONST_KEY_TIME)
  76.                      {
  77.                         uiKeyTimeCnt_turn=0;
  78.                         ucKeyLock_turn=1;  
  79.                         ucKeySec=2;    //觸發2號鍵,turn
  80.                      }
  81.             }
  82.         }

  83.         if(uc_flag_taskrefresh[3])
  84.         {
  85.                 if(key_sr_right==1)//right
  86.                   {
  87.                      ucKeyLock_right=0;
  88.                      uiKeyTimeCnt_right=0;
  89.                          uiKeyCtntyCnt_right=0;   
  90.                  }
  91.             else if(ucKeyLock_right==0)
  92.                  {
  93.                      uiKeyTimeCnt_right++;
  94.                      if(uiKeyTimeCnt_right>CONST_KEY_TIME)
  95.                      {
  96.                         uiKeyTimeCnt_right=0;
  97.                         ucKeyLock_right=1;  
  98.                         ucKeySec=3;    //觸發3號鍵,right
  99.                      }
  100.             }
  101.                 else if(uiKeyTimeCnt_right<const_time_0_5s)
  102.                 {
  103.                          uiKeyTimeCnt_right++;
  104.                 }
  105.                 else
  106.                 {
  107.                          uiKeyCtntyCnt_right++;
  108.                          if(uiKeyCtntyCnt_right>const_time_0_25s)
  109.                          {
  110.                                  uiKeyCtntyCnt_right=0;
  111.                                 ucKeySec=3;    //觸發3號鍵,right
  112.                          }
  113.                 }
  114.         }

  115.         if(uc_flag_taskrefresh[4])
  116.         {
  117.                 if(key_sr_down==1)//down
  118.                   {
  119.                      ucKeyLock_down=0; //按鍵自鎖標志清零
  120.                      uiKeyTimeCnt_down=0;//按鍵去抖動延時計數器清零   
  121.                  }
  122.             else if(ucKeyLock_down==0)//有按鍵按下,且是第一次被按下,并且當前界面支持這個按鍵
  123.                  {
  124.                      uiKeyTimeCnt_down++; //累加定時中斷次數
  125.                           if(uiKeyTimeCnt_down>CONST_KEY_TIME)
  126.                      {
  127.                         uiKeyTimeCnt_down=0;
  128.                         ucKeyLock_down=1;  //自鎖按鍵置位,避免一直觸發
  129.                         ucKeySec=4;    //觸發4號鍵,down
  130.                      }
  131.             }
  132.         }

  133.         if(uc_flag_taskrefresh[6])
  134.         {                        
  135.           if(key_sr_left==1||key_sr_turn==1)//pause,按鍵左和按鍵旋轉未同時按下
  136.           {
  137.                  ucKeyLock_pause=0; //按鍵自鎖標志清零
  138.                  uiKeyTimeCnt_pause=0;//按鍵去抖動延時計數器清零      
  139.           }
  140.                 else if(ucKeyLock_pause==0)//有按鍵按下,且是第一次被按下
  141.                 {
  142.                     uiKeyTimeCnt_pause++; //累加定時中斷次數
  143.                     if(uiKeyTimeCnt_pause>CONST_KEY_TIME)
  144.                     {
  145.                             uiKeyTimeCnt_pause=0;
  146.                         ucKeyLock_pause=1;  //自鎖按鍵置位,避免一直觸發
  147.                     ucKeySec=6;    //觸發6號鍵,暫停
  148.                     }
  149.                 }
  150.         }
  151. }

  152. //按鍵服務函數
  153. void task_key_service(void)
  154. {
  155.         unsigned char ucCheck=0;
  156.         unsigned char ucOldEnum=0;
  157.         unsigned char ucNewEnum=0;
  158.         unsigned char i=0;
  159.         switch(ucKeySec) //按鍵服務狀態切換
  160.           {
  161.             case 1:// 1號鍵,left
  162.                                 ucCoordinate[0]++;                                //旋轉點坐標H+1
  163.                                 WriteBlockCoordinate();                        //寫入其他3個方塊坐標
  164.                                 ucCheck=TaskCheck();                        //檢測碰撞
  165.                                 if(ucCheck)                                                //未碰撞,則左移
  166.                                 {
  167.                                         ucCoordinate[0]--;
  168.                                         ChangeBlock(0);
  169.                                         ucCoordinate[0]++;
  170.                                         ChangeBlock(1);
  171.                                 }
  172.                                 else                                                    //碰撞,不變
  173.                                 {
  174.                                         ucCoordinate[0]--;
  175.                                         WriteBlockCoordinate();
  176.                                 }
  177.             break;
  178.                 case 2:// 2號鍵,turn
  179.                                 ucOldEnum=enumBlock;
  180.                                 switch(enumBlock)                                //旋轉后改變方塊編號
  181.                                 {
  182.                                         case S1:
  183.                                                         enumBlock=S2;
  184.                                         break;
  185.                                         case S2:
  186.                                                         enumBlock=S1;
  187.                                         break;
  188.                                         case Z1:
  189.                                                         enumBlock=Z2;
  190.                                         break;
  191.                                         case Z2:
  192.                                                         enumBlock=Z1;
  193.                                         break;
  194.                                         case L1:
  195.                                                         enumBlock=L2;
  196.                                         break;
  197.                                         case L2:
  198.                                                         enumBlock=L3;
  199.                                         break;
  200.                                         case L3:
  201.                                                         enumBlock=L4;
  202.                                         break;
  203.                                         case L4:
  204.                                                         enumBlock=L1;
  205.                                         break;
  206.                                         case J1:
  207.                                                         enumBlock=J2;
  208.                                         break;
  209.                                         case J2:
  210.                                                         enumBlock=J3;
  211.                                         break;
  212.                                         case J3:
  213.                                                         enumBlock=J4;
  214.                                         break;
  215.                                         case J4:
  216.                                                         enumBlock=J1;
  217.                                         break;
  218.                                         case I1:
  219.                                                         enumBlock=I2;
  220.                                         break;
  221.                                         case I2:
  222.                                                         enumBlock=I1;
  223.                                         break;
  224.                                         case O1:
  225.                                                         enumBlock=O1;
  226.                                         break;
  227.                                         case T_1:
  228.                                                         enumBlock=T_2;
  229.                                         break;
  230.                                         case T_2:
  231.                                                         enumBlock=T_3;
  232.                                         break;
  233.                                         case T_3:
  234.                                                         enumBlock=T_4;
  235.                                         break;
  236.                                         case T_4:
  237.                                                         enumBlock=T_1;
  238.                                         break;
  239.                                         default:
  240.                                         break;
  241.                                 }
  242.                                 WriteBlockCoordinate();
  243.                                 ucCheck=TaskCheck();
  244.                                 if(ucCheck)
  245.                                 {
  246.                                         ucNewEnum=enumBlock;
  247.                                         enumBlock=ucOldEnum;
  248.                                         ChangeBlock(0);
  249.                                         enumBlock=ucNewEnum;
  250.                                         ChangeBlock(1);
  251.                                 }
  252.                                 else
  253.                                 {
  254.                                         enumBlock=ucOldEnum;
  255.                                         WriteBlockCoordinate();
  256.                                 }

  257.             break;
  258.             case 3:// 3號鍵,right
  259.                                 ucCoordinate[0]--;
  260.                                 WriteBlockCoordinate();
  261.                                 ucCheck=TaskCheck();
  262.                                 if(ucCheck)
  263.                                 {
  264.                                         ucCoordinate[0]++;
  265.                                         ChangeBlock(0);
  266.                                         ucCoordinate[0]--;
  267.                                         ChangeBlock(1);
  268.                                 }
  269.                                 else
  270.                                 {
  271.                                         ucCoordinate[0]++;
  272.                                         WriteBlockCoordinate();
  273.                                 }

  274.             break;
  275.                 case 4:// 4號鍵,down
  276.                                 //根據所處界面不同,按鍵down的功能不同
  277.                                 switch(uc_state)
  278.                                 {
  279.                                         case 1:
  280.                                                         ucBlockNow=TL1%7;                //準備進入等待界面,就先產生當前隨機方塊
  281.                                                         uc_state=2;                                 //進入等待界面
  282.                                                         ucFlagScreenChange=1;        //激活界面變更
  283.                                         break;
  284.                                         case 2:
  285.                                                         uc_state=3;                                //進入下落界面
  286.                                                         ucFlagScreenChange=1;
  287.                                         break;
  288.                                         case 3:        //在下落界面下,down為直接下落到底
  289.                                                         ET0=0;//關閉計時器0,出新后開啟,防止直接下落
  290.                                                         ChangeBlock(0);                 //先清除當前的圖形
  291.                                                         do                                                //循環模擬下落并檢測,直到失敗
  292.                                                         {
  293.                                                                 ucCoordinate[1]++;
  294.                                                                 WriteBlockCoordinate();
  295.                                                                 ucCheck=TaskCheck();
  296.                                                         }
  297.                                                         while(ucCheck);
  298.                                                         ucCoordinate[1]--;                //恢復到最后一次成功的坐標
  299.                                                         WriteBlockCoordinate();
  300.                                                         ChangeBlock(1);                        //畫方塊

  301.                                                         //立即寫入,并消除,防止到底后還可以移動
  302.                                                         //寫入Map
  303.                                                         for(i=0;i<4;i++)
  304.                                                         {
  305.                                                                 ucxMap[ ucxBlockPosition[i][0] ][ ucxBlockPosition[i][1] ]=1;
  306.                                                         }
  307.                                                         //調用消除
  308.                                                         TaskClear();
  309.                                                         //刷新下落延遲,防止出新后,直接下落
  310.                                                         ET0=1;
  311.                                         break;
  312.                                         case 4:        //死亡界面
  313.                                                         ucBlockNow=TL1%7;                //準備進入等待界面,就先產生當前隨機方塊
  314.                                                         uc_state=2;                                 //進入等待界面
  315.                                                         ucFlagScreenChange=1;
  316.                                         break;
  317.                                         case 5:        //暫停界面
  318.                                                         uc_state=3;                                //進入下落界面
  319.                                                         //開啟下落界面時的相關任務
  320.                                                         uc_flag_taskrefresh[1]=1;
  321.                                                     uc_flag_taskrefresh[2]=1;
  322.                                                     uc_flag_taskrefresh[3]=1;
  323.                                                     uc_flag_taskrefresh[4]=1;
  324.                                                     uc_flag_taskrefresh[5]=1;
  325.                                                     uc_flag_taskrefresh[6]=1;
  326.                                         break;
  327.                                 }
  328.             break;
  329.                 case 6:// 6號鍵,pause
  330.                                 uc_state=5;
  331.                                 ucFlagScreenChange=1;
  332.                 break;
  333.                 default:
  334.                 break;                 
  335.           }
  336.         ucKeySec=0;
  337. }
復制代碼
  1. /*******************************************************
  2. * 文件名稱:TaskBlock.c
  3. * 單 片 機:STC89C52RC
  4. * 簡    述:方塊子程序,包含,下落,出新,消除,檢測
  5. * 作    者:劉琦
  6. * 完成日期:2015年4月21日
  7. *******************************************************/
  8. #include<reg52.h>
  9. #include"Tetris.h"
  10. #include"Block.h"
  11. #include"tetris.h"
  12. #include"Score.h"
  13. /*******************************************************
  14. * 函 數 名:TaskCheck(void)
  15. * 功能描述:檢測
  16. * 函數說明:檢測左右移,下落,出新,旋轉
  17. * 輸入參數:無
  18. * 返 回 值:成功失敗標示,ucReturn
  19. *******************************************************/
  20. unsigned char TaskCheck(void)
  21. {
  22.         unsigned char ucReturn=0;
  23.         unsigned char i=0;
  24.         //加入檢測部分,包括邊界檢測,碰撞檢測
  25.         //邊界檢測
  26.         for(i=0;i<4;i++)
  27.         {
  28.                 if(ucxBlockPosition[i][0]>=0&&ucxBlockPosition[i][0]<=9                        //檢測左右
  29.                    &&ucxBlockPosition[i][1]>=0&&ucxBlockPosition[i][1]<=19)                //檢測上下
  30.                 {
  31.                         ucReturn=1;
  32.                 }
  33.                 else
  34.                 {
  35.                         ucReturn=0;
  36.                         return ucReturn;//如果邊界檢測失敗,就不進行下面檢測,直接返回失敗
  37.                 }
  38.         }
  39.         //碰撞檢測
  40.         for(i=0;i<4;i++)
  41.         {
  42.                 if(ucxMap[ ucxBlockPosition[i][0] ][ ucxBlockPosition[i][1] ]!=0)//與地圖標記位置進行比較
  43.                 {
  44.                         ucReturn=0;
  45.                         return ucReturn;
  46.                 }
  47.         }
  48.         return ucReturn;
  49. }
  50. /*******************************************************
  51. * 函 數 名:unsigned char TaskGoingDown(void)
  52. * 功能描述:方塊下落
  53. * 函數說明:
  54. * 輸入參數:無
  55. * 返 回 值:ucResult,1無碰撞,0碰撞
  56. *******************************************************/
  57. unsigned char TaskGoingDown(void)
  58. {
  59.         unsigned char ucCheck=0;
  60.         unsigned char ucResult=0;
  61.         ucCoordinate[1]++;                                //旋轉點坐標,豎S+1
  62.         WriteBlockCoordinate();                        //將其他三個小方塊坐標寫入數組
  63.         ucCheck=TaskCheck();                        //檢測碰撞
  64.         if(ucCheck)                                                //無碰撞
  65.         {
  66.                 ucCoordinate[1]--;                        //坐標復位
  67.                 ChangeBlock(0);                                //在老位置消除方塊,只刷新有改變的位置,加快顯示速度
  68.                 ucCoordinate[1]++;                        //坐標+1
  69.                 ChangeBlock(1);                                //在新位置畫方塊
  70.                 ucResult=1;
  71.         }
  72.         else                                                        //有碰撞,則不變
  73.         {
  74.                 ucCoordinate[1]--;                        
  75.                 WriteBlockCoordinate();
  76.                 ucResult=0;
  77.         }
  78.         return ucResult;
  79. }
  80. /*******************************************************
  81. * 函 數 名:unsigned char TaskComingNew(void)
  82. * 功能描述:方塊出新
  83. * 函數說明:
  84. * 輸入參數:無
  85. * 返 回 值:ucResult,1成功,0失敗
  86. *******************************************************/
  87. unsigned char TaskComingNew(void)
  88. {
  89.         unsigned char ucCheck=0;
  90.         unsigned char ucResult=0;
  91.         //寫入當前方塊的相關信息
  92.         switch(ucBlockNow)                                         
  93.         {
  94.                 case 0:
  95.                                 enumBlock=S1;
  96.                                 ucCoordinate[0]=4;
  97.                                 ucCoordinate[1]=0;
  98.                 break;
  99.                 case 1:
  100.                                 enumBlock=Z1;
  101.                                 ucCoordinate[0]=4;
  102.                                 ucCoordinate[1]=0;
  103.                 break;
  104.                 case 2:
  105.                                 enumBlock=L1;
  106.                                 ucCoordinate[0]=4;
  107.                                 ucCoordinate[1]=1;
  108.                 break;
  109.                 case 3:
  110.                                 enumBlock=J1;
  111.                                 ucCoordinate[0]=4;
  112.                                 ucCoordinate[1]=1;
  113.                 break;
  114.                 case 4:
  115.                                 enumBlock=I1;
  116.                                 ucCoordinate[0]=5;
  117.                                 ucCoordinate[1]=0;
  118.                 break;
  119.                 case 5:
  120.                                 enumBlock=O1;
  121.                                 ucCoordinate[0]=5;
  122.                                 ucCoordinate[1]=0;
  123.                 break;
  124.                 case 6:
  125.                                 enumBlock=T_1;
  126.                                 ucCoordinate[0]=4;
  127.                                 ucCoordinate[1]=0;
  128.                 break;
  129.                 default:
  130.                 break;
  131.         }
  132.         //檢測碰撞
  133.         WriteBlockCoordinate();        
  134.         ucCheck=TaskCheck();
  135.         if(ucCheck)                                                //成功
  136.         {
  137.                 ChangeSmallBlock(0);                //將預覽的方塊清除
  138.                 ucBlockNext=TL1%7;                        //產生隨機數,作為預覽方塊
  139.                 ChangeBlock(1);                         //畫新的方塊
  140.                 ChangeSmallBlock(1);                //畫新的預覽方塊
  141.                 ucBlockNow=ucBlockNext;
  142.                 ucResult=1;
  143.         }
  144.         else
  145.         {
  146.                 ucResult=0;
  147.         }

  148.         return ucResult;
  149. }
  150. /*******************************************************
  151. * 函 數 名:void TaskClear(void)
  152. * 功能描述:消除滿行
  153. * 函數說明:消除滿行,并出新
  154. * 輸入參數:無
  155. * 返 回 值:無
  156. *******************************************************/
  157. void TaskClear(void)
  158. {
  159.         char i=0,j=0,n=0;
  160.         unsigned char m=0;
  161.         unsigned char k=0;
  162.         unsigned char flag_man=1,flag_kong=1,flag_clear=0;//滿行、空行、待清除標志
  163.         unsigned char man[4],count=0;                                          //滿行位置數組,滿行數量
  164.         unsigned char kong=20;                                                          //空行位置
  165.         unsigned char oldkong=20;                                                  //用來儲存舊的空行位置

  166.         unsigned char ucResult=0;

  167.         //標記出來滿行及第一個空行
  168.         for(i=19;i>=0;i--)
  169.         {
  170.                 for(j=9;j>=0;j--)
  171.                 {
  172.                         if(ucxMap[j][i]==0)
  173.                         {
  174.                                 flag_man=0;
  175.                         }
  176.                         else
  177.                         {
  178.                                 flag_kong=0;
  179.                         }
  180.                 }
  181.                 if(flag_man==1)
  182.                 {
  183.                         flag_clear=1;//激活消除標記
  184.                         man[k]=i;//標記滿行
  185.                         count++;
  186.                         k++;
  187.                 }
  188.                 else if(flag_kong==1)
  189.                 {
  190.                          kong=i;
  191.                         break;//檢測到第一個空行,就退出循環
  192.                 }
  193.                 flag_man=1;//將滿行標志復位
  194.                 flag_kong=1;
  195.         }

  196.         //計分
  197.         switch(count)
  198.         {
  199.                 case 0:
  200.                                 ucScore=ucScore+100;
  201.                                 break;
  202.                 case 1:
  203.                                 ucScore=ucScore+200;
  204.                                 break;
  205.                 case 2:
  206.                                 ucScore=ucScore+400;
  207.                                 break;
  208.                 case 3:
  209.                                 ucScore=ucScore+700;
  210.                                 break;
  211.                 case 4:
  212.                                 ucScore=ucScore+1100;
  213.                                 break;
  214.                 default:
  215.                                 break;
  216.         }

  217.         oldkong=kong;
  218.         //消除滿行
  219.         if(flag_clear==1)
  220.         {
  221.                 while(count!=0)//至少有一個滿行,才進行消除
  222.                 {
  223.                         //逐行下移
  224.                         for(m=0;m<man[count-1]-kong-1;m++)
  225.                         {
  226.                                 for(n=9;n>=0;n--)
  227.                                 {
  228.                                         ucxMap[n][man[count-1]-m]=ucxMap[n][man[count-1]-m-1];        
  229.                                 }
  230.                         }
  231.                         //最上行清空
  232.                         for(n=0;n<10;n++)
  233.                         {
  234.                                 ucxMap[n][kong+1]=0;        
  235.                         }

  236.                         kong++;
  237.                         count--;
  238.                 }
  239.                 ChangeMap(oldkong-1,man[0]); //寫入當前Map,只寫有改變的行,加快顯示速度
  240.         }

  241.         //將分數寫入屏幕
  242.         TaskScore();
  243.         //出新的方塊
  244.         ucResult=TaskComingNew();
  245.         //如果失敗,就進入失敗界面
  246.         if(ucResult==0)
  247.         {
  248.                 uc_state=4;
  249.                 ucFlagScreenChange=1;
  250.         }
  251. }
復制代碼

評分

參與人數 6黑幣 +34 收起 理由
分經濟 + 5 太強了,膜拜,哈哈
周超然 + 5 絕世好帖!
stkh + 5 很給力!
踏步如云 + 5 很給力!
蘇眉ZH + 2 贊一個!
zhaok2013 + 12 絕世好帖!

查看全部評分

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

使用道具 舉報

沙發
ID:130231 發表于 2017-3-17 19:41 | 只看該作者
太厲害了
回復

使用道具 舉報

板凳
ID:162136 發表于 2017-3-18 09:45 | 只看該作者
這個要支持。正打算用匯編寫這個
回復

使用道具 舉報

地板
ID:143525 發表于 2017-5-4 10:18 | 只看該作者
謝謝分享!!!!1
回復

使用道具 舉報

5#
ID:199694 發表于 2017-5-15 15:51 | 只看該作者
這個io口怎么改?能不能詳細說下
回復

使用道具 舉報

6#
ID:99130 發表于 2017-6-28 19:01 | 只看該作者
編譯過不了,
回復

使用道具 舉報

7#
ID:99130 發表于 2017-6-30 16:28 | 只看該作者
花屏有點嚴重啊 為什么圖里的很清楚??怎么解決
回復

使用道具 舉報

8#
ID:209954 發表于 2017-7-2 22:04 來自手機 | 只看該作者
越快樂越墮落 發表于 2017-6-30 16:28
花屏有點嚴重啊 為什么圖里的很清楚??怎么解決

圖里用的晶振是11兆的,如果你用的晶振是12兆的就要修改延時,否則可能會花屏。
回復

使用道具 舉報

9#
ID:223554 發表于 2017-7-31 14:06 | 只看該作者
積分不夠
回復

使用道具 舉報

10#
ID:216536 發表于 2017-8-1 08:34 | 只看該作者
學習學習
回復

使用道具 舉報

11#
ID:231984 發表于 2017-11-23 19:36 | 只看該作者
鎖存器用的什么型號的呢?
回復

使用道具 舉報

12#
ID:266764 發表于 2017-12-26 19:35 | 只看該作者
我用清翔的開發板,其他引腳都改好了,但是dula=P2^6和wela=P2^7是什么東西的引腳
回復

使用道具 舉報

13#
ID:166341 發表于 2017-12-28 16:17 | 只看該作者
孤狼131 發表于 2017-12-26 19:35
我用清翔的開發板,其他引腳都改好了,但是dula=P2^6和wela=P2^7是什么東西的引腳

控制數碼管的段選與位選鎖存器的
回復

使用道具 舉報

14#
ID:266764 發表于 2017-12-28 23:17 | 只看該作者
Jerry0925 發表于 2017-12-28 16:17
控制數碼管的段選與位選鎖存器的

那你知道這個鎖存器是哪個型號的嗎
回復

使用道具 舉報

15#
ID:224487 發表于 2018-1-5 00:33 | 只看該作者
按照接線連好單片機,為什么進入界面后無法運行,只有一個邊框。本人剛接觸單片機,還有很多不懂
回復

使用道具 舉報

16#
ID:196311 發表于 2018-1-7 21:34 | 只看該作者
樓主很強大,下載學習下算法,謝謝分享
回復

使用道具 舉報

17#
ID:273035 發表于 2018-1-8 09:28 來自手機 | 只看該作者
學習學習
回復

使用道具 舉報

18#
ID:228939 發表于 2018-1-15 21:13 | 只看該作者
坐等超級瑪麗
回復

使用道具 舉報

19#
ID:288471 發表于 2018-3-6 22:57 | 只看該作者
高手啊  不錯!!
回復

使用道具 舉報

20#
ID:306312 發表于 2018-4-12 08:20 | 只看該作者
感謝樓主的無私奉獻,給了我很大的啟發
回復

使用道具 舉報

21#
ID:319242 發表于 2018-5-2 22:39 | 只看該作者
感謝分享代碼,經測試能夠運行,但是移植到串行12864模塊上很難,單片機RAM太小,無法緩存所有屏幕點陣,而并口LCD則可以直接讀取屏幕內容。
回復

使用道具 舉報

22#
ID:59433 發表于 2018-5-2 23:29 | 只看該作者
給個元器件電路圖咯  謝謝
回復

使用道具 舉報

23#
ID:320508 發表于 2018-11-29 14:22 | 只看該作者
好帖收藏一波
回復

使用道具 舉報

24#
ID:20468 發表于 2018-11-29 19:41 | 只看該作者
這是好資料
回復

使用道具 舉報

25#
ID:445953 發表于 2018-12-13 20:31 | 只看該作者
厲害厲害,支持一波
回復

使用道具 舉報

26#
ID:3802 發表于 2019-1-25 14:31 | 只看該作者
太厲害了
回復

使用道具 舉報

27#
ID:479216 發表于 2019-2-22 11:00 來自手機 | 只看該作者
樓主有沒有更詳細的資料啊,要買啥,焊哪里
回復

使用道具 舉報

28#
ID:479299 發表于 2019-2-23 01:33 | 只看該作者
mark!mark!mark!mark!
回復

使用道具 舉報

29#
ID:414624 發表于 2019-4-10 16:24 | 只看該作者
DB0-DB7是P0口嗎,那要上啦電阻輸出嗎
回復

使用道具 舉報

30#
ID:533791 發表于 2019-5-12 00:27 來自手機 | 只看該作者
孤狼131 發表于 2017-12-26 19:35
我用清翔的開發板,其他引腳都改好了,但是dula=P2^6和wela=P2^7是什么東西的引腳

我用的也是清翔的開發板,想請問你這個子程序到底怎么弄啊。我萌新,這個復制過去編譯都過不了
回復

使用道具 舉報

31#
ID:538436 發表于 2019-5-14 22:42 | 只看該作者
萌新求一下資料 么有幣。。
回復

使用道具 舉報

32#
ID:634589 發表于 2019-11-2 23:07 | 只看該作者
哇!!!這個才是硬核!!!!
回復

使用道具 舉報

33#
ID:625113 發表于 2019-11-26 09:29 來自手機 | 只看該作者
大佬大佬,來學習學習
回復

使用道具 舉報

34#
ID:663957 發表于 2019-12-28 10:40 | 只看該作者
linlexiao 發表于 2019-5-12 00:27
我用的也是清翔的開發板,想請問你這個子程序到底怎么弄啊。我萌新,這個復制過去編譯都過不了

所以到底怎么搞啊
回復

使用道具 舉報

35#
ID:59884 發表于 2020-1-6 19:54 | 只看該作者
謝謝樓主分享!
回復

使用道具 舉報

36#
ID:669226 發表于 2020-1-24 19:30 | 只看該作者
感謝分享!!!
回復

使用道具 舉報

37#
ID:185815 發表于 2020-2-4 21:25 | 只看該作者
感謝分享了,困家里沒事做,D一個
回復

使用道具 舉報

38#
ID:614068 發表于 2020-2-5 18:23 | 只看該作者
謝謝樓主分享,這個算是大型程序了,值得我學習啊。
回復

使用道具 舉報

39#
ID:624009 發表于 2020-2-10 21:44 | 只看該作者
謝謝分享,樓主太厲害了
回復

使用道具 舉報

40#
ID:808771 發表于 2020-8-24 09:31 | 只看該作者
感謝樓主的分享,稍后自己也試試看
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品视频一区二区三区, | 久久久久久国产一区二区三区 | 免费黄色av | 国产成人精品一区二区 | 日韩欧美不卡 | 日本公妇乱淫xxxⅹ 国产在线不卡 | 精品一区二区三区免费视频 | 日韩人体在线 | 91av亚洲 | 日日日色 | 黄色大片在线 | 在线视频一区二区三区 | 日本成人免费网站 | 香蕉视频91 | 成人免费视频一区 | 亚洲精品视频三区 | 亚洲成色777777在线观看影院 | 国产一区二区中文字幕 | 蜜桃视频在线观看免费视频网站www | 午夜男人天堂 | 亚洲欧美日韩精品久久亚洲区 | 欧美精品在线免费 | 精品一区二区三区av | 一区二区不卡 | 蜜臀久久99精品久久久久久宅男 | 国产农村妇女毛片精品久久麻豆 | 美女视频一区二区三区 | 91在线视频免费观看 | 国产色爽 | 欧美黑人激情 | 一区二区三区视频免费观看 | 午夜精品在线观看 | 国产精品a久久久久 | 天天看片天天干 | 国产在线永久免费 | 日韩中文字幕免费 | 干狠狠| 黄网站在线观看 | 蜜臀网| 国产精品视频在线观看 | 韩国精品一区 |