找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3843|回复: 2
打印 上一主题 下一主题
收起左侧

Lcd12864贪吃蛇(HC6800-ES)一个有趣的单片机代码

[复制链接]
跳转到指定楼层
楼主
这是一个小游戏的代码


单片机源程序如下:
  1. /***********************************************************
  2. 功能说明:贪吃蛇
  3. 编译环境:keil4
  4. MCU     :STC89C52RC
  5. 时钟频率: 22.1184MHz

  6. 注意:该例程中“过关”不能在keil4编译环境中正常显示
  7. ************************************************************/
  8. /*****************************************************************
  9.                     /^\/^\
  10.                   _|__|  O|
  11.          \/     /~     \_/ \
  12.           \____|__________/  \
  13.                  \_______      \
  14.                          `\     \                 \
  15.                            |     |                  \
  16.                           /      /                    \
  17.                          /     /                       \\
  18.                        /      /                         \ \
  19.                       /     /                            \  \
  20.                     /     /             _----_            \   \
  21.                    /     /           _-~      ~-_         |   |
  22.                  (      (        _-~    _--_    ~-_     _/   |
  23.                    \      ~-____-~    _-~    ~-_    ~-_-~    /
  24.                      ~-_           _-~          ~-_       _-~   
  25.                         ~--______-~                ~-___-~  
  26. *****************************************************************/
  27. #include "stc.h"
  28. #include "Lcd12864.h"
  29. #include "Key.h"
  30. #define uchar unsigned char
  31. #define uint unsigned int

  32. static unsigned long Seed = 1;
  33. #define A 48271L
  34. #define M 2147483647L
  35. #define Q (M / A)
  36. #define R (M % A)
  37. /************************************
  38. 伪随机数发生器
  39. *************************************/
  40. double Random(void)
  41. {
  42.         long TmpSeed;
  43.         TmpSeed=A*(Seed%Q)-R*(Seed/Q);
  44.         if(TmpSeed>=0)
  45.                 Seed=TmpSeed;
  46.         else
  47.                 Seed=TmpSeed+M;
  48.         return (double)Seed/M;
  49. }

  50. /**************************************
  51. 为伪随机数发生器播种
  52. ***************************************/
  53. void InitRandom(unsigned long InitVal)
  54. {
  55.         Seed=InitVal;
  56. }

  57. //延时子程序
  58. void delay(unsigned int t)
  59. {  
  60.         unsigned int i,j;
  61.         for(i=0;i<t;i++)
  62.                 for(j=0;j<10;j++);   
  63. }

  64. /*********************************
  65. 初始化MPU
  66. **********************************/
  67. void InitCpu(void)
  68. {
  69.         TMOD=0x01;
  70.         TH0=0;
  71.         TL0=0;
  72.         TR0=1;
  73.         ET0=1;
  74.         EA=1;
  75. }

  76. #define N 25
  77. struct Food
  78. {
  79.         unsigned char x;
  80.         unsigned char y;
  81.         unsigned char yes;
  82. }food;//食物结构体
  83. struct Snake
  84. {
  85.         unsigned char x[N];
  86.         unsigned char y[N];
  87.         unsigned char node;
  88.         unsigned char direction;
  89.         unsigned char life;
  90. }snake;//蛇结构体

  91. unsigned char Flag=0;
  92. unsigned char Score=0;
  93. unsigned char Speed=5;                   //speed越大,速度越慢
  94. unsigned char KeyBuffer=0;
  95. #define FUNC 1                                   //(P3^1)表示级别
  96. #define UP 2                                   //(P3^3)表示左
  97. #define DOWN 3                                   //(P3^5)表示右
  98. #define LEFT 4                                   //(P3^4)表示下
  99. #define RIGHT 5                                   //(P3^2)表示上
  100. #define PASSSCORE 20                   //预定义过关成绩
  101. void Timer0Int(void) interrupt 1
  102. {
  103.         switch(OSReadKey())
  104.         {
  105.                 case 5:
  106.                                 KeyBuffer=FUNC;                                                  //表示级别
  107.                                 /*if(++Speed>=10)
  108.                                         Speed=1;
  109.                                    Flag|=1<<1;//速度变化标志置1*/
  110.                                 break;
  111.                 case 21:
  112.                                 KeyBuffer=DOWN;                                                 //表示右
  113.                                 /*if(snake.direction!=2)
  114.                                         snake.direction=1;*/
  115.                                 break;
  116.                 case 13:
  117.                                 KeyBuffer=UP;                                                 //表示左
  118.                                 /*if(snake.direction!=1)
  119.                                         snake.direction=2;*/
  120.                                 break;
  121.                 case 9:
  122.                                 KeyBuffer=RIGHT;                                         //表示上
  123.                                 /*if(snake.direction!=4)
  124.                                         snake.direction=3;*/
  125.                                 break;
  126.                    case 17:
  127.                                 KeyBuffer=LEFT;                                                 //表示下
  128.                                 /*if(snake.direction!=3)
  129.                                         snake.direction=4;*/
  130.                                 break;
  131.                 default:
  132.                                 break;
  133.         }
  134. }

  135. /******************************
  136. 画墙壁,初始化界面
  137. *******************************/
  138. void DrawBoard(void)
  139. {
  140.         unsigned char n;
  141.         for(n=0;n<31;n++)
  142.         {
  143.                 Lcd_Rectangle(3*n,0,3*n+2,2,1);
  144.                 Lcd_Rectangle(3*n,60,3*n+2,62,1);
  145.         }
  146.         for(n=0;n<21;n++)
  147.         {
  148.                 Lcd_Rectangle(0,3*n,2,3*n+2,1);
  149.                 Lcd_Rectangle(90,3*n,92,3*n+2,1);               
  150.         }
  151.         Lcd_HoriLine(93,31,35,1);
  152.         Lcd_HoriLine(93,63,35,1);
  153. }

  154. /***************************
  155. 打印成绩
  156. ****************************/
  157. void PrintScore(void)
  158. {
  159.         unsigned char Str[3];
  160.         Lcd_WriteStr(6,0,"成绩");
  161.         Str[0]=(Score/10)|0x30;//十位
  162.         Str[1]=(Score%10)|0x30;//个位
  163.         Str[2]=0;
  164.         Lcd_WriteStr(7,1,Str);
  165. }

  166. /********************************
  167. 打印速度级别
  168. *********************************/
  169. void PrintSpeed(void)
  170. {
  171.         unsigned char Str[2];
  172.         Lcd_WriteStr(6,2,"级别");
  173.         Str[0]=Speed|0x30;
  174.         Str[1]=0;
  175.         Lcd_WriteStr(7,3,Str);
  176. }

  177. /***********************************
  178. 游戏结束处理
  179. ************************************/
  180. void GameOver(void)
  181. {
  182.         unsigned char n;
  183.         Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,0);//消隐出食物
  184.         for(n=1;n<snake.node;n++)
  185.         {
  186.                 Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,0);//消隐食物,蛇头已到墙壁内,故不用消去               
  187.         }
  188.         if(snake.life==0)//如果蛇还活着
  189.                 Lcd_WriteStr(2,1,"过关");
  190.         else             //如果蛇死了
  191.                 Lcd_WriteStr(2,1,"输了");
  192.         Lcd_WriteStr(1,2,"游戏结束");
  193. }

  194. /********************************
  195. 游戏的具体过程,也是贪吃蛇算法的关键部分
  196. *********************************/
  197. void GamePlay(void)
  198. {
  199.         unsigned char n;
  200.         InitRandom(TL0);
  201.         food.yes=1;//1表示需要出现新事物,0表示已经存在食物尚未吃掉
  202.         snake.life=0;//表示蛇还活着
  203.         snake.direction=DOWN;
  204.         snake.x[0]=6;snake.y[0]=6;
  205.         snake.x[1]=3;snake.y[1]=6;
  206.         snake.node=2;
  207.         PrintScore();
  208.         PrintSpeed();
  209.         while(1)
  210.         {
  211.                 if(food.yes==1)
  212.                 {
  213.                         while(1)
  214.                         {
  215.                                 food.x=Random()*85+3;
  216.                                 food.y=Random()*55+3;//获得随机数
  217.        
  218.                                 while(food.x%3!=0)
  219.                                         food.x++;
  220.                                 while(food.y%3!=0)
  221.                                         food.y++;
  222.                             for(n=0;n<snake.node;n++)//判断产生的食物坐标是否和蛇身重合
  223.                                 {
  224.                                         if((food.x==snake.x[n])&&(food.y==snake.y[n]))
  225.                                                 break;
  226.                                 }
  227.                                 if(n==snake.node)
  228.                                 {
  229.                                         food.yes=0;
  230.                                         break;//产生有效的食物坐标
  231.                                 }
  232.                         }
  233.                 }
  234.                 if(food.yes==0)
  235.                 {
  236.                         Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,1);
  237.                 }       
  238.                 for(n=snake.node-1;n>0;n--)
  239.                 {
  240.                         snake.x[n]=snake.x[n-1];
  241.                         snake.y[n]=snake.y[n-1];
  242.                 }
  243.                 switch(snake.direction)
  244.                 {
  245.                         case DOWN:snake.x[0]+=3;break;
  246.                         case UP:snake.x[0]-=3;break;
  247.                         case RIGHT:snake.y[0]-=3;break;
  248.                         case LEFT:snake.y[0]+=3;break;
  249.                         default:break;
  250.                 }
  251.                 for(n=3;n<snake.node;n++)//从第三节开始判断蛇头是否咬到自己
  252.                 {
  253.                         if(snake.x[n]==snake.x[0]&&snake.y[n]==snake.y[0])
  254.                         {
  255.                                 GameOver();
  256.                                 snake.life=1;
  257.                                 break;
  258.                         }
  259.                 }
  260.                 if(snake.x[0]<3||snake.x[0]>=90||snake.y[0]<3||snake.y[0]>=60)//判蛇头是否撞到墙壁
  261.                 {
  262.                         GameOver();
  263.                         snake.life=1;
  264.                 }
  265.                 if(snake.life==1)
  266.                         break;//蛇死,则跳出while(1)循环
  267.                 if(snake.x[0]==food.x&&snake.y[0]==food.y)//判蛇是否吃到食物
  268.                 {
  269.                         Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,0);//消隐食物
  270.                         snake.x[snake.node]=200;
  271.                         snake.y[snake.node]=200;//产生蛇新的节坐标先放在看不见的位置
  272.                         snake.node++;//蛇节数加1
  273.                         food.yes=1;//食物标志置1
  274.                         if(++Score>=PASSSCORE)
  275.                         {
  276.                                 PrintScore();
  277.                                 GameOver();
  278.                                 break;
  279.                         }
  280.                         PrintScore();
  281.                 }
  282.                 for(n=0;n<snake.node;n++)
  283.                 {
  284.                         Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,1);
  285.                 }//根据蛇的节数画出蛇
  286.                 delay(Speed*1000);          //调速
  287.                 delay(Speed*1000);
  288.                 Lcd_Rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+2,snake.y[snake.node-1]+2,0);
  289.                 switch(KeyBuffer)
  290.                 {
  291.                         case FUNC:
  292.                                         KeyBuffer=0;
  293.                                         if(++Speed>=10)
  294.                                                 Speed=1;
  295.                                            PrintSpeed();
  296.                                         break;
  297.                         case DOWN:
  298.                                         KeyBuffer=0;
  299.                                         if(snake.direction!=UP)
  300.                                                 snake.direction=DOWN;
  301.                                         break;
  302.                         case UP:
  303.                                         KeyBuffer=0;
  304.                                         if(snake.direction!=DOWN)
  305.                                                 snake.direction=UP;
  306.                                         break;
  307.                         case RIGHT:
  308.                                         KeyBuffer=0;
  309.                                         if(snake.direction!=LEFT)
  310.                                                 snake.direction=RIGHT;
  311.                                         break;
  312.                            case LEFT:
  313.                                         KeyBuffer=0;
  314.                                         if(snake.direction!=RIGHT)
  315.                                                 snake.direction=LEFT;
  316.                                         break;
  317.                         default:
  318.                                         break;
  319.                 }                       
  320.         }//结束while(1)
  321. }

  322. void Main()
  323. {  
  324.         InitCpu();//初始化CPU
  325.         Lcd_Reset(); //初始化LCD屏
  326.         Lcd_WriteStr(2,1,"航峰兴业");
  327.         delay(5000);
  328.         delay(5000);
  329.         Lcd_WriteCmd(0x01);   //清除显示,并且设定地址指针为00H
  330.         Lcd_Clear(0);//清屏
  331.         DrawBoard();//画界面
  332.         GamePlay();//玩游戏
  333.         GameOver();//游戏结束
  334.         while(1);//要想重玩,只能重启,可继续完善该游戏
  335. }

复制代码

所有资料51hei提供下载:
贪吃蛇(HC6800-ES V2.0).rar (124.1 KB, 下载次数: 102)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:531235 发表于 2019-5-14 23:54 | 只看该作者
这个12864 是带字库的吗
回复

使用道具 举报

板凳
ID:757080 发表于 2020-5-23 21:59 | 只看该作者
sdwfywl 发表于 2019-5-14 23:54
这个12864 是带字库的吗

我看了下是不带
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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