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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機俄羅斯方塊游戲Proteus仿真程序

[復制鏈接]
跳轉到指定樓層
樓主
俄羅斯方塊仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. //描 述:                                                                   //
  2. //      1、功能完整,直接使用                                               //
  3. //      2、模塊獨立性強,移植方便,外部僅init和move函數,修改顯示和輸入即可 //
  4. //      3、對減少內存占用、盡量減少屏幕操作進行適當優化                     //
  5. //      4、新方塊生成高度隨機,絕對無規律                                   //
  6. //      5、仿真環境為Keil7.5+Proteus6.5,可以聯機也可脫機運行                //
  7. //      CODE SIZE        =   1845    ----                                   //
  8. //      CONSTANT SIZE    =    326    ----                                   //
  9. //      DATA SIZE        =     16      19                                   //
  10. //      IDATA SIZE       =     50    ----                                   //
  11. //      BIT SIZE         =      1       1                                   //
  12. //--------------------------------------------------------------------------//
  13. #include <stdlib.h>
  14. #include "xwj_lcd16.h"                                 // 字符液晶控制函數聲明    //
  15. #include "xwj_lcd6963.h"                        // T6963C 公用函數
  16. #include "xwj_hlkey.h"                                //  P1口行列式鍵盤  //
  17. #include "xwj_serial.h"                                //串口函數集
  18. #include "change.h"                                        //數制轉換
  19. #include "xwj_fk.h"                                        //俄羅斯方塊程序

  20. #define ulong                unsigned long
  21. #define uint                unsigned int
  22. #define uchar                unsigned char

  23. extern void delay(unsigned int x);
  24. //----------------俄羅斯方塊內部函數----------------------------------------//
  25. void fk_dot(uchar x,uchar y);                //顯示1個方塊點
  26. void fk_cldot(uchar x,uchar y);                //清除1個方塊點
  27. void fk_show(void);                                        //顯示分數
  28. void fk_reffk(void);                                //刷新方塊
  29. void fk_refnew(void);                                //刷新預覽方塊
  30. void fk_refline(yy);                                //刷新1行背景
  31. bit  fk_chk(void);                                        //沖突檢查
  32. void fk_new(void);                                        //產生新方塊
  33. void fk_add(void);                                        //方塊合并

  34. /*
  35. //-----------------俄羅斯方塊公用函數--------------------------------------//
  36. void fk_init(void);                                                //方塊初始化
  37. void fk_move(unsigned char mode);                //移動方塊
  38. */

  39. //-------------------------------------------------------------------------//
  40. #define FULLMAP        0x0fff                                /*掩碼*/
  41. #define LINEGUAN        20                                /*20行過一關*/
  42. #define NEWX        15                                        /*預覽方塊X位置*/
  43. #define NEWY        12                                        /*預覽方塊Y位置*/
  44. #define LINEMAX        21                                        /*屏幕最高21行*/
  45. uint idata fk_map[LINEMAX+4];                //背景映象
  46. uchar  fk_x,fk_y,fk_r;                                //方塊左右、高度、方向
  47. uchar fk_type;                                                //方塊形狀
  48. uchar  fk_oldx,fk_oldy,fk_oldr;                //方塊上次左右、高度、方向
  49. uchar  fk_newtype,fk_newr;                        //新方塊形狀、方向
  50. uint score;                                                        //總分
  51. uint line;                                                        //總行數        
  52. uchar speed;                                                //速度
  53. uchar moven;                                                //速度相關計數器
  54. uchar automapn;                                                //隨機方塊的行數
  55. bit fk_run;                                                        //俄羅斯方坑蝸吩誦?
  56.         
  57. uchar code fk_mod[][4][4]={                        //方塊模型號,4個方向,4行
  58.         0,0,7,2,0,1,3,1,0,0,2,7,0,2,3,2,        //_|_
  59.         0,0,6,3,0,1,3,2,0,0,6,3,0,1,3,2,        //_|~
  60.         0,0,3,6,0,2,3,1,0,0,3,6,0,2,3,1,        //~|_
  61.         0,0,7,4,0,3,1,1,0,0,1,7,0,2,2,3,        //|__
  62.         0,0,7,1,0,1,1,3,0,0,4,7,0,3,2,2,        //__|
  63.         0,0,0,15,1,1,1,1,0,0,0,15,1,1,1,1,        //____
  64.         0,0,3,3,0,0,3,3,0,0,3,3,0,0,3,3,        //田字
  65. };

  66. uchar code strmap[4][9]={
  67.         "不錯!  ","真棒!  ","好極啦!","太棒了!",
  68. };

  69. //--------------------------------------------------------------------------//
  70. void fk_dot(uchar x,uchar y)                //顯示1個方塊點
  71. {
  72.         printat(x*3+1, 241-(y-4)*12,"■");
  73. }

  74. //--------------------------------------------------------------------------//
  75. void fk_cldot(uchar x,uchar y)                //清除1個方塊點
  76. {
  77. //        printat(x*3+1, 241-(y-4)*12,"□");
  78.         printat(x*3+1, 241-(y-4)*12,"┘");
  79. }

  80. //--------------------------------------------------------------------------//
  81. void fk_show(void)                                        //顯示分數
  82. {
  83.         printat(50, 12,chnint(score,1));
  84.         printat(60, 12,"00");
  85.         printat(40, 12,"得分:");
  86.         printat(54,36,chnint(line,1));
  87.         printat(40, 36,"行數:");
  88.         printat(54,60,chnchar(speed,1));
  89.         printat(40,60,"速度:");
  90.         printat(54,84,chnchar(automapn,1));
  91.         printat(40,84,"關數:");               
  92. }

  93. //--------------------------------------------------------------------------//
  94. void fk_reffk(void)                                        //刷新方塊
  95. {
  96.         uchar i,j;
  97.         uchar temp;
  98.         //----------------------------------------------//清除原來的方塊
  99.         for (i=0;i<4;i++)
  100.         {
  101.                 temp=(fk_mod[fk_type][fk_oldr][i]);
  102.                 for (j=fk_oldx;j<fk_oldx+4;j++)
  103.                 {
  104.                         if(temp&0x01)
  105.                         {
  106.                                 fk_cldot(j,fk_oldy+i);
  107.                         }
  108.                         temp>>=1;
  109.                 }
  110.         }
  111.         //----------------------------------------------//顯示新的方塊
  112.         for (i=0;i<4;i++)
  113.         {
  114.                 temp=(fk_mod[fk_type][fk_r][i]);
  115.                 for (j=fk_x;j<fk_x+4;j++)
  116.                 {
  117.                         if(temp&0x01)
  118.                         {
  119.                                 fk_dot(j,fk_y+i);
  120.                         }
  121.                         temp>>=1;
  122.                 }
  123.         }
  124.         fk_oldx=fk_x;fk_oldy=fk_y;fk_oldr=fk_r;        //保存新方塊位置
  125. }

  126. //--------------------------------------------------------------------------//
  127. void fk_refnew(void)                                //刷新預覽方塊
  128. {
  129.         uchar i,j;
  130.         uchar temp;
  131.         //----------------------------------------------//預覽方塊
  132.         for (i=0;i<4;i++)
  133.         {
  134.                 temp=(fk_mod[fk_newtype][fk_newr][i]);
  135.                 for (j=NEWX;j<NEWX+4;j++)
  136.                 {
  137.                         if(temp&0x01)
  138.                         {
  139.                                 fk_dot(j,NEWY+i);
  140.                         }
  141.                         else
  142.                         {
  143.                                 fk_cldot(j,NEWY+i);
  144.                         }
  145.                         temp>>=1;
  146.                 }
  147.         }
  148. }

  149. //--------------------------------------------------------------------------//
  150. void fk_refline(yy)                                        //刷新1行背景
  151. {
  152.         uchar i;
  153.         uint temp;
  154.         if (yy>=4)
  155.         {
  156.                 temp=fk_map[yy];
  157.                 for (i=0;i<12;i++)
  158.                 {
  159.                         if ((temp&0x01) !=0)
  160.                                 fk_dot(i,yy);
  161.                         else
  162.                                 fk_cldot(i,yy);
  163.                         temp >>= 1;
  164.                 }
  165.         }
  166. }

  167. //--------------------------------------------------------------------------//
  168. bit fk_chk(void)                                        //沖突檢查
  169. {
  170.         uchar i;
  171.         bit neq=0;
  172.         for (i=0;i<4;i++)
  173.         {
  174.                 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])) )
  175.                         neq=1;
  176.         }
  177.         return(neq);
  178. }

  179. //--------------------------------------------------------------------------//
  180. void fk_new(void)                                                //產生新方塊
  181. {
  182.         srand(rand()+fk_x+fk_y+fk_r);
  183.         fk_oldx=fk_x=5;
  184.         fk_oldy=fk_y=LINEMAX;
  185.     fk_type = fk_newtype;
  186.         fk_oldr=fk_newr;
  187.     fk_newtype = rand()%7;
  188.         fk_newr=rand()%4;
  189.         fk_refnew();                        //刷新預覽方塊
  190.         if (fk_run)
  191.                 fk_reffk();        //刷新顯示
  192. }

  193. //--------------------------------------------------------------------------//
  194. void fk_add(void)                                        //方塊合并
  195. {
  196.         uchar i,j;
  197.         uchar full=0x00;
  198.         uchar fulltemp;
  199.         uchar fullline=0x00;
  200.         for (i=0;i<4;i++)        //方塊合并
  201.         {
  202.                 fk_map[fk_y+i] |= (fk_mod[fk_type][fk_r][i])<<fk_x;
  203.                 full <<= 1;
  204.                 if ((fk_y+i >= 4) && (fk_map[fk_y+i] == 0xffff))                //滿行
  205.                 {
  206.                         full |= 0x01;
  207.                 }
  208.         }
  209.         if (full != 0)                //有滿行
  210.         {
  211.                 for (j=0;j<3;j++)                //消行閃爍3次
  212.                 {
  213.                         delay(300);
  214.                         fulltemp=full;
  215.                         for (i=0;i<4;i++)        //4行
  216.                         {
  217.                                 if ((fulltemp&0x08) != 0)
  218.                                 {
  219.                                         fk_map[fk_y+i] ^= FULLMAP;
  220.                                 }
  221.                                 fk_refline(fk_y+i);
  222.                                 fulltemp <<= 1;
  223.                         }
  224.                 }
  225.                 fulltemp=full;
  226.                 for (i=fk_y;i<LINEMAX+4+fullline;i++)        //上面行下移
  227.                 {
  228.                         if ((i < LINEMAX+4)&&(fk_map[i-fullline]!=fk_map[i]))
  229.                         {
  230.                                 fk_map[i-fullline]=fk_map[i];
  231.                                 fk_refline(i-fullline);
  232.                         }
  233.                         if ((i >= LINEMAX+4)&&(fk_map[i-fullline]!=~FULLMAP))
  234.                         {
  235.                                 fk_map[i-fullline]=~FULLMAP;        //背景映象
  236.                                 fk_refline(i-fullline);
  237.                         }
  238.                         if ((fulltemp&0x08) != 0)
  239.                         {
  240.                                 fullline++;
  241.                         }
  242.                         fulltemp <<= 1;
  243.                 }
  244.                 if (((line+fullline)/LINEGUAN) != (line/LINEGUAN))//每20行速度+1
  245.                         speed ++;
  246.                 line += fullline;                                //更新分數、行數
  247.                 score += (1<<fullline)-1;
  248.                 printat(46,180,strmap[fullline-1]);        //夸獎
  249.                 fk_show();                                                //顯示分數
  250.                 fk_new();                        //產生新方塊
  251.         }
  252.         else
  253.         {
  254.                 if (fk_y > LINEMAX-10)        //在最高位置碰撞且不能消行則游戲結束
  255.                         printat(46,180,"加油啊!");                //加油啊
  256.                 if (fk_y > LINEMAX-6)        //在最高位置碰撞且不能消行則游戲結束
  257.                         printat(46,180,"糟糕了!");                //糟糕了

  258.                 if (fk_y==LINEMAX)                //在最高位置碰撞且不能消行則游戲結束
  259.                         fk_run=0;        //方塊初始化
  260.                 else
  261.                         fk_new();        //產生新方塊
  262.         }
  263. }

  264. //--------------------------------------------------------------------------//
  265. void fk_init(void)                                        //方塊初始化
  266. {
  267.         uchar i;
  268.         fk_run = 0;
  269.         moven=0;
  270.         Lcd6963Cls();
  271.         Lcd6963Rec(0,0,152,255);
  272.         Lcd6963ChHz(0);                                        //切換到16X16點陣
  273.         printat(2, 16,"歡迎光臨文君閣");
  274.         printat(2, 48,"請按鍵選擇:");
  275.         printat(2, 80,"-----------------");
  276.         printat(2, 96,"7左旋 8右旋 9右旋");
  277.         printat(2, 112,"4左移 5右旋 6右移");
  278.         printat(2, 128,"4速度 5開始 6關數");
  279.         printat(2, 144,"1左移 2下移 3右移");
  280.         printat(2, 160,"-----------------");
  281.         Lcd6963ChHz(1);                                        //切換到12X12點陣
  282.         printat(46,180,"歡迎使用");
  283.         fk_show();                                                //顯示分數
  284.         while (~fk_run)
  285.         {
  286.                 fk_move();                                        //等待設置速度關數開始
  287.                 delay(10);
  288.         }
  289.         for (i=0;i<4;i++)
  290.         {
  291.                 fk_map[i]=0xffff;        //背景映象
  292.         }        delay(3000);
  293.         for (i=4;i<LINEMAX+4;i++)
  294.         {
  295.                 if (i<(automapn+4))
  296.                         fk_map[i]=rand()-1|~FULLMAP; //背景映象
  297.                 else
  298.                         fk_map[i]=~FULLMAP;                //背景映象
  299.                 fk_refline(i);                                //刷新1行背景
  300.         }
  301.         fk_show();                                                //顯示分數
  302. //        fk_new();                                                //產生新方塊
  303. }   

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

  432. /*
  433. // ---------------------------------------------- //        32字節
  434. void delay(uint x)
  435. {
  436.    uint i,j;
  437.    for (i=0; i<x;i++) {
  438.       for (j=0;j<102; j++) ;
  439.    }
  440. }

  441. //--------------------------------------------------------------------------//
  442. void main(void)                                                // 測試用
  443. {
  444.         serial_init();
  445.         Lcd6963Init();                                        //Lcd6963復位
  446.         Lcd16Reset();                                        //Lcd16復位
  447.         Serial_main();                                        //        串口測試用主函數  
  448.         Lcd16main();                                        //Lcd16臨時測試主程序
  449.         Lcd6963main();                                        //Lcd6963測試用
  450.         fk_init();                                                //方塊初始化
  451.         while(1)
  452.         {
  453.                 if (~fk_run)
  454.                         fk_init();                                                //方塊初始化
  455.                 fk_move();                                        //移動方塊
  456.                 delay(10);
  457.         }
  458. }
  459. */
