找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3473|回复: 1
收起左侧

单片机打地鼠游戏源程序与Proteus仿真电路

[复制链接]
ID:273434 发表于 2020-10-20 22:06 | 显示全部楼层 |阅读模式
最近新接触的一个小游戏,打地鼠,已经用开发板验证

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<stdlib.h>
  3. sbit RS=P2^0;
  4. sbit EN=P2^1;
  5. sbit Speak=P2^2;
  6. sbit button1=P2^3;            //选择模式键
  7. sbit button2=P2^4;                //确认键、返回键、暂停键、下一关开始键
  8. sbit Buzzer=P2^6;
  9. sbit hole1=P2^7;        //1号洞
  10. sbit SDA=P1^1;                //24c02数据线
  11. sbit SCL=P1^0;                //24c02时钟线
  12. unsigned char Count;        //Play_Song使用
  13. unsigned char i,j;
  14. unsigned char temp;                //随机数种子
  15. unsigned char result;        //随机数临时变量
  16. unsigned char score;        //保存临时分数
  17. unsigned char tempname[2];//保存临时分数的名字
  18. unsigned char time;                //保存时间(30秒倒计时)
  19. unsigned char num;                //1秒钟判断变量
  20. unsigned char flag1;        //1标识得分,led全灭,不进行scankey操作
  21. unsigned char flag2;        //1标识得分Buzzer响方式1
  22. unsigned char flag3;        //1标识地鼠出洞时间到,开始下一轮地鼠出洞
  23. unsigned char flag4;        //1标识关卡时间到
  24. unsigned char flag5;        //1标志暂停
  25. unsigned char level;        //关卡等级
  26. unsigned char holenum;        //保存随机生成的洞号
  27. unsigned char topscore[3]={0}; //保存3个最高分
  28. unsigned char name[3][2]={"AA","BB","CC"};  //保存3个最高分名字          
  29. unsigned char code hole[]={0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//P3口控制的洞       
  30. unsigned char code str1[]={"Welcome!"};                                //欢迎标语
  31. unsigned char code str2[]={"1.start 2.score"};
  32. unsigned char code str3[]={"3.exit"};                               
  33. unsigned char code str4[]={"See You! "};                                //exit界面
  34. unsigned char code str5[]={"Ready?"};
  35. unsigned char code str6[]={"GO!"};
  36. unsigned char code str7[]={"Your Soccer: "};                        //查看分数
  37. unsigned char code str8[]={"Time:   Score:  "};
  38. unsigned char code str9[]={" Team: SONGE "};                        //队名
  39. unsigned char code str10[]={"Game Over!"};       
  40. unsigned char code str11[]={"You Win! GO?"};       
  41. unsigned char code str12[]={"You Lose!"};
  42. unsigned char code str13[]={"top1:"};
  43. unsigned char code str14[]={"Congratulations"};
  44. unsigned char code str15[]={"hole:   level:"};
  45. unsigned char code str16[]={"top2:"};
  46. unsigned char code str17[]={"top3:"};
  47. unsigned char code str18[]={"Your Name:"};                        //记录姓名
  48. //*************************1602函数声明*******************************//
  49. void displayWelcome();                                        //显示欢迎界面
  50. void displayPrepare();                                        //显示选项
  51. void Game();                                                        //游戏真正进行
  52. void displayGame();                                                  //开始游戏
  53. void displayExit();                                                 //显示退出界面
  54. void displaytime();
  55. void displayChoose();                                         //显示选择界面
  56. void displayover();
  57. void scankey();
  58. void pause();
  59. void displayScoreNext();
  60. //***************************基础函数*****************************//
  61. void delayms(unsigned int xms)        //延时xms 毫秒
  62. {
  63.         unsigned int i,j;
  64.         for(i=xms; i>0; i--)
  65.                 for(j=110; j>0; j--);
  66. }
  67. void delayus(unsigned int ums)        //延时ums 个3微秒
  68. {
  69.         unsigned int i,j;
  70.         for(i=0; i<ums; i++)
  71.                 for(j=0; j<3; j++);
  72. }

  73. void Time_init()           //定时器初始化,11.0592MZ晶振                 初始选择:定时器0用于播放音乐,定时器1关闭
  74. {                                                                                                          //进入游戏:定时器1用于LCD显示分数
  75.         TMOD = 0x11;        //16位定时器                                                退出游戏:定时器0播放音乐,定时器1关闭
  76.         TH0  = 0xDC;
  77.         TL0  = 0x00;               
  78.         TH1=(65536-45872)/256;
  79.         TL1=(65536-45872)%256;
  80.         EA=1;                         //开总中断
  81.         ET0=1;                        //开定时器0中断
  82.         ET1=1;                        //开定时器1中断
  83. }

  84. void Time0() interrupt 1                        //定时器0中断        播放音乐
  85. {
  86.         TH0 = 0xDC;
  87.         TL0 = 0x00;
  88.         Count++;                        //长度加1
  89. }

  90. void Time1() interrupt 3                        //定时器1中断        游戏中显示分数
  91. {
  92.         TH1=(65536-45872)/256;                               
  93.         TL1=(65536-45872)%256;                        //每50ms中断一次
  94.         num++;
  95.         if(num%20==0)                                //近似1秒钟
  96.         {
  97.                 time--;
  98.         }
  99.         if(num==(60-20*level))        //出洞结束,level1:3s; level2:2s; level3:1s
  100.         {
  101.                 num=0;
  102.                 flag3=1;
  103.         }
  104.         if(time==0)                //一关结束
  105.         {
  106.                 time=30;
  107.                 flag4=1;
  108.         }
  109. }

  110. //***********************播放音乐*********************************//

  111. unsigned char code SONG[] ={      //祝你平安
  112.                         0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
  113.                         0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x00,           //27个数字
  114.                         //0x20,0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,
  115.                         //0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
  116.                         //0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
  117.                         //0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
  118.                         //0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
  119.                         //0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
  120.                         //0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
  121.                         //0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
  122.                         //0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
  123.                         //0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
  124.                         //0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
  125.                         //0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
  126.                         //0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,//第217个数字
  127.                                                           //路边的野花不要采
  128.                         //        0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,0x1C,
  129.                         //        0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,
  130.                         0x20,0x30,0x1C,0x10,0x18,0x20,
  131.                         0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,
  132.                         0x30,0x80,0xFF,0x20,0x20,0x00,
  133.                         //0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
  134.                         //0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
  135.                         //0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,
  136.                         //0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20,
  137.                         //0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x15,0x1F,
  138.                         //0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,
  139.                         //0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,
  140.                         //0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,
  141.                         //0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,
  142. };

  143. void Play_Song(unsigned char i)                //i=1 播放 路边的野花不要采
  144. {                                                                        //i=0 播放 祝你平安
  145.         unsigned char Temp1,Temp2;
  146.         unsigned int Addr;
  147.         Count = 0;                                                //中断计数器清0
  148.         Addr = i * 27;         //音乐地址
  149.         TR0=1;                        //开启定时器0
  150.         while(1)
  151.         {
  152.                 Temp1 = SONG[Addr++];
  153.             if (Temp1 == 0xFF)          //休止符
  154.             {
  155.                     TR0 = 0;                                 //关闭定时器0
  156.                     delayus(100);
  157.             }
  158.             else if (Temp1 == 0x00)           //歌曲结束符
  159.             {
  160.                         TR0=0;                                           //关闭定时器0
  161.                     return;
  162.             }
  163.             else                                           //正常播放歌曲
  164.             {
  165.                     Temp2 = SONG[Addr++];
  166.                     TR0 = 1;
  167.                           while(1)
  168.                           {
  169.                             Speak = ~Speak;
  170.                             delayus(Temp1);
  171.                             if(Temp2 == Count)
  172.                             {
  173.                                     Count = 0;
  174.                                     break;
  175.                             }
  176.                     }
  177.             }
  178.         }
  179. }

  180. void playBuzzer()
  181. {
  182.   
  183.         if(flag2==1)  //得分响
  184.         {
  185.            for(i=0;i<20;i++)
  186.             {        Speak=1;
  187.                     delayms(1);                       
  188.                     Speak=0;
  189.                         delayms(1);
  190.               }
  191.         Speak=0;Buzzer=0;delayms(500);Buzzer=1;delayms(100);                 
  192.         }
  193.         else
  194.         {
  195.                
  196.         }

  197. }
  198. //******************************24C02环节*************************************//
  199. void init()
  200. {
  201.         SDA=1;
  202.         delayms(5);
  203.         SCL=1;
  204.         delayms(5);
  205. }
  206. void start()        //开始信号
  207. {
  208.         SDA=1;
  209.         delayms(5);
  210.         SCL=1;
  211.         delayms(5);
  212.         SDA=0;
  213.         delayms(5);       
  214. }
  215. void stop()                //停止信号
  216. {
  217.         SDA=0;
  218.         delayms(5);
  219.         SCL=1;
  220.         delayms(5);
  221.         SDA=1;
  222.         delayms(5);
  223. }
  224. void respons()        //应答
  225. {
  226.         unsigned char i;
  227.         SCL=1;
  228.         delayms(5);
  229.         while((SDA==1)&&(i<250))
  230.                 i++;
  231.         SCL=0;
  232.         delayms(5);
  233. }

  234. void write_byte(unsigned char date)//写字节
  235. {
  236.         unsigned char i,temp,j;
  237.         temp=date;
  238.         for(i=0; i<8; i++)
  239.         {
  240.                 j=0x80&temp;
  241.                 temp=temp<<1;
  242.                 SCL=0;
  243.                 delayms(5);
  244.                 SDA=(bit)j;
  245.                 delayms(5);
  246.                 SCL=1;
  247.                 delayms(5);
  248.         }
  249.         SCL=0;
  250.         delayms(5);
  251.         SDA=1;
  252.         delayms(5);
  253. }
  254. unsigned char read_byte()//读字节
  255. {
  256.         unsigned char i,k;
  257.         SCL=0;
  258.         delayms(2);
  259.         SDA=1;
  260.         for(i=0; i<8; i++)
  261.         {
  262.                 SCL=1;
  263.                 delayms(5);
  264.                 k=(k<<1)|SDA;
  265.                 SCL=0;
  266.                 delayms(5);
  267.         }
  268.         return k;
  269. }
  270. void write_add(unsigned char address,unsigned char date)//往地址写数据
  271. {
  272.         start();
  273.         write_byte(0xa0);        //控制字写1010 000 0(写操作)
  274.         respons();
  275.         write_byte(address);//存储单元地址
  276.         respons();
  277.         write_byte(date);
  278.         respons();

  279.         stop();
  280. }
  281. unsigned char read_add(unsigned char address)        //往地址中读数据
  282. {
  283.         unsigned char date;
  284.         start();
  285.         write_byte(0xa0);         //控制字 写
  286.         respons();
  287.         write_byte(address); //单元地址
  288.         respons();
  289.         start();
  290.         write_byte(0xa1);         //控制字读1010 000 1(读操作)
  291.         respons();
  292.         date=read_byte();         //数据
  293.         SDA=1;                   //非应答
  294.         delayus(5);          
  295.         SCL=1;
  296.         delayus(5);
  297.         stop();
  298.         return date;
  299. }
  300. void getRecord()        //读取前三名分数
  301. {
  302.          topscore[0]=read_add(0);//第一名
  303.          name[0][0]=read_add(1);
  304.          name[0][1]=read_add(2);
  305.          topscore[1]=read_add(3);//第二名
  306.          name[1][0]=read_add(4);
  307.          name[1][1]=read_add(5);
  308.          topscore[2]=read_add(6);//第三名
  309.          name[2][0]=read_add(7);
  310.          name[2][1]=read_add(8);
  311. }
  312. void Record()        //更新前三并记录分数
  313. {
  314.         write_add(0,topscore[0]);//第一名
  315.         write_add(1,name[0][0]);
  316.         write_add(2,name[0][1]);
  317.         write_add(3,topscore[1]);//第二名
  318.         write_add(4,name[1][0]);
  319.         write_add(5,name[1][1]);
  320.         write_add(6,topscore[2]);//第三名
  321.         write_add(7,name[2][0]);
  322.         write_add(8,name[2][1]);
  323. }

  324. void Judge()           //判断分数高低
  325. {
  326.         if(score>topscore[0])
  327.         {
  328.                 topscore[2]=topscore[1];//第二名赋给第三名
  329.                 name[2][0]=name[1][0];
  330.                 name[2][1]=name[1][1];
  331.                 topscore[1]=topscore[0];//第一名赋给第二名
  332.                 name[1][0]=name[0][0];
  333.                 name[1][1]=name[0][1];
  334.                 topscore[0]=score;                //临时变量赋给第一名
  335.                 name[0][0]=tempname[0];
  336.                 name[0][1]=tempname[1];

  337.         }else if(score>topscore[1])
  338.         {
  339.                 topscore[2]=topscore[1];//第二名赋给第三名
  340.                 name[2][0]=name[1][0];
  341.                 name[2][1]=name[1][1];
  342.                 topscore[1]=score;           //临时变量赋给第二名
  343.                 name[1][0]=tempname[0];
  344.                 name[1][1]=tempname[1];

  345.         }else if(score>topscore[2])
  346.         {
  347.                 topscore[2]=score;           //临时变量赋给第三名
  348.                 name[2][0]=tempname[0];
  349.                 name[2][1]=tempname[1];
  350.         }
  351. }
  352. //*******************************1602环节*************************************//                                                                  
  353. void wr_com(unsigned char com)        //写指令
  354. {  
  355.         delayms(5);
  356.         RS=0;
  357.         EN=0;
  358.         P0=com;
  359.         delayms(5);
  360.         EN=1;
  361.         delayms(5);
  362.         EN=0;
  363. }

  364. void wr_dat(unsigned char dat)        //写数据
  365. {  
  366.         delayms(5);
  367.         RS=1;
  368.         EN=0;
  369.         P0=dat;
  370.         delayms(5);
  371.         EN=1;
  372.         delayms(5);
  373.         EN=0;
  374. }

  375. void lcd_init()                                                //1602初始化设置//
  376. {
  377.         delayms(1);
  378.         wr_com(0x38);           //设置16*2显示,5*7点阵,8位数据接口
  379.         wr_com(0x01);           //显示清0,数据指针清0
  380.         wr_com(0x06);           //写一个字符后地址加一
  381.         wr_com(0x0c);           //设置开显示,不显示光标
  382.         getRecord();          
  383. }
  384. void displayWelcome()                                        //显示欢迎界面
  385. {
  386.         wr_com(0x80+0x03);
  387.         delayms(1);
  388.         for(i=0; i<9; i++)
  389.         {       
  390.                 wr_dat(str1[i]);
  391.                 delayus(1);
  392.         }
  393.         wr_com(0xc0+0x01);
  394.         delayms(1);
  395.         for(i=0; i<13; i++)
  396.         {
  397.                 wr_dat(str9[i]);
  398.                 delayus(1);
  399.         }
  400.         for(i=0; i<10; i++)                //开关显示完成闪烁
  401.         {
  402.                 if(j==0)
  403.                 {
  404.                         wr_com(0x08);        //关显示
  405.                         delayms(100);   
  406.                 }else
  407.                 {
  408.                         wr_com(0x0c);        //开显示   
  409.                         delayms(100);
  410.                 }
  411.                 j=~j;
  412.         }
  413.         Play_Song(0);
  414.         delayms(100);
  415. }
  416. void displayPrepare()                //显示选项
  417. {
  418.         wr_com(0x01);                //清屏
  419.         delayms(5);
  420.         wr_com(0x80);
  421.         delayms(5);
  422.         for(i=0; i<15; i++)
  423.         {
  424.                 wr_dat(str2[i]);
  425.                 delayus(5);
  426.         }
  427.         wr_com(0x80+0x40);
  428.         delayms(5);
  429.         for(i=0; i<6; i++)
  430.         {
  431.                 wr_dat(str3[i]);
  432.                 delayus(5);
  433.         }
  434.         for(i=0; i<9; i++)
  435.         {
  436.                 switch(i%3)
  437.                 {
  438.                         case 0:hole1=0;P3=0x00;delayms(100);
  439.                         case 1:hole1=0;P3=0x55;delayms(100);
  440.                         case 2:hole1=1;P3=0xaa;delayms(100);
  441.                 }
  442.         }
  443.         hole1=0;
  444.         P3=0x00;
  445. }
  446. void displaytime()                                 //游戏过程中刷新显示时间、分数
  447. {
  448.         wr_com(0x80+0x05);           //显示倒计时
  449.         delayus(5);
  450.         wr_dat(0x30+time/10);
  451.         delayus(5);
  452.         wr_dat(0x30+time%10);
  453.         delayus(5);
  454.         wr_com(0x80+0x0e);           //显示分数
  455.         delayus(5);
  456.         wr_dat(0x30+score/10);
  457.         delayus(5);
  458.         wr_dat(0x30+score%10);
  459.         delayus(5);
  460.         wr_com(0xc0+0x0e);           //显示关卡
  461.         delayus(5);
  462.         wr_dat(0x30+(level+1));
  463.         delayus(5);               
  464. }
  465. void recordName()                                        //记录姓名
  466. {
  467.         wr_com(0x01);
  468.         delayus(5);
  469.         wr_com(0x80);
  470.         delayus(5);
  471.         for(i=0; i<10; i++)        //Your Name:
  472.         {
  473.                 wr_dat(str18[i]);
  474.                 delayus(5);
  475.         }
  476.         i='A';
  477.         wr_dat(i);
  478.         delayus(5);
  479.         wr_com(0x10);        //光标左移
  480.         delayus(5);       
  481.         wr_com(0x0f);        //光标闪烁
  482.         delayus(5);
  483.        
  484.        
  485.         while(1)            //输入第一个字母
  486.         {       
  487.                 wr_com(0x80+0x0a);
  488.                 delayus(5);
  489.                 wr_dat(i);
  490.                 delayus(5);
  491.                 if(button1==0)
  492.                 {
  493.                         delayms(10);
  494.                         if(button1==0)
  495.                         {
  496.                                 while(!button1);
  497.                                 i++;
  498.                                 if(i>'Z')
  499.                                         i='A';
  500.                         }
  501.                 }
  502.                 if(button2==0)//确认,开始输入第二个字母
  503.                 {
  504.                         tempname[0]=i;
  505.                         break;          
  506.                 }
  507.         }
  508.         i='A';                        //输入第二个字母
  509.         wr_dat(i);
  510.         delayus(5);
  511.         while(1)
  512.         {
  513.                 wr_com(0x80+0x0b);
  514.                 delayus(5);
  515.                 wr_dat(i);
  516.                 delayus(5);
  517.                 if(button1==0)
  518.                 {
  519.                         delayms(10);
  520.                         if(button1==0)
  521.                         {
  522.                                 while(!button1);
  523.                                 i++;
  524.                                 if(i>'Z')
  525.                                         i='A';
  526.                         }
  527.                 }
  528.                 if(button2==0)//确认,输入完毕
  529.                 {
  530.                         tempname[1]=i;
  531.                         break;          
  532.                 }
  533.         }
  534.         wr_com(0x0c);        //关闭光标
  535.         delayus(5);
  536.         displayChoose();               
  537. }
  538. void displayover()                           //显示一轮游戏结束画面
  539. {
  540.         TR1=0;        //关闭定时器1
  541.         wr_com(0x01);
  542.         delayms(5);
  543.         wr_com(0x80);
  544.         delayms(5);
  545.         for(i=0; i<10; i++)        //Game Over
  546.         {
  547.                 wr_dat(str10[i]);
  548.                 delayus(5);
  549.         }
  550.         wr_com(0xc0);
  551.         delayus(5);
  552.        
  553.         if(score>=(10*(1+level))) //不同level分数要求不同,win了
  554.         {
  555.                 if(level==3) //通关了
  556.                 {
  557.                         level=0;
  558.                         wr_com(0x80);
  559.                         delayus(5);
  560.                         for(i=0; i<15; i++)
  561.                         {
  562.                                 wr_dat(str14[i]);
  563.                                 delayus(5);
  564.                         }
  565.                         wr_com(0xc0);
  566.                         delayus(5);
  567.                         for(i=0; i<8; i++)
  568.                         {
  569.                                 wr_dat(str11[i]);
  570.                                 delayus(5);
  571.                         }
  572.                         while(1)
  573.                         {
  574.                                 if(button2==0)
  575.                                 {
  576.                                         delayms(10);
  577.                                         if(button2==0)
  578.                                         {
  579.                                                 while(!button2);
  580.                                                 recordName();                                                 
  581.                                         }
  582.                                 }
  583.                         }       
  584.                 }
  585.                 else                    //升级了
  586.                 {
  587.                         for(i=0; i<12; i++)          //You Win!
  588.                         {
  589.                                 wr_dat(str11[i]);
  590.                                 delayus(5);
  591.                         }               
  592.                                
  593.                         while(1)
  594.                         {
  595.                                
  596.                                 if(button2==0)
  597.                                 {
  598.                                         delayms(10);
  599.                                         if(button2==0)
  600.                                         {
  601.                                                 while(!button2);
  602.                                                 level++;
  603.                                                 displayGame();       
  604.                                         }
  605.                                 }
  606.                         }
  607.                 }
  608.         }
  609.         else                 //You Lose!
  610.         {
  611.                 for(i=0; i<9; i++)
  612.                 {
  613.                         wr_dat(str12[i]);
  614.                         delayus(5);
  615.                 }
  616.         }

  617.         while(1)        //失败了
  618.         {
  619.                 if(button2==0)
  620.                 {
  621.                         delayms(10);
  622.                         if(button2==0)
  623.                         {
  624.                                 while(!button2);
  625.                                 if(score!=0)        //0分不记录
  626.                                         recordName();
  627.                                 displayChoose();                                                 
  628.                         }
  629.                 }
  630.         }
  631. }
  632. void scankey()                                        //扫描按键,判断是否得分
  633. {
  634.     if((hole1==0) && (P3==0x00))//打中地鼠
  635.         {
  636.                 delayms(5);       
  637.                         flag1=1;   //标志得分不进行scankey
  638.                         flag2=1;   //标识得分buzzer
  639.                         score++;
  640.                         playBuzzer();
  641.                         hole1=0;
  642.                         P3=0x00;               

  643.         }
  644. }
  645. unsigned char random()                //随机数
  646. {
  647.         temp++;
  648.         result=rand()%9+1;
  649.         return result;

  650. }
  651. void displayhole()                          //hole地鼠显示
  652. {
  653.         holenum=random();
  654.         if(holenum==0)
  655.                 holenum++;
  656.         wr_com(0xc0+0x06);
  657.         delayus(5);
  658.         wr_dat(0x30+holenum);
  659.         delayus(5);
  660.         switch(holenum)
  661.         {
  662.                 case 0:        break;
  663.                 case 1:                          //1号洞亮
  664.                                 hole1=1;
  665.                                 P3=hole[1];
  666.                                 break;          
  667.                 case 2:                                 //2号洞亮
  668.                                 hole1=0;
  669.                                 P3=hole[2];
  670.                                 break;          
  671.                 case 3:                                 //3号洞亮
  672.                                 hole1=0;
  673.                                 P3=hole[3];
  674.                                 break;          
  675.                 case 4:                                 //4号洞亮
  676.                                 hole1=0;
  677.                                 P3=hole[4];
  678.                                 break;          
  679.                 case 5:                                 //5号洞亮
  680.                                 hole1=0;
  681.                                 P3=hole[5];
  682.                                 break;          
  683.                 case 6:                                 //6号洞亮
  684.                                 hole1=0;
  685.                                 P3=hole[6];
  686.                                 break;          
  687.                 case 7:                                //7号洞亮
  688.                                  hole1=0;
  689.                                 P3=hole[7];
  690.                                 break;          
  691.                 case 8:                                 //8号洞亮
  692.                                 hole1=0;
  693.                                 P3=hole[8];
  694.                                 break;          
  695.                 case 9:                                 //9号洞亮
  696.                                 hole1=0;
  697.                                 P3=hole[9];
  698.                                 break;          
  699.         }
  700. }
  701. void pause()                                //暂停/恢复游戏
  702. {
  703.         if(button2==0)                //暂停键
  704.         {
  705.             delayms(5);                //去抖动
  706.             if(button2==0)
  707.                 {
  708.                            while(!button2);
  709.                         TR1=~TR1;
  710.                         flag5=~flag5;                
  711.                         return;
  712.                 }
  713.         }
  714. }
  715. void Gameinit()                         //游戏开始时数据初始化
  716. {
  717.         flag1=0;//scankey标识
  718.         flag2=0;//蜂鸣器标志位
  719.         flag3=0;//出洞结束标识
  720.         flag4=0;//timeover标识
  721.         time=30;
  722.         if(level==0)        //重新开始闯关,则清零得分
  723.                 score=0;
  724.         wr_com(0x01);           //清屏
  725.         delayus(5);
  726.         wr_com(0x80);
  727.         delayus(5);
  728.         for(i=0; i<15; i++)                //固定内容显示
  729.         {
  730.                 wr_dat(str8[i]);
  731.                 delayus(5);
  732.         }
  733.         wr_com(0xc0);
  734.         delayus(5);
  735.         for(i=0; i<14; i++)
  736.         {
  737.                 wr_dat(str15[i]);
  738.                 delayus(5);
  739.         }
  740. }
  741. void Game()                                                                                                //游戏真正进行!!!!!!!!!!
  742. {
  743.         Gameinit();
  744.         displaytime();        //显示时间、分数、洞、关卡
  745.         TR1=1;                //开启定时器1
  746.         while(1)        
  747.         {
  748.                 displayhole();                //地鼠出洞
  749.                 while(!flag3)//地鼠出洞时间 level:3s; level2:2s; level3:1s
  750.                 {
  751.                         if(flag5==0)
  752.                         {
  753.                                 if(flag1==0)
  754.                                         scankey();
  755.                                 displaytime();
  756.                         }
  757.                         pause();        //暂停键判断
  758.                 };
  759.                 if(flag2==0)//没有打中地鼠
  760.                 {
  761.                         playBuzzer();
  762.                 }
  763.                 if(flag4==1)//时间到,结束game
  764.                 {
  765.                         displayover();
  766.                 }
  767.                 flag1=0;//scankey标识
  768.                 flag2=0;//蜂鸣器标志位
  769.                 flag3=0;//出洞结束标识
  770.                 flag4=0;//timeover标识
  771.         }

  772. }
  773. void displayGame()                                                   //开始游戏
  774. {
  775.         wr_com(0x01);        //清屏
  776.         delayms(5);
  777.         wr_com(0x80+0x04);
  778.         delayms(5);
  779.         for(i=0; i<6; i++) //显示Ready
  780.         {
  781.                 wr_dat(str5[i]);
  782.                 delayus(5);       
  783.         }
  784.         wr_com(0xc0+0x06);
  785.         delayms(5);
  786.         for(i=5; i>0; i--) //显示倒数5秒
  787.         {       
  788.                 wr_dat(0x30+i);
  789.                 for(j=0; j<10; j++)
  790.                         delayms(100);
  791.                 wr_com(0xc0+0x06);
  792.                 delayms(5);
  793.         }
  794.         wr_com(0xc0+0x06);
  795.         delayms(5);
  796.         for(i=0; i<3; i++) //显示GO
  797.         {
  798.                 wr_dat(str6[i]);
  799.                 delayus(5);
  800.         }
  801.         delayms(200);
  802.         Game();                //开始游戏!
  803. }
  804. void displayScore()                                                  //显示得分记录
  805. {
  806.         getRecord();//从24C02中获取数据

  807.         wr_com(0x01);
  808.         delayms(5);
  809.         wr_com(0x80);
  810.         delayms(5);
  811.         for(i=0; i<12; i++)         //显示当前得分
  812.         {
  813.                 wr_dat(str7[i]);
  814.                 delayus(5);
  815.         }
  816.         wr_dat(0x30+score/10);
  817.         delayms(5);
  818.         wr_dat(0x30+score%10);
  819.         delayms(5);

  820.         wr_com(0xc0);
  821.         delayus(5);
  822.         for(i=0; i<5; i++)         //第二行显示top1
  823.         {
  824.                 wr_dat(str13[i]);
  825.                 delayus(5);                       
  826.         }

  827.         wr_com(0xc0+0x06);         //top1
  828.         delayus(5);
  829.         wr_dat('4');
  830.         delayus(5);
  831.         wr_dat('0');
  832.         delayus(5);

  833.         wr_com(0xc0+0x09);
  834.         delayus(5);
  835.         wr_dat('A');
  836.         delayus(5);
  837.         wr_dat('Q');
  838.         delayus(5);

  839.         while(1)                        //进入第二页键
  840.         {
  841.                 if(button2==0)
  842.                 {
  843.                    delayms(10);                //去抖动
  844.                    if(button2==0)
  845.                    {
  846.                                    while(!button2);
  847.                                 displayScoreNext();
  848.                                 break;
  849.                    }
  850.                 }
  851.         }
  852. }
  853. void displayScoreNext()        //显示分数第二页
  854. {
  855.         wr_com(0x01);
  856.         delayms(5);
  857.         wr_com(0x80);         
  858.         delayus(5);
  859.         for(i=0; i<5; i++)         //第一行显示top2
  860.         {
  861.                 wr_dat(str16[i]);
  862.                 delayus(5);                       
  863.         }
  864.         wr_com(0x80+0x06);         
  865.         delayus(5);
  866.         wr_dat('3');
  867.         delayus(5);
  868.         wr_dat('9');
  869.         delayus(5);
  870.         wr_com(0x80+0x09);         
  871.         delayus(5);
  872.         wr_dat('A');
  873.         delayus(5);
  874.         wr_dat('W');
  875.         delayus(5);

  876.        
  877.         wr_com(0xc0);         
  878.         delayus(5);
  879.         for(i=0; i<5; i++)         //第二行显示top3
  880.         {
  881.                 wr_dat(str17[i]);
  882.                 delayus(5);                       
  883.         }
  884.         wr_com(0xc0+0x06);         
  885.         delayus(5);
  886.         wr_dat('3');
  887.         delayus(5);
  888.         wr_dat('8');
  889.         delayus(5);
  890.         wr_com(0xc0+0x09);         
  891.         delayus(5);
  892.         wr_dat('A');
  893.         delayus(5);
  894. ……………………

  895. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
打地鼠游戏设计.zip (160.12 KB, 下载次数: 92)
回复

使用道具 举报

ID:855269 发表于 2020-12-6 13:40 | 显示全部楼层
有.hex文件吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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