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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4667|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

虛擬串口控制的俄羅斯方塊游戲仿真及源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
今天給51黑電子論壇的壇友共享一個(gè)好東東,使用51單片機(jī)實(shí)現(xiàn)的俄羅斯方塊游戲, 能虛擬串口控制,實(shí)用性還是比較高的,下面是仿真原理圖,大家可以下載附件后直接用proteus打開。


所有資料包含仿真工程文件和源碼下載:
俄羅斯方塊游戲.rar (422.54 KB, 下載次數(shù): 14)


俄羅斯方塊源程序:
  1. //--------------------------------------------------------------------------//
  2. //                                源程序大公開                              //
  3. //                    (c) Copyright 2001-2025 xuwenjun                     //
  4. //                            All Rights Reserved                           //
  5. //                                    V1.00                                 //
  6. //--------------------------------------------------------------------------//
  7. //標(biāo) 題: 俄羅斯方塊程序                            ?                      //
  8. //文件名: xwj_fk.c                                                          //
  9. //版 本: V1.00                                                             //
  10. //修改人: 徐文軍                         E-mail:xuwenjun@21cn.com           //
  11. //日 期: 05-13                                                           //
  12. //描 述: 俄羅斯方塊程序                            ?                      //
  13. //聲 明:                                                                   //
  14. //        以下代碼僅免費(fèi)提供給學(xué)習(xí)用途,但引用或修改后必須在文件中聲明出處. //
  15. //        如用于商業(yè)用途請(qǐng)與作者聯(lián)系.    E-mail:xuwenjun@21cn.com           //
  16. //        有問題請(qǐng)mailto xuwenjun@21cn.com   歡迎與我交流!                  //
  17. //--------------------------------------------------------------------------//
  18. //老版本: 無                             老版本文件名:                      //
  19. //創(chuàng)建人: 徐文軍                         E-mail:xuwenjun@21cn.com           //
  20. //日 期: 05-13                                                          //
  21. //描 述:                                                                   //
  22. //      1、功能完整,直接使用                                               //
  23. //      2、模塊獨(dú)立性強(qiáng),移植方便,外部?jī)Hinit和move函數(shù),修改顯示和輸入即可 //
  24. //      3、對(duì)減少內(nèi)存占用、盡量減少屏幕操作進(jìn)行適當(dāng)優(yōu)化                     //
  25. //      4、新方塊生成高度隨機(jī),絕對(duì)無規(guī)律                                   //
  26. //      5、仿真環(huán)境為Keil7.5+Proteus6.5,可以聯(lián)機(jī)也可脫機(jī)運(yùn)行                //
  27. //      CODE SIZE        =   1845    ----                                   //
  28. //      CONSTANT SIZE    =    326    ----                                   //
  29. //      DATA SIZE        =     16      19                                   //
  30. //      IDATA SIZE       =     50    ----                                   //
  31. //      BIT SIZE         =      1       1                                   //
  32. //--------------------------------------------------------------------------//
  33. #include <stdlib.h>
  34. #include "xwj_lcd16.h"                                 // 字符液晶控制函數(shù)聲明    //
  35. #include "xwj_lcd6963.h"                        // T6963C 公用函數(shù)
  36. #include "xwj_hlkey.h"                                //  P1口行列式鍵盤  //
  37. #include "xwj_serial.h"                                //串口函數(shù)集
  38. #include "change.h"                                        //數(shù)制轉(zhuǎn)換
  39. #include "xwj_fk.h"                                        //俄羅斯方塊程序

  40. #define ulong                unsigned long
  41. #define uint                unsigned int
  42. #define uchar                unsigned char

  43. extern void delay(unsigned int x);
  44. //----------------俄羅斯方塊內(nèi)部函數(shù)----------------------------------------//
  45. void fk_dot(uchar x,uchar y);                //顯示1個(gè)方塊點(diǎn)
  46. void fk_cldot(uchar x,uchar y);                //清除1個(gè)方塊點(diǎn)
  47. void fk_show(void);                                        //顯示分?jǐn)?shù)
  48. void fk_reffk(void);                                //刷新方塊
  49. void fk_refnew(void);                                //刷新預(yù)覽方塊
  50. void fk_refline(yy);                                //刷新1行背景
  51. bit  fk_chk(void);                                        //沖突檢查
  52. void fk_new(void);                                        //產(chǎn)生新方塊
  53. void fk_add(void);                                        //方塊合并

  54. /*
  55. //-----------------俄羅斯方塊公用函數(shù)--------------------------------------//
  56. void fk_init(void);                                                //方塊初始化
  57. void fk_move(unsigned char mode);                //移動(dòng)方塊
  58. */

  59. //-------------------------------------------------------------------------//
  60. #define FULLMAP        0x0fff                                /*掩碼*/
  61. #define LINEGUAN        20                                /*20行過一關(guān)*/
  62. #define NEWX        15                                        /*預(yù)覽方塊X位置*/
  63. #define NEWY        12                                        /*預(yù)覽方塊Y位置*/
  64. #define LINEMAX        21                                        /*屏幕最高21行*/
  65. uint idata fk_map[LINEMAX+4];                //背景映象
  66. uchar  fk_x,fk_y,fk_r;                                //方塊左右、高度、方向
  67. uchar fk_type;                                                //方塊形狀
  68. uchar  fk_oldx,fk_oldy,fk_oldr;                //方塊上次左右、高度、方向
  69. uchar  fk_newtype,fk_newr;                        //新方塊形狀、方向
  70. uint score;                                                        //總分
  71. uint line;                                                        //總行數(shù)        
  72. uchar speed;                                                //速度
  73. uchar moven;                                                //速度相關(guān)計(jì)數(shù)器
  74. uchar automapn;                                                //隨機(jī)方塊的行數(shù)
  75. bit fk_run;                                                        //俄羅斯方坑蝸吩誦?
  76.         
  77. uchar code fk_mod[][4][4]={                        //方塊模型號(hào),4個(gè)方向,4行
  78.         0,0,7,2,0,1,3,1,0,0,2,7,0,2,3,2,        //_|_
  79.         0,0,6,3,0,1,3,2,0,0,6,3,0,1,3,2,        //_|~
  80.         0,0,3,6,0,2,3,1,0,0,3,6,0,2,3,1,        //~|_
  81.         0,0,7,4,0,3,1,1,0,0,1,7,0,2,2,3,        //|__
  82.         0,0,7,1,0,1,1,3,0,0,4,7,0,3,2,2,        //__|
  83.         0,0,0,15,1,1,1,1,0,0,0,15,1,1,1,1,        //____
  84.         0,0,3,3,0,0,3,3,0,0,3,3,0,0,3,3,        //田字
  85. };

  86. uchar code strmap[4][9]={
  87.         "不錯(cuò)!  ","真棒!  ","好極啦!","太棒了!",
  88. };

  89. //--------------------------------------------------------------------------//
  90. void fk_dot(uchar x,uchar y)                //顯示1個(gè)方塊點(diǎn)
  91. {
  92.         printat(x*3+1, 241-(y-4)*12,"■");
  93. }

  94. //--------------------------------------------------------------------------//
  95. void fk_cldot(uchar x,uchar y)                //清除1個(gè)方塊點(diǎn)
  96. {
  97. //        printat(x*3+1, 241-(y-4)*12,"□");
  98.         printat(x*3+1, 241-(y-4)*12,"┘");
  99. }

  100. //--------------------------------------------------------------------------//
  101. void fk_show(void)                                        //顯示分?jǐn)?shù)
  102. {
  103.         printat(50, 12,chnint(score,1));
  104.         printat(60, 12,"00");
  105.         printat(40, 12,"得分:");
  106.         printat(54,36,chnint(line,1));
  107.         printat(40, 36,"行數(shù):");
  108.         printat(54,60,chnchar(speed,1));
  109.         printat(40,60,"速度:");
  110.         printat(54,84,chnchar(automapn,1));
  111.         printat(40,84,"關(guān)數(shù):");               
  112. }

  113. //--------------------------------------------------------------------------//
  114. void fk_reffk(void)                                        //刷新方塊
  115. {
  116.         uchar i,j;
  117.         uchar temp;
  118.         //----------------------------------------------//清除原來的方塊
  119.         for (i=0;i<4;i++)
  120.         {
  121.                 temp=(fk_mod[fk_type][fk_oldr][i]);
  122.                 for (j=fk_oldx;j<fk_oldx+4;j++)
  123.                 {
  124.                         if(temp&0x01)
  125.                         {
  126.                                 fk_cldot(j,fk_oldy+i);
  127.                         }
  128.                         temp>>=1;
  129.                 }
  130.         }
  131.         //----------------------------------------------//顯示新的方塊
  132.         for (i=0;i<4;i++)
  133.         {
  134.                 temp=(fk_mod[fk_type][fk_r][i]);
  135.                 for (j=fk_x;j<fk_x+4;j++)
  136.                 {
  137.                         if(temp&0x01)
  138.                         {
  139.                                 fk_dot(j,fk_y+i);
  140.                         }
  141.                         temp>>=1;
  142.                 }
  143.         }
  144.         fk_oldx=fk_x;fk_oldy=fk_y;fk_oldr=fk_r;        //保存新方塊位置
  145. }

  146. //--------------------------------------------------------------------------//
  147. void fk_refnew(void)                                //刷新預(yù)覽方塊
  148. {
  149.         uchar i,j;
  150.         uchar temp;
  151.         //----------------------------------------------//預(yù)覽方塊
  152.         for (i=0;i<4;i++)
  153.         {
  154.                 temp=(fk_mod[fk_newtype][fk_newr][i]);
  155.                 for (j=NEWX;j<NEWX+4;j++)
  156.                 {
  157.                         if(temp&0x01)
  158.                         {
  159.                                 fk_dot(j,NEWY+i);
  160.                         }
  161.                         else
  162.                         {
  163.                                 fk_cldot(j,NEWY+i);
  164.                         }
  165.                         temp>>=1;
  166.                 }
  167.         }
  168. }

  169. //--------------------------------------------------------------------------//
  170. void fk_refline(yy)                                        //刷新1行背景
  171. {
  172.         uchar i;
  173.         uint temp;
  174.         if (yy>=4)
  175.         {
  176.                 temp=fk_map[yy];
  177.                 for (i=0;i<12;i++)
  178.                 {
  179.                         if ((temp&0x01) !=0)
  180.                                 fk_dot(i,yy);
  181.                         else
  182.                                 fk_cldot(i,yy);
  183.                         temp >>= 1;
  184.                 }
  185.         }
  186. }

  187. //--------------------------------------------------------------------------//
  188. bit fk_chk(void)                                        //沖突檢查
  189. {
  190.         uchar i;
  191.         bit neq=0;
  192.         for (i=0;i<4;i++)
  193.         {
  194.                 if ( (((fk_mod[fk_type][fk_r][i])<<fk_x)+(fk_map[fk_y+i])) != (((fk_mod[fk_type][fk_r][i])<<fk_x)|(fk_map[fk_y+i])) )
  195.                         neq=1;
  196.         }
  197.         return(neq);
  198. }

  199. //--------------------------------------------------------------------------//
  200. void fk_new(void)                                                //產(chǎn)生新方塊
  201. {
  202.         srand(rand()+fk_x+fk_y+fk_r);
  203.         fk_oldx=fk_x=5;
  204.         fk_oldy=fk_y=LINEMAX;
  205.     fk_type = fk_newtype;
  206.         fk_oldr=fk_newr;
  207.     fk_newtype = rand()%7;
  208.         fk_newr=rand()%4;
  209.         fk_refnew();                        //刷新預(yù)覽方塊
  210.         if (fk_run)
  211.                 fk_reffk();        //刷新顯示
  212. }

  213. //--------------------------------------------------------------------------//
  214. void fk_add(void)                                        //方塊合并
  215. {
  216.         uchar i,j;
  217.         uchar full=0x00;
  218.         uchar fulltemp;
  219.         uchar fullline=0x00;
  220.         for (i=0;i<4;i++)        //方塊合并
  221.         {
  222.                 fk_map[fk_y+i] |= (fk_mod[fk_type][fk_r][i])<<fk_x;
  223.                 full <<= 1;
  224.                 if ((fk_y+i >= 4) && (fk_map[fk_y+i] == 0xffff))                //滿行
  225.                 {
  226.                         full |= 0x01;
  227.                 }
  228.         }
  229.         if (full != 0)                //有滿行
  230.         {
  231.                 for (j=0;j<3;j++)                //消行閃爍3次
  232.                 {
  233.                         delay(300);
  234.                         fulltemp=full;
  235.                         for (i=0;i<4;i++)        //4行
  236.                         {
  237.                                 if ((fulltemp&0x08) != 0)
  238.                                 {
  239.                                         fk_map[fk_y+i] ^= FULLMAP;
  240.                                 }
  241.                                 fk_refline(fk_y+i);
  242.                                 fulltemp <<= 1;
  243.                         }
  244.                 }
  245.                 fulltemp=full;
  246.                 for (i=fk_y;i<LINEMAX+4+fullline;i++)        //上面行下移
  247.                 {
  248.                         if ((i < LINEMAX+4)&&(fk_map[i-fullline]!=fk_map[i]))
  249.                         {
  250.                                 fk_map[i-fullline]=fk_map[i];
  251.                                 fk_refline(i-fullline);
  252.                         }
  253.                         if ((i >= LINEMAX+4)&&(fk_map[i-fullline]!=~FULLMAP))
  254.                         {
  255.                                 fk_map[i-fullline]=~FULLMAP;        //背景映象
  256.                                 fk_refline(i-fullline);
  257.                         }
  258.                         if ((fulltemp&0x08) != 0)
  259.                         {
  260.                                 fullline++;
  261.                         }
  262.                         fulltemp <<= 1;
  263.                 }
  264.                 if (((line+fullline)/LINEGUAN) != (line/LINEGUAN))//每20行速度+1
  265.                         speed ++;
  266.                 line += fullline;                                //更新分?jǐn)?shù)、行數(shù)
  267.                 score += (1<<fullline)-1;
  268.                 printat(46,180,strmap[fullline-1]);        //夸獎(jiǎng)
  269.                 fk_show();                                                //顯示分?jǐn)?shù)
  270.                 fk_new();                        //產(chǎn)生新方塊
  271.         }
  272.         else
  273.         {
  274.                 if (fk_y > LINEMAX-10)        //在最高位置碰撞且不能消行則游戲結(jié)束
  275.                         printat(46,180,"加油啊!");                //加油啊
  276.                 if (fk_y > LINEMAX-6)        //在最高位置碰撞且不能消行則游戲結(jié)束
  277.                         printat(46,180,"糟糕了!");                //糟糕了

  278.                 if (fk_y==LINEMAX)                //在最高位置碰撞且不能消行則游戲結(jié)束
  279.                         fk_run=0;        //方塊初始化
  280.                 else
  281.                         fk_new();        //產(chǎn)生新方塊
  282.         }
  283. }

  284. //--------------------------------------------------------------------------//
  285. void fk_init(void)                                        //方塊初始化
  286. {
  287.         uchar i;
  288.         fk_run = 0;
  289.         moven=0;
  290.         Lcd6963Cls();
  291.         Lcd6963Rec(0,0,152,255);
  292.         Lcd6963ChHz(0);                                        //切換到16X16點(diǎn)陣
  293.         printat(2, 16,"歡迎光臨文君閣");
  294.         printat(2, 48,"請(qǐng)按鍵選擇:");
  295.         printat(2, 80,"-----------------");
  296.         printat(2, 96,"7左旋 8右旋 9右旋");
  297.         printat(2, 112,"4左移 5右旋 6右移");
  298.         printat(2, 128,"4速度 5開始 6關(guān)數(shù)");
  299.         printat(2, 144,"1左移 2下移 3右移");
  300.         printat(2, 160,"-----------------");
  301.         Lcd6963ChHz(1);                                        //切換到12X12點(diǎn)陣
  302.         printat(46,180,"歡迎使用");
  303.         fk_show();                                                //顯示分?jǐn)?shù)
  304.         while (~fk_run)
  305.         {
  306.                 fk_move();                                        //等待設(shè)置速度關(guān)數(shù)開始
  307.                 delay(10);
  308.         }
  309.         for (i=0;i<4;i++)
  310.         {
  311.                 fk_map[i]=0xffff;        //背景映象
  312.         }        delay(3000);
  313.         for (i=4;i<LINEMAX+4;i++)
  314.         {
  315.                 if (i<(automapn+4))
  316.                         fk_map[i]=rand()-1|~FULLMAP; //背景映象
  317.                 else
  318.                         fk_map[i]=~FULLMAP;                //背景映象
  319.                 fk_refline(i);                                //刷新1行背景
  320.         }
  321.         fk_show();                                                //顯示分?jǐn)?shù)
  322. //        fk_new();                                                //產(chǎn)生新方塊
  323. }   

  324. //--------------------------------------------------------------------------//
  325. void fk_move(void)                                                //移動(dòng)方塊
  326. {
  327.         unsigned char temp;
  328.         if(KeyTest())                                        //檢查有無按鍵
  329.         {
  330.                 putinbuf(KeyGetCode());                //按鍵碼輸入接收緩沖區(qū)
  331.         }
  332.         if (checkin())
  333.         {
  334.                 temp=getbyte();
  335.                 if (temp!=0) Lcd16WrCharhh(12,0,temp);
  336.                 if (temp!=0) Lcd16WrChar(15,0,temp);
  337.                 putchar(temp);
  338.         }
  339.         else
  340.                 temp=0xff;                                        //無鍵設(shè)為無效鍵用于下移方塊
  341.         temp -= '0';
  342.         switch(temp)
  343.         {
  344.         default:
  345.                 if (--moven)                                //游戲難度
  346.                         break;
  347.                 else
  348.                 {
  349.                         moven=(252>>speed)+2;
  350.                 }
  351.         case 2:                //下移
  352.                 if (fk_run)                                        //游戲中下移
  353.                 {
  354.                         if(fk_y>0)
  355.                         {
  356.                                 fk_y--;
  357.                                 if(fk_chk())
  358.                                 {
  359.                                         fk_y++;                //有沖突取消操作,執(zhí)行碰撞組合
  360.                                         fk_add();        //方塊合并        //產(chǎn)生新方塊
  361.                                 }
  362.                         }
  363.                         else                                //方塊到底也執(zhí)行碰撞組合
  364.                         {
  365.                                 fk_add();                //方塊合并
  366.                         }
  367.                 }
  368.                 else                                                //初始化時(shí)
  369.                 {
  370.                         fk_new();                                //產(chǎn)生新方塊
  371.                 }
  372.                 break;
  373.         case 0:                //下移到底
  374.                 while((fk_y>0)&&~(fk_chk())) //一直下移直到?jīng)_突
  375.                 {
  376.                         fk_y--;
  377.                 }
  378.                 moven=1;
  379.                 fk_y++;                                //恢復(fù)到未沖突位置
  380.                 break;
  381.         case 3:                //右移
  382.         case 6:                //右移
  383.                 if (fk_run)                                        //游戲中右移
  384.                 {
  385.                         if(fk_x<12)
  386.                         {
  387.                                 fk_x++;
  388.                                 if(fk_chk())
  389.                                         fk_x--;//有沖突取消操作
  390.                         }
  391.                 }
  392.                 else                                                        //初始化時(shí)
  393.                 {
  394.                         automapn++;
  395.                         automapn &= 0x0f;
  396.                         fk_show();                                        //顯示分?jǐn)?shù)
  397.                 }
  398.                 break;
  399.         case 1:                //左移
  400.         case 4:                //移
  401.                 if (fk_run)                                                //游戲中左移
  402.                 {
  403.                         if(fk_x>0)
  404.                         {
  405.                                 fk_x--;
  406.                                 if(fk_chk())
  407.                                         fk_x++;//有沖突取消操作
  408.                         }
  409.                 }
  410.                 else                                                        //初始化時(shí)
  411.                 {
  412.                         speed++;
  413.                         speed &= 0x07;
  414.                         fk_show();                                        //顯示分?jǐn)?shù)
  415.                 }
  416.                 break;
  417.         case 9:                //右轉(zhuǎn)
  418.         case 8:                //右轉(zhuǎn)
  419.         case 5:                //右轉(zhuǎn)
  420.                 if (fk_run)                                                //游戲中右轉(zhuǎn)
  421.                 {
  422.                         fk_r++;
  423.                         if(fk_chk())
  424.                                 fk_r--;                                        //有沖突取消操作
  425.                         fk_r &= 0x03;
  426.                 }
  427.                 else                                                        //初始化時(shí)
  428.                 {
  429.                         fk_run = 1;
  430.                 }
  431.                 break;
  432.         case 7:                //左轉(zhuǎn)
  433.                 if (fk_run)                                                //游戲中右轉(zhuǎn)
  434.                 {
  435.                         fk_r--;
  436.                         if(fk_chk())
  437.                                 fk_r++;                                //有沖突取消操作
  438.                         fk_r &= 0x03;
  439.                 }
  440.                 else                                                        //初始化時(shí)
  441.                 {
  442.                         fk_run = 1;
  443.                 }
  444.                 break;
  445.         }
  446.         if((fk_run)&& ((fk_x!=fk_oldx)||(fk_y!=fk_oldy)||(fk_r!=fk_oldr)) )
  447.         {
  448.                 fk_reffk();        //刷新顯示
  449.         }
  450.         rand();
  451. }

  452. /*
  453. // ---------------------------------------------- //        32字節(jié)
  454. void delay(uint x)
  455. {
  456.    uint i,j;
  457.    for (i=0; i<x;i++) {
  458.       for (j=0;j<102; j++) ;
  459.    }
  460. }

  461. //--------------------------------------------------------------------------//
  462. void main(void)                                                // 測(cè)試用
  463. {
  464.         serial_init();
  465.         Lcd6963Init();                                        //Lcd6963復(fù)位
  466.         Lcd16Reset();                                        //Lcd16復(fù)位
  467.         Serial_main();                                        //        串口測(cè)試用主函數(shù)  
  468.         Lcd16main();                                        //Lcd16臨時(shí)測(cè)試主程序
  469.         Lcd6963main();                                        //Lcd6963測(cè)試用
  470.         fk_init();                                                //方塊初始化
  471.         while(1)
  472.         {
  473.                 if (~fk_run)
  474.                         fk_init();                                                //方塊初始化
  475.                 fk_move();                                        //移動(dòng)方塊
  476.                 delay(10);
  477.         }
  478. }
  479. */
復(fù)制代碼

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

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久久国产一区 | 日韩在线第一 | 男人av网 | 亚洲福利一区二区 | 亚洲啊v| 亚洲美女视频 | 99久久精品免费看国产四区 | 日韩在线小视频 | 国产福利在线 | 老司机午夜性大片 | 在线视频一区二区三区 | 天天拍天天操 | 欧美一区二区在线看 | 久久男女视频 | 韩日视频在线观看 | 91资源在线 | 成人影院在线 | 黄色国产大片 | 亚洲精品二区 | 国产午夜三级一区二区三 | 国产成人精品一区二区三 | 一区二区三区在线播放视频 | 特黄色一级毛片 | 午夜精品影院 | 国产一区二区在线免费观看 | 久久久99国产精品免费 | 欧美美女爱爱视频 | 中文字幕电影在线观看 | 国产精品视频999 | 国产精品五区 | 国产精品久久久爽爽爽麻豆色哟哟 | 操操网站 | 亚洲综合免费 | 黄色一级电影在线观看 | 亚洲一区二区免费电影 | 一区二区三区四区av | 成av在线 | 丁香婷婷久久久综合精品国产 | 99精品在线 | 国产精品国产三级国产aⅴ浪潮 | 欧美区在线观看 |