復制代碼

全部資料51hei下載地址:
20項目二十 俄羅斯方塊游戲.7z (312.71 KB, 下載次數: 28)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区三区四区 | 日本超碰在线 | 毛片视频观看 | 日本久久福利 | 日韩二 | 啪啪免费 | 欧美色专区| 一区二区三区免费在线观看 | 欧美日韩一 | 亚洲一级毛片 | 久久久久香蕉视频 | 国产一区二区三区 | 日韩免费毛片 | 欧美综合国产精品久久丁香 | 亚洲色图第一页 | 欧美精品91 | 国产精品久久久久久久久久久久 | 精品国产视频 | 国产精品免费一区二区 | 日韩一区二区在线视频 | 最新国产精品精品视频 | 四虎影音 | 一区二区精品 | 久久人操 | 欧美99| 性一爱一乱一交一视频 | 综合久久99 | 亚洲精品国产成人 | 欧美精品一区二区在线观看 | 91麻豆产精品久久久久久 | 狠狠久久 | 欧美5区 | 在线中文字幕视频 | 日韩在线中文 | 亚洲三区在线观看 | 国产ts人妖一区二区三区 | 亚洲欧美久久 | 一区二区三区四区在线视频 | 亚洲国产精品一区 | 欧美一级二级在线观看 | 欧美日韩亚洲系列 |