找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4103|回复: 4
收起左侧

51单片机俄罗斯方块代码 12864液晶显示

[复制链接]
ID:245302 发表于 2018-7-19 16:32 | 显示全部楼层 |阅读模式
用51单片机和12864显示屏,60s2芯片,独立按键做的俄罗斯方块程序,用的话改一下端口即可。
QQ图片20180719162052.jpg

单片机源程序:
  1. //说明******************************
  2. //此程序包含一个俄罗斯方块.c 文件和一个12864.h 文件
  3. //********************俄罗斯方块.c文件**************************
  4. //
  5. #include <reg51.h>        
  6. #include "12864.h"
  7. static unsigned long Seed = 1;
  8. #define A 48271L
  9. #define M 2147483647L
  10. #define Q (M / A)//44488
  11. #define R (M % A)//3399

  12. sbit K1=P3^5;
  13. sbit K2=P3^4;
  14. sbit K3=P3^3;
  15. sbit K4=P3^2;
  16. unsigned int idata num[19+2]={
  17. 0xfff,//第1行,最下面
  18. 0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,
  19. 0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,//第2行到第20行共19行
  20. 0xfff//第21行,最上面

  21. };



  22. //定义共21行,其中num[0]为下墙壁行,num[20]为上墙壁行,每行12格,最左一格为左墙壁列,最右一格为右墙壁列
  23. /*
  24.                         0 1        2 3        4 5        6 7 8 9        10 11
  25.         0   ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
  26.                 1   ■ □ □ □ □ □ □ □ □ □ □ ■
  27.                 2   ■ □ □ □ □ □ □ □ □ □ □ ■
  28.                 3   ■ □ □ □ □ □ □ □ □ □ □ ■
  29.                 4   ■ □ □ □ □ □ □ □ □ □ □ ■
  30.                 5   ■ □ □ □ □ □ □ □ □ □ □ ■
  31.                 6   ■ □ □ □ □ □ □ □ □ □ □ ■
  32.                 7   ■ □ □ □ □ □ □ □ □ □ □ ■
  33.                 8   ■ □ □ □ □ □ □ □ □ □ □ ■                  
  34.                 9   ■ □ □ □ □ □ □ □ □ □ □ ■
  35.             10  ■ □ □ □ □ □ □ □ □ □ □ ■
  36.             11  ■ □ □ □ □ □ □ □ □ □ □ ■
  37.             12  ■ □ □ □ □ □ □ □ □ □ □ ■
  38.              13        ■ □ □ □ □ □ □ □ □ □ □ ■
  39.         14        ■ □ □ □ □ □ □ □ □ □ □ ■
  40.             15        ■ □ □ □ □ □ □ □ □ □ □ ■
  41.             16        ■ □ □ □ □ □ □ □ □ □ □ ■
  42.             17        ■ □ □ □ □ □ □ □ □ □ □ ■
  43.             18        ■ □ □ □ □ □ □ □ □ □ □ ■
  44.             19        ■ □ □ □ □ □ □ □ □ □ □ ■
  45.             20        ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■


  46. */
  47. unsigned char code Block[28][2]={
  48. /*
  49. *   口     口口口   口口
  50. *   口     口         口      口
  51. *   口口              口  口口口      
  52. */
  53. {0x88,0xc0},{0xe8,0x00},{0x62,0x20},{0x02,0xe0},
  54. /*
  55. *   口        口口 口口口
  56. *   口 口     口       口
  57. * 口口 口口口 口   
  58. */
  59. {0x22,0x60},{0x08,0xe0},{0xc8,0x80},{0xe2,0x00},  
  60. /*
  61. *   口
  62. *   口口         口口
  63. *     口       口口
  64. */
  65. {0x8c,0x40},{0x6c,0x00},{0x8c,0x40},{0x6c,0x00},
  66. /*
  67. *   口        口口
  68. * 口口          口口
  69. * 口
  70. */
  71. {0x4c,0x80},{0xc6,0x00},{0x4c,0x80},{0xc6,0x00},  
  72. /*
  73. *          口                口
  74. *   口     口口   口口口   口口
  75. * 口口口   口       口       口
  76. */
  77. {0x04,0xe0},{0x8c,0x80},{0xe4,0x00},{0x26,0x20},
  78. /*口
  79. * 口
  80. * 口       口口口口
  81. * 口
  82. */
  83. {0x44,0x44},{0x0f,0x00},{0x44,0x44},{0x0f,0x00},  
  84. /*
  85. * 口口
  86. * 口口
  87. */  
  88. {0x06,0x60},{0x06,0x60},{0x06,0x60},{0x06,0x60}
  89. };

  90. #define PASSSCORE 20


  91. struct Jimu
  92. {
  93.         unsigned int dat;
  94.          char x;
  95.         unsigned char y;
  96.         unsigned char type;
  97.         unsigned char change;
  98. }Sign[3];//积木结构体

  99. unsigned char SysFlag=0;
  100. #define NEWSIGNFLAG 0
  101. #define DEADFLAG 1
  102. #define PAUSEFLAG 2

  103. unsigned char Score=0;
  104. unsigned char Level=1;
  105. unsigned char DelayCnt=5;


  106. /*********************************************************/
  107. #define N 25
  108. /************************************
  109. 伪随机数发生器
  110. *************************************/
  111. double Random(void)
  112. {
  113.         long TmpSeed;
  114.         TmpSeed=A*(Seed%Q)-R*(Seed/Q);
  115.         if(TmpSeed>=0)
  116.                 Seed=TmpSeed;
  117.         else
  118.                 Seed=TmpSeed+M ;
  119.         return (double)Seed/M;
  120. }

  121. /**************************************
  122. 为伪随机数发生器播种
  123. ***************************************/
  124. void InitRandom(unsigned long InitVal)
  125. {
  126.         Seed=InitVal;
  127. }

  128. //延时子程序
  129. void Delay(unsigned int t)
  130. {  
  131.         unsigned int i,j;
  132.         for(i=0;i<t;i++)
  133.                 for(j=0;j<10;j++);   
  134. }
  135. /*********************************
  136. 初始化MPU
  137. **********************************/
  138. void InitCpu(void)
  139. {
  140.          TMOD=0x0;
  141.         TH0=0;
  142.         TL0=0;
  143.         TR0=1;
  144.         ET0=1;               
  145.         EX1=1;
  146.         EA=1;
  147.     TCON|=0x04;
  148. }
  149. /****************************
  150. welcome          游戏选择界面
  151. /**********************/
  152. void welcome()
  153. {
  154.         Lcd_WriteStr(0,0,"欢迎来玩");
  155.         Lcd_WriteStr(0,1,"俄罗斯方块 ");
  156.         Lcd_WriteStr(0,2,"设置按K1");
  157.         Lcd_WriteStr(0,2,"开玩按K2");
  158.         
  159. }
  160. /**************************************************俄罗斯方块部分******************************************************8**********/



  161. /******************************画墙壁,初始化界面*******************************/
  162. void DrawBoard(void)
  163. {
  164.         unsigned char n;
  165.         for(n=0;n<12;n++)
  166.         {
  167.                 Lcd_Rectangle(3*n,0,3*n+2,2,1);
  168.                 Lcd_Rectangle(3*n,60,3*n+2,62,1);
  169.         }
  170.         for(n=0;n<20;n++)
  171.         {
  172.                 Lcd_Rectangle(0,3*n,2,3*n+2,1);
  173.                 Lcd_Rectangle(33,3*n,35,3*n+2,1);               
  174.         }
  175.         Lcd_WriteStr(4,0,"经典游戏");
  176.         Lcd_WriteStr(3,2,"Score:");
  177.         Lcd_WriteStr(3,3,"Level:");
  178. }

  179. /***********************************
  180. 游戏结束处理
  181. ************************************/
  182. void GameOver(void)
  183. {
  184.         if((SysFlag&(1<<DEADFLAG))!=0)
  185.                 Lcd_WriteStr(3,1,"You Fail");
  186.         else
  187.                 Lcd_WriteStr(3,1,"You Pass");
  188. }

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

  193. /**********************************
  194. 根据积木图标左下坐标X,Y来画出积木图标
  195. ***********************************/
  196. void DrawSign(struct Jimu Temp,unsigned char DrawMode)
  197. {
  198.         unsigned char m,n;
  199.         for(m=0;m<4;m++)
  200.                 for(n=0;n<4;n++)
  201.                 {
  202.                         if((Temp.dat&MaskTab[4*m+n])!=0)
  203.                                 Lcd_Rectangle(Temp.x+n*3,Temp.y-2-3*m,Temp.x+n*3+2,Temp.y-3*m,DrawMode);
  204.                 }
  205. }

  206. /********************************
  207. 将积木图标值融入num数据中
  208. 也即把积木图标固定,无法再下降
  209. *********************************/
  210. void FixSign(void)
  211. {
  212.         unsigned char m,n;
  213.         for(m=0;m<4;m++)//行循环
  214.                 for(n=0;n<4;n++)//列循环
  215.                 {
  216.                         if((Sign[0].dat&MaskTab[4*m+n])!=0)
  217.                         {
  218.                                 num[20-(Sign[0].y-2)/3+m]|=MaskTab[11-Sign[0].x/3-n];
  219.                         }
  220.                 }
  221. }

  222. /********************************
  223. 判断积木图标中方块是否与障碍方块重合
  224. *********************************/
  225. unsigned char CheckIf(void)
  226. {
  227.         unsigned char m,n;
  228.         for(m=0;m<4;m++)//行循环
  229.                 for(n=0;n<4;n++)//列循环
  230.                 {
  231.                         if((Sign[1].dat&MaskTab[4*m+n])!=0)
  232.                         {
  233.                                 if((num[20-(Sign[1].y-2)/3+m]&MaskTab[11-Sign[1].x/3-n])!=0)
  234.                                         return 0;
  235.                         }
  236.                 }
  237.         return 1;
  238. }

  239. /********************************
  240. 判断积木图标是否可以继续下降一格
  241. ********************************/
  242. unsigned char CheckIfDown(void)
  243. {
  244.         Sign[1]=Sign[0];//
  245.         Sign[1].y+=3;//假设下降一格        
  246.         return CheckIf();
  247.         
  248. }

  249. /********************************
  250. 判断积木图标是否可以向左移动
  251. *********************************/
  252. unsigned char CheckIfLeft(void)
  253. {
  254.         Sign[1]=Sign[0];
  255.         Sign[1].x-=3;        
  256.         return CheckIf();
  257. }

  258. /********************************
  259. 判断积木图标是否可以向右移动
  260. *********************************/
  261. unsigned char CheckIfRight(void)
  262. {
  263.         Sign[1]=Sign[0];
  264.         Sign[1].x+=3;        
  265.         return CheckIf();
  266. }

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

  284. /********************************
  285. 寻找满格的行并做消除处理
  286. 最多寻找4个满行并做消除
  287. *********************************/
  288. void DelFull(void)
  289. {
  290.         unsigned char m,n;
  291.         unsigned char Temp;
  292.         unsigned char Flag=0;
  293.         Temp=(Sign[0].y-2)/3;
  294.         if(Temp>=20)//防止越过了下边界
  295.                 Temp=1;
  296.         else
  297.                 Temp=20-Temp;
  298.         for(n=Temp+3;n>=Temp;n--)//积木图标的最顶行开始寻找满行比较有利于运算
  299.         {
  300.                 if(num[n]==0xfff)
  301.                 {
  302.                         Flag=1;
  303.                         for(m=n+1;m<=19;m++)
  304.                         {
  305.                                 num[m-1]=num[m];
  306.                         }
  307.                         num[m]=0x801;
  308.                         Score++;//每找到一个满行,则分数加1
  309.                 }
  310.         }
  311.         if(Flag)//为加速而设置并判断的标志,有已固定的积木有满格消行变化则重画积木界面
  312.         {
  313.                 for(m=Temp;m<=19;m++)//为加速,不必要重第一行重画起,只需要从积木图标最下行开始往上的重画
  314.                         for(n=1;n<=10;n++)
  315.                         {
  316.                                 if((num[m]&MaskTab[n])==0)
  317.                                 {        
  318.                                         if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)!=0)//为加速而做的读象素操作
  319.                                         {
  320.                                                 Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,0);
  321.                                         }
  322.                                 }
  323.                                    else
  324.                                 {
  325.                                         if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)==0)//为加速而做的读象素操作
  326.                                         {
  327.                                                 Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,1);
  328.                                         }
  329.                                 }
  330.                         }
  331.         }
  332. }


  333. /*******************************
  334. 随机产生一个积木图标放到预产生区域并显示出来
  335. ********************************/
  336. void CreatSign(void)
  337. {
  338.         unsigned char n;
  339.         unsigned int Temp;

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

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

  351. void PrintScore(void)
  352. {
  353.         unsigned char Str[3];
  354.         Str[0]=(Score/10)|0x30;
  355.         Str[1]=(Score%10)|0x30;
  356.         Str[2]=0;
  357.         Lcd_WriteStr(6,2,Str);
  358. }
复制代码


全部资料51hei下载地址:
参考代码--俄罗斯游戏代码.zip (62.52 KB, 下载次数: 76)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:402815 发表于 2018-9-26 19:25 | 显示全部楼层
12864,俄罗斯方块
回复

使用道具 举报

ID:282941 发表于 2018-11-26 20:55 | 显示全部楼层
楼主,有对应的电路图。
回复

使用道具 举报

ID:435181 发表于 2018-11-28 19:47 | 显示全部楼层
有电路图吗?楼主
回复

使用道具 举报

ID:375381 发表于 2018-12-10 16:14 来自手机 | 显示全部楼层
八个数据传输口是哪个?p1还是p2
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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