贪吃蛇游戏程序分模块检测好用,合在一起单片机执行得时候功能不能实现,一直按复位键部分功能可能好用,很多功能执行不了,谢谢
- #include"reg52.h"
- #include "intrins.h"
- sbit RS=P2^6; //并行的指令/数据选择信号, H数据, L命令
- sbit RW=P2^5; //并行读写选择信号, H读, L写
- sbit E=P2^7; //并行使能端, H有效, L无效
- sbit PSB=P3^2; //并/串接口选择, H并,L串
- sbit RET=P3^4; //复位, L有效
- sbit kxuanze=P3^1;
- sbit kenter=P3^3;
- #define LcdData P0
- #define N 25
- unsigned char moshiceshi;
- unsigned char flag,s1num;
- #define OS_LONG_EYK_EN 1 //如果应用中需要处理长按键动作,则定义为1,否则定义为0(如果应用中不需要处理长按动作,则建议定义为0,以节省代码空间)
- #define GPIO_KEY P1
- unsigned char KeyValue;//用来存放读取到的键值
- unsigned char code DIG_CODE[17]={
- 0,0,0,0,0,5,0,0,6,0,4,0,0,3,0,0,0};
- #define uchar unsigned char
- #define uint unsigned int
- static unsigned long Seed = 1;
- #define A 48271L
- #define M 2147483647L
- #define Q (M / A)
- #define R (M % A)
- struct Food
- {
- unsigned char x;
- unsigned char y;
- unsigned char yes;
- }food;//食物结构体
- struct Snake
- {
- unsigned char x[N];
- unsigned char y[N];
- unsigned char node;
- unsigned char direction;
- unsigned char life;
- }snake;//蛇结构体
- unsigned char Flag_gamedisplay=0;
- unsigned char Score=0;
- unsigned char Speed_tiaosu; //speed越大,速度越慢
- unsigned char KeyBuffer=0;
- #define FUNC 1 //(P3^1)表示级别
- #define UP 2 //(P3^3)表示左
- #define DOWN 3 //(P3^5)表示右
- #define LEFT 4 //(P3^4)表示下
- #define RIGHT 5 //(P3^2)表示上
- #define PASSSCORE 20 //预定义过关成绩
- void Lcd_WriteData(unsigned char);
- unsigned char Check_Busy(void);
- unsigned char Lcd_ReadData(void);
- void Lcd_WriteCmd(unsigned char);
- void Lcd_PutPixel(unsigned char,unsigned char,unsigned char);
- //unsigned char Lcd_ReadPixel(unsigned char,unsigned char);
- void Lcd_HoriLine(unsigned char,unsigned char,unsigned char Length,unsigned char Color);
- void Lcd_VertLine(unsigned char x,unsigned char y,unsigned char Length,unsigned char Color);
- void Lcd_Line(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char Color);
- void Lcd_Rectangle(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char Color);
- void Lcd_Circle(unsigned char x,unsigned char y,unsigned char r,unsigned char Color);
- void Lcd_Clear(unsigned char);
- void Lcd_WriteStr(unsigned char,unsigned char,unsigned char *);
- void Lcd_Reset(void);
- unsigned char OSReadKey(void);
- unsigned char KeyDown(); //检测按键函数
- void Delay10ms(void); //延时10ms
- double Random(void);
- void InitRandom(unsigned long InitVal);
- void InitCpu(void);
- void DrawBoardf();
- void Drawboardt(void);
- void PrintScore(void);
- void PrintSpeed(void);
- void GameOver(void);
- void Gameplayt(void);
- void GamePlayf(void);
- void delay(unsigned int t);
- void delayus(unsigned int j);
- void lcd_st(unsigned char *st);
- void scankey(void);
- void moshi(void);
- void zhujiemian(void);
- unsigned char moshi1(void);
- unsigned char moshi2(void);
- void speed(void);
- void Speed1(void);
- void Speed2(void);
- void Speed3(void);
- void Speed4(void);
- void game(void);
- void main()
- {
- Lcd_Reset();
- Lcd_WriteStr(0,0,"Welcome");
- Lcd_WriteStr(2,2,"贪吃蛇");
- delay(20000000);
- zhujiemian();
- while(1)
- {
- scankey();
- }
- }
- /*************
- 测试LCD是否处于忙状态
- 如果忙则返回0x80,否则返回0
- **************/
- unsigned char Lcd_CheckBusy(void)
- {
- unsigned char Busy;
- LcdData=0xff;
- RS=0;
- RW=1;
- E=1;
- _nop_();
- Busy=LcdData&0x80;
- E=0;
- return Busy;
- }
- /*********************************
- 向LCD写入字节数据
- **********************************/
- void Lcd_WriteData(unsigned char LCD_Data)
- {
- while(Lcd_CheckBusy());
- RS=1;
- RW=0;
- E=0;
- _nop_();
- _nop_();
- LcdData=LCD_Data;
- E=1;
- _nop_();
- _nop_();
- E=0;
- }
- /***********************************
- 从LCD中读出数据
- ************************************/
- unsigned char Lcd_ReadData(void)
- {
- unsigned char Temp;
- //while(Lcd_CheckBusy());
- LcdData=0xff;
- RS=1;
- RW=1;
- E=1;
- _nop_();
- Temp=LcdData;
- E=0;
- return Temp;
- }
- /*************************************
- 向LCD中写入指令代码
- **************************************/
- void Lcd_WriteCmd(unsigned char CmdCode)
- {
- while(Lcd_CheckBusy());
- RS=0;
- RW=0;
- E=0;
- _nop_();
- _nop_();
- LcdData=CmdCode;
- _nop_();
- _nop_();
- E=1;
- _nop_();
- _nop_();
- E=0;
- }
- void set_postion(unsigned char x,unsigned char y)
- {
- unsigned char postion;
- switch(x)
- {
- case 0:x=0x80;break;
- case 1:x=0x90;break;
- case 2:x=0x88;break;
- case 3:x=0x98;break;
- default:break;
- }
- postion=x+y;
- Lcd_WriteCmd(postion);
- }
- /*************************************
- 向LCD指定起始位置写入一个字符串
- *************************************/
- void Lcd_WriteStr(unsigned char x,unsigned char y,unsigned char *Str)
- {
- if((y>3)||(x>7))
- return;//如果指定位置不在显示区域内,则不做任何写入直接返回
- EA=0;
- switch(y)
- {
- case 0:
- Lcd_WriteCmd(0x80+x);
- break;
- case 1:
- Lcd_WriteCmd(0x90+x);
- break;
- case 2:
- Lcd_WriteCmd(0x88+x);
- break;
- case 3:
- Lcd_WriteCmd(0x98+x);
- break;
- }
- while(*Str>0)
- {
- Lcd_WriteData(*Str);
- Str++;
- }
- EA=1;
- }
- /**************************************
- 为加速逻辑运算而设置的掩码表,这是以牺牲空间而换取时间的办法
- ***************************************/
- code unsigned int MaskTab[]={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
- 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
- /***************************************
- 向LCD指定坐标写入一个象素,象素颜色有两种,0代表白(无显示),1代表黑(有显示)
- ****************************************/
- void Lcd_PutPixel(unsigned char x,unsigned char y,unsigned char Color)
- {
- unsigned char z,w;
- unsigned int Temp;
- if(x>=128||y>=64)
- return;
- Color=Color%2;
- w=15-x%16;//确定对这个字的第多少位进行操作
- x=x/16;//确定为一行上的第几字
- if(y<32) //如果为上页
- z=0x80;
- else //否则如果为下页
- z=0x88;
- y=y%32;
- EA=0;
- Lcd_WriteCmd(0x36);
- Lcd_WriteCmd(y+0x80); //行地址
- Lcd_WriteCmd(x+z); //列地址
- Temp=Lcd_ReadData();//先空读一次
- Temp=(unsigned int)Lcd_ReadData()<<8;//再读出高8位
- Temp|=(unsigned int)Lcd_ReadData();//再读出低8位
- EA=1;
- if(Color==1) //如果写入颜色为1
- Temp|=MaskTab[w];//在此处查表实现加速
- else //如果写入颜色为0
- Temp&=~MaskTab[w];//在此处查表实现加速
- EA=0;
- Lcd_WriteCmd(y+0x80); //行地址
- Lcd_WriteCmd(x+z); //列地址
- Lcd_WriteData(Temp>>8);//先写入高8位,再写入低8位
- Lcd_WriteData(Temp&0x00ff);
- Lcd_WriteCmd(0x30);
- EA=1;
- }
- /***************************************
- 向LCD指定位置画一条长度为Length的指定颜色的水平线
- ****************************************/
- void Lcd_HoriLine(unsigned char x,unsigned char y,unsigned char Length,unsigned char Color)
- {
- unsigned char i;
- if(Length==0)
- return;
- for(i=0;i<Length;i++)
- {
- Lcd_PutPixel(x+i,y,Color);
- }
- }
- /***************************************
- 向LCD指定位置画一条长度为Length的指定颜色的垂直线
- ****************************************/
- void Lcd_VertLine(unsigned char x,unsigned char y,unsigned char Length,unsigned char Color)
- {
- unsigned char i;
- if(Length==0)
- return;
- for(i=0;i<Length;i++)
- {
- Lcd_PutPixel(x,y+i,Color);
- }
- }
- /*******************************************
- 向LCD指定起始坐标和结束坐标之间画一条指定颜色的直线
- void Lcd_Line(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char Color)
- {
- unsigned int x,y;
- unsigned int d_x,d_y;//d_x=x2-x1;d_y=y2-y1;
- int err=0;
- unsigned char temp=0;
- if(y2<y1)
- {
- x=x1;
- y=y1;
- x1=x2;
- y1=y2;
- x2=x;
- y2=y;
- }
- d_y=y2-y1;
- if (d_y==0)
- {
- if (x1>x2)
- {
- x=x1;
- x1=x2;
- x2=x;
- }
- for (x=x1;x<=x2;x++)
- Lcd_PutPixel(x,y1,Color);
- }
- else
- {
- if(x2>=x1)
- {
- temp=1;
- d_x=x2-x1;
- }
- else
- d_x=x1-x2;
- x=x1;
- y=y1;
- Lcd_PutPixel(x,y,1);
- if(temp&&(d_y<=d_x))
- while(x!=x2)
- {
- if(err<0)
- {
- x=x+1;
- err=err+(y2-y);
- }
- else
- {
- x=x+1;
- y=y+1;
- err=err+(y2-y)-(x2-x);
- }
- Lcd_PutPixel(x,y,Color);
- }
- else if(temp&&(d_y>d_x))
- while(y!=y2)
- {
- d_x=x2-x;
- d_y=y2-y;
- if(err<0)
- {
- x=x+1;
- y=y+1;
- err=err+d_y-d_x;
- }
- else
- {
- y=y+1;
- err=err-d_x;
- }
- Lcd_PutPixel(x,y,Color);
- }
- else if(!temp&&(d_y<=d_x))
- while(x!=x2)
- {
- d_x=x-x2;
- d_y=y2-y;
- if(err<0)
- {
- x=x-1;
- err=err+d_y;
- }
- else
- {
- x=x-1;
- y=y+1;
- err=err+d_y-d_x;
- }
- Lcd_PutPixel(x,y,Color);
- }
- else if(!temp &&(d_y>d_x))
- while(y!=y2)
- {
- d_x=x-x2;
- d_y=y2-y;
- if(err<0)
- {
- x=x-1;
- y=y+1;
- err=err+d_y-d_x;
- }
- else
- {
- y=y+1;
- err=err-d_x;
- }
- Lcd_PutPixel(x,y,Color);
- }
- }
- }
- ********************************************/
- /*******************************************
- 向LCD指定左上角坐标和右下角坐标画一个指定颜色的矩形
- ********************************************/
- void Lcd_Rectangle(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char Color)
- {
- unsigned char Temp;
- if(x0>x1)
- {
- Temp=x0;
- x0=x1;
- x1=Temp;
- }
- if(y0>y1)
- {
- Temp=y0;
- y0=y1;
- y1=Temp;
- }
- Lcd_VertLine(x0,y0,y1-y0+1,Color);
- Lcd_VertLine(x1,y0,y1-y0+1,Color);
- Lcd_HoriLine(x0,y0,x1-x0+1,Color);
- Lcd_HoriLine(x0,y1,x1-x0+1,Color);
- }
- /****************************************
- 对称法画圆的8个镜像点
- void CircleDot(unsigned char x,unsigned char y,char xx,char yy,unsigned char Color)//内部函数,对称法画圆的8个镜像点
- {
- Lcd_PutPixel((x+yy),(y+xx),Color);//第 1 个 8 分圆
- Lcd_PutPixel((x+xx),(y+yy),Color);//第 2 个 8 分圆
- Lcd_PutPixel((x-xx),(y+yy),Color);//第 3 个 8 分圆
- Lcd_PutPixel((x-yy),(y+xx),Color);//第 4 个 8 分圆
- Lcd_PutPixel((x-yy),(y-xx),Color);//第 5 个 8 分圆
- Lcd_PutPixel((x-xx),(y-yy),Color);//第 6 个 8 分圆
- Lcd_PutPixel((x+xx),(y-yy),Color);//第 7 个 8 分圆
- Lcd_PutPixel((x+yy),(y-xx),Color);//第 8 个 8 分圆
- }
- *****************************************/
- /******************************************
- 向LCD指定圆心坐标画一个半径为r的指定颜色的圆
- void Lcd_Circle(unsigned char x,unsigned char y,unsigned char r,unsigned char Color)//中点法画圆
- {//中点法画圆
- unsigned char xx,yy;
- char deltax,deltay,d;
- xx=0;
- yy=r;
- deltax=3;
- deltay=2-r-r;
- d=1-r;
- CircleDot(x,y,xx,yy,Color);//对称法画圆的8个镜像点
- while (xx<yy)
- {
- if (d<0)
- {
- d+=deltax;
- deltax+=2;
- xx++;
- }
- else
- {
- d+=deltax+deltay;
- deltax+=2;
- deltay+=2;
- xx++;
- yy--;
- }
- CircleDot(x,y,xx,yy,Color);//对称法画圆的8个镜像点
- }
- }
- *******************************************/
- /*****************************************
- 清除Lcd全屏,如果清除模式Mode为0,则为全屏清除为颜色0(无任何显示)
- 否则为全屏清除为颜色1(全屏填充显示)
- ******************************************/
- void Lcd_Clear(unsigned char Mode)
- {
- unsigned char x,y,ii;
- unsigned char Temp;
- if(Mode%2==0)
- Temp=0x00;
- else
- Temp=0xff;
- Lcd_WriteCmd(0x36);//扩充指令 绘图显示
- for(ii=0;ii<9;ii+=8)
- for(y=0;y<0x20;y++)
- for(x=0;x<8;x++)
- {
- EA=0;
- Lcd_WriteCmd(y+0x80); //行地址
- Lcd_WriteCmd(x+0x80+ii); //列地址
- Lcd_WriteData(Temp); //写数据 D15-D8
- Lcd_WriteData(Temp); //写数据 D7-D0
- EA=1;
- }
- Lcd_WriteCmd(0x30);
- }
- /****************************************
- LCD初始化
- *****************************************/
- void Lcd_Reset(void)
- {
- PSB=1;
- Lcd_WriteCmd(0x30); //选择基本指令集
- delay(5);
- Lcd_WriteCmd(0x0c); //开显示(无游标、不反白)
- delay(5);
- Lcd_WriteCmd(0x01); //清除显示,并且设定地址指针为00H
- delay(5);
- Lcd_WriteCmd(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位
- }
- void Delay10ms(void) //误差 0us
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- void delay(unsigned int t)
- {
- unsigned int i,j;
- for(i=0;i<t;i++)
- for(j=0;j<10;j++);
- }
- /***********************************************
- 按键驱动扫描
- 扫描一次键盘以获得按键句柄
- 注:交OSReadKey()函数调用
- ***********************************************/
- unsigned char KeyDown(void)
- {
- char a=0;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f)//读取按键是否按下
- {
- Delay10ms();//延时10ms进行消抖
- if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
- {
-
- //测试列
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=3;break;
- }
- //测试行
- GPIO_KEY=0XF0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue;break;
- case(0Xb0): KeyValue=KeyValue+4;break;
- case(0Xd0): KeyValue=KeyValue+8;break;
- case(0Xe0): KeyValue=KeyValue+12;break;
- }
- while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
- {
- Delay10ms();
- a++;
- }
- }
- }
-
- return KeyValue;
- }
- /**********************************************
- 功能说明:读取按键动作
- 入口参数:无
- 出口参数:返回按键动作
- 注意:
- 没有按键动作,则返回0,
- 使用矩阵按键:向上S12;向下S6;向左S12;向右S9;
- ***********************************************/
- unsigned char OSReadKey(void)
- {
- static unsigned char KeyEventCnt=0;
- static unsigned char KeySampleCnt=0;
- static unsigned char KeyBuffer=0;
- #define SHORT_ON_DITHERING_COUNTER 3//定义短按按下去抖时间
- #define SHORT_OFF_DITHERING_COUNTER 3//定义短按松开去抖时间,一般与短按按下去抖时间相同
- #if OS_LONG_EYK_EN>0
- static unsigned int LongKeySampleCnt=0;
- #define LONG_ON_DITHERING_COUNTER 250//定义长按按下确认需要的时间,如果是每1MS调用一次OSReadKey(),则1000意味着这个时间为1S
- #define LONG_OFF_DITHERING_COUNTER 3//定义长按松开去抖时间,一般和短按去抖时间相同
- #endif
- unsigned char KeyTemp;
- KeyTemp=DIG_CODE[KeyDown()];
- switch(KeyEventCnt)
- {
- case 0:
- if(KeyTemp!=0)
- {
- KeySampleCnt=0;
- KeyBuffer=KeyTemp;
- KeyEventCnt=1;
- }
- return 0;//no key on,return 0
- break;
-
- #if OS_LONG_EYK_EN>0
- case 1:
- if(KeyTemp!=KeyBuffer)
- {
- KeyEventCnt=0;
- return 0;//is dithering,return 0
- }
- else
- {
- if(++KeySampleCnt>SHORT_ON_DITHERING_COUNTER)
- {
- KeySampleCnt=0;
- KeyEventCnt=2;
- LongKeySampleCnt=0;
- return ((KeyBuffer-1)<<2)+1;//sure that key on,return (KeyBuffer-1)<<2+1
- }
- else
- return 0;//not sure that key on,return 0
- }
- break;
-
- case 2:
- if(++LongKeySampleCnt>LONG_ON_DITHERING_COUNTER)
- {
- KeySampleCnt=0;
- KeyEventCnt=3;
- return ((KeyBuffer-1)<<2)+2; //sure that key long on,return (KeyBuffer-1)<<2+2
- }
- else
- {
- if(KeyTemp!=KeyBuffer)
- {
- if(++KeySampleCnt>SHORT_OFF_DITHERING_COUNTER)
- {
- KeyEventCnt=0;
- return ((KeyBuffer-1)<<2)+3;//after short on to off,(KeyBuffer-1)<<2+3
- }
- else
- return 0;
- }
- else
- {
- KeySampleCnt=0;
- return 0;
- }
- }
- break;
-
- case 3:
- if(KeyTemp!=KeyBuffer)
- {
- if(++KeySampleCnt>LONG_OFF_DITHERING_COUNTER)
- {
- KeyEventCnt=0;
- return ((KeyBuffer-1)<<2)+4; //after long key on turn to off,(KeyBuffer-1)<<2+4
- }
- else
- return 0;
- }
- else
- {
- KeySampleCnt=0;
- return 0;
- }
- break;
-
- #else
- case 1:
- if(KeyTemp!=KeyBuffer)
- {
- KeyEventCnt=0;
- return 0;//is dithering,return 0
- }
- else
- {
- if(++KeySampleCnt>=SHORT_ON_DITHERING_COUNTER)
- {
- KeySampleCnt=0;
- KeyEventCnt=2;
- return ((KeyBuffer-1)<<2)+1;//sure that key on,return (KeyBuffer-1)<<2+1
- }
- else
- return 0;//not sure that key on,return 0
- }
- break;
-
- case 2:
- if(KeyTemp!=KeyBuffer)
- {
- if(++KeySampleCnt>=SHORT_OFF_DITHERING_COUNTER)
- {
- KeyEventCnt=0;
- return ((KeyBuffer-1)<<2)+3;//after short on to off,(KeyBuffer-1)<<2+3
- }
- else
- return 0;
- }
- else
- {
- KeySampleCnt=0;
- return 0;
- }
- break;
- #endif
- default:break;
- }
- return 0;
- }
- /************************************
- 伪随机数发生器
- *************************************/
- double Random(void)
- {
- long TmpSeed;
- TmpSeed=A*(Seed%Q)-R*(Seed/Q);
- if(TmpSeed>=0)
- Seed=TmpSeed;
- else
- Seed=TmpSeed+M;
- return (double)Seed/M;
- }
- /**************************************
- 为伪随机数发生器播种
- ***************************************/
- void InitRandom(unsigned long InitVal)
- {
- Seed=InitVal;
- }
- /*********************************
- 初始化MPU
- **********************************/
- void InitCpu(void)
- {
- TMOD=0x01;
- TH0=0;
- TL0=0;
- TR0=1;
- ET0=1;
- EA=1;
- }
- void Timer0Int(void) interrupt 1
- {
- switch(OSReadKey())
- {
- case 5:
- KeyBuffer=FUNC; //表示级别
- break;
- case 21:
- KeyBuffer=DOWN; //表示右
- break;
- case 13:
- KeyBuffer=UP; //表示左
- break;
- case 9:
- KeyBuffer=RIGHT; //表示上
- break;
- case 17:
- KeyBuffer=LEFT; //表示下
- break;
- default:
- break;
- }
- }
- /******************************
- 画墙壁,初始化界面
- *******************************/
- void DrawBoardf()
- {
- unsigned char n;
- for(n=0;n<31;n++)
- {
- Lcd_Rectangle(3*n,0,3*n+2,2,1);
- Lcd_Rectangle(3*n,60,3*n+2,62,1);
- }
- for(n=0;n<21;n++)
- {
- Lcd_Rectangle(0,3*n,2,3*n+2,1);
- Lcd_Rectangle(90,3*n,92,3*n+2,1);
- }
- Lcd_HoriLine(93,31,35,1);
- Lcd_HoriLine(93,63,35,1);
- }
- void Drawboardt(void)
- {
- unsigned char n;
- for(n=0;n<21;n++)
- {
- Lcd_Rectangle(0,3*n,2,3*n+2,1);
- Lcd_Rectangle(90,3*n,92,3*n+2,1);
- }
- Lcd_HoriLine(93,31,35,1);
- Lcd_HoriLine(93,63,35,1);
- }
- /***************************
- 打印成绩
- ****************************/
- void PrintScore(void)
- {
- unsigned char Str[3];
- Lcd_WriteStr(6,0,"成绩");
- Str[0]=(Score/10)|0x30;//十位
- Str[1]=(Score%10)|0x30;//个位
- Str[2]=0;
- Lcd_WriteStr(7,1,Str);
- }
- /********************************
- 打印速度级别
- *********************************/
- void PrintSpeed(void)
- {
- unsigned char Str[2];
- Lcd_WriteStr(6,2,"级别");
- Str[0]=Speed_tiaosu|0x30;
- Str[1]=0;
- Lcd_WriteStr(7,3,Str);
- }
- /***********************************
- 游戏结束处理
- ************************************/
- void GameOver(void)
- {
- unsigned char n;
- Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,0);//消隐出食物
- for(n=1;n<snake.node;n++)
- {
- Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,0);//消隐食物,蛇头已到墙壁内,故不用消去
- }
- if(snake.life==0)//如果蛇还活着
- Lcd_WriteStr(2,1,"过关");
- else //如果蛇死了
- Lcd_WriteStr(2,1,"输了");
- Lcd_WriteStr(1,2,"游戏结束");
- }
- /********************************
- 游戏的具体过程,也是贪吃蛇算法的关键部分
- *********************************/
- void GamePlayf(void)
- {
- unsigned char n;
- InitRandom(TL0);
- food.yes=1;//1表示需要出现新事物,0表示已经存在食物尚未吃掉
- snake.life=0;//表示蛇还活着
- snake.direction=DOWN;
- snake.x[0]=6;snake.y[0]=6;
- snake.x[1]=3;snake.y[1]=6;
- snake.node=2;
- PrintScore();
- PrintSpeed();
- while(1)
- {
- if(food.yes==1)
- {
- while(1)
- {
- food.x=Random()*85+3;
- food.y=Random()*55+3;//获得随机数
- while(food.x%3!=0)
- food.x++;
- while(food.y%3!=0)
- food.y++;
- for(n=0;n<snake.node;n++)//判断产生的食物坐标是否和蛇身重合
- {
- if((food.x==snake.x[n])&&(food.y==snake.y[n]))
- break;
- }
- if(n==snake.node)
- {
- food.yes=0;
- break;//产生有效的食物坐标
- }
- }
- }
- if(food.yes==0)
- {
- Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,1);
- }
- for(n=snake.node-1;n>0;n--)
- {
- snake.x[n]=snake.x[n-1];
- snake.y[n]=snake.y[n-1];
- }
- switch(snake.direction)
- {
- case DOWN:snake.x[0]+=3;break;
- case UP:snake.x[0]-=3;break;
- case RIGHT:snake.y[0]-=3;break;
- case LEFT:snake.y[0]+=3;break;
- default:break;
- }
- for(n=3;n<snake.node;n++)//从第三节开始判断蛇头是否咬到自己
- {
- if(snake.x[n]==snake.x[0]&&snake.y[n]==snake.y[0])
- {
- GameOver();
- snake.life=1;
- break;
- }
- }
- if(snake.x[0]<3||snake.x[0]>=90||snake.y[0]<3||snake.y[0]>=60)//判蛇头是否撞到墙壁
- {
- GameOver();
- snake.life=1;
- }
- if(snake.life==1)
- break;//蛇死,则跳出while(1)循环
- if(snake.x[0]==food.x&&snake.y[0]==food.y)//判蛇是否吃到食物
- {
- Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,0);//消隐食物
- snake.x[snake.node]=200;
- snake.y[snake.node]=200;//产生蛇新的节坐标先放在看不见的位置
- snake.node++;//蛇节数加1
- food.yes=1;//食物标志置1
- if(++Score>=PASSSCORE)
- {
- PrintScore();
- GameOver();
- break;
- }
- PrintScore();
- }
- for(n=0;n<snake.node;n++)
- {
- Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,1);
- }//根据蛇的节数画出蛇
- delay(Speed_tiaosu*1000); //调速
- delay(Speed_tiaosu*1000);
- 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);
- switch(KeyBuffer)
- {
- case FUNC:
- KeyBuffer=0;
- if(++Speed_tiaosu>=10)
- Speed_tiaosu=1;
- PrintSpeed();
- break;
- case DOWN:
- KeyBuffer=0;
- if(snake.direction!=UP)
- snake.direction=DOWN;
- break;
- case UP:
- KeyBuffer=0;
- if(snake.direction!=DOWN)
- snake.direction=UP;
- break;
- case RIGHT:
- KeyBuffer=0;
- if(snake.direction!=LEFT)
- snake.direction=RIGHT;
- break;
- case LEFT:
- KeyBuffer=0;
- if(snake.direction!=RIGHT)
- snake.direction=LEFT;
- break;
- default:
- break;
- }
- }
- }
- void Gameplayt(void)
- {
- unsigned char n;
- InitRandom(TL0);
- food.yes=1;//1表示需要出现新事物,0表示已经存在食物尚未吃掉
- snake.life=0;//表示蛇还活着
- snake.direction=DOWN;
- snake.x[0]=6;snake.y[0]=6;
- snake.x[1]=3;snake.y[1]=6;
- snake.node=2;
- PrintScore();
- PrintSpeed();
- while(1)
- {
- if(food.yes==1)
- {
- while(1)
- {
- food.x=Random()*85+3;
- food.y=Random()*55+3;//获得随机数
- while(food.x%3!=0)
- food.x++;
- while(food.y%3!=0)
- food.y++;
- for(n=0;n<snake.node;n++)//判断产生的食物坐标是否和蛇身重合
- {
- if((food.x==snake.x[n])&&(food.y==snake.y[n]))
- break;
- }
- if(n==snake.node)
- {
- food.yes=0;
- break;//产生有效的食物坐标
- }
- }
- }
- if(food.yes==0)
- {
- Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,1);
- }
- for(n=snake.node-1;n>0;n--)
- {
- snake.x[n]=snake.x[n-1];
- snake.y[n]=snake.y[n-1];
- }
- switch(snake.direction)
- {
- case DOWN:snake.x[0]+=3;break;
- case UP:snake.x[0]-=3;break;
- case RIGHT:snake.y[0]-=3;break;
- case LEFT:snake.y[0]+=3;break;
- default:break;
- }
- for(n=3;n<snake.node;n++)//从第三节开始判断蛇头是否咬到自己
- {
- if(snake.x[n]==snake.x[0]&&snake.y[n]==snake.y[0])
- {
- GameOver();
- snake.life=1;
- break;
- }
- }
- if(snake.x[0]<3||snake.x[0]>=90)//判蛇头是否撞到墙壁
- {
- GameOver();
- snake.life=1;
- }
- if(snake.life==1)
- break;//蛇死,则跳出while(1)循环
- if(snake.y[0]<3||snake.y[0]>=60)
- { if(snake.y[0]<3)
- snake.y[0]=59;
- // for(n=0;n<snake.node;n++)
- // {
- // Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,1);
- // }//根据蛇的节数画出蛇
- if(snake.y[0]>=60)
- snake.y[0]=3;
- // for(n=0;n<snake.node;n++)
- // {
- // Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,1);
- // }//根据蛇的节数画出蛇
- //
-
- }
- if(snake.x[0]==food.x&&snake.y[0]==food.y)//判蛇是否吃到食物
- {
- Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,0);//消隐食物
- snake.x[snake.node]=200;
- snake.y[snake.node]=200;//产生蛇新的节坐标先放在看不见的位置
- snake.node++;//蛇节数加1
- food.yes=1;//食物标志置1
- if(++Score>=PASSSCORE)
- {
- PrintScore();
- GameOver();
- break;
- }
- PrintScore();
- }
- for(n=0;n<snake.node;n++)
- {
- Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,1);
- }//根据蛇的节数画出蛇
- delay(Speed_tiaosu*1000); //调速
- delay(Speed_tiaosu*1000);
- 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);
- switch(KeyBuffer)
- {
- case FUNC:
- KeyBuffer=0;
- if(++Speed_tiaosu>=10)
- Speed_tiaosu=1;
- PrintSpeed();
- break;
- case DOWN:
- KeyBuffer=0;
- if(snake.direction!=UP)
- snake.direction=DOWN;
- break;
- case UP:
- KeyBuffer=0;
- if(snake.direction!=DOWN)
- snake.direction=UP;
- break;
- case RIGHT:
- KeyBuffer=0;
- if(snake.direction!=LEFT)
- snake.direction=RIGHT;
- break;
- case LEFT:
- KeyBuffer=0;
- if(snake.direction!=RIGHT)
- snake.direction=LEFT;
- break;
- default:
- break;
- }
- }
- }
- void scankey(void)
- {
- }
- void speed(void)
- {
- Lcd_WriteStr(0,1,"Speed1");
-
- Lcd_WriteStr(1,1,"Speed2");
-
- Lcd_WriteStr(2,1,"Speed3");
-
- Lcd_WriteStr(3,1,"Speed4");
- }
- void moshi(void)
- {
- Lcd_WriteStr(0,1,"mosho1");
- Lcd_WriteStr(1,1,"moshi2");
- }
- void zhujiemian(void)
- {
- Lcd_WriteCmd(0x01);
- Lcd_WriteStr(0,0,"开始游戏");
- Lcd_WriteStr(0,1,"速度选择");
- Lcd_WriteStr(0,2,"模式设置");
- }
- unsigned char moshi1()
- {
- moshiceshi=1;
- DrawBoardf();
- GamePlayf();
- return moshiceshi;
- zhujiemian();
- }
- unsigned char moshi2()
- {
- moshiceshi=2;
- Drawboardt();
- Gameplayt();
- return moshiceshi;
- zhujiemian();
- }
- void Speed1(void)
- {
- unsigned char Speed_tiaosu=1;
- zhujiemian();
- }
- void Speed2(void)
- {
- unsigned char Speed_tiaosu=2;
- zhujiemian();
-
- }
- void Speed3(void)
- {
- unsigned char Speed_tiaosu=3;
- zhujiemian();
-
- }
- void Speed4(void)
- {
- unsigned char Speed_tiaosu=4;
- zhujiemian();
- }
- void game(void)
- {
- InitCpu();//初始化CPU
- Lcd_Reset(); //初始化LCD屏
- delay(5000);
- Lcd_Clear(0);//清屏
- switch(Speed_tiaosu)
- {
- case '1':
- Speed1();
- break;
- case '2':
- Speed2();
- break;
- case '3':
- Speed3();
- break;
- case '4':
- Speed4();
- break;
- default:
- Speed4();
- }
- switch(moshiceshi)
- {
- case '1':
- moshi1();
- break;
- case '2':
- moshi2();
- break;
- default:
- moshi1();
- }
- GameOver();//游戏结束
- }
复制代码
|