|
發布時間: 2018-8-13 19:57
正文摘要:本帖最后由 lynn710 于 2018-8-13 20:01 編輯 急用,多謝指正 #include"reg52.h" #include "intrins.h" sbit RS=P2^6; //并行的指令/數據選擇信號, H數據, L命令 sbit RW=P2^5; //并行讀寫選擇 ... |
|
這是修改后的代碼,為什么程序會卡住呢??? |
|
#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();//游戲結束 } |
angmall 發表于 2018-8-14 18:15 大神,沒有錯了,但是單片機運行好像卡住了,我一直按復位鍵前面的部分功能才可能好用,后面的一直用不了,但我各功能分開檢測得時候是都好用得 |
|
這個試試 #define OS_LONG_KEY_EN 1 |
angmall 發表于 2018-8-13 23:34 我加了還是那個錯 |
|
少了這個 #define OS_LONG_EYK_EN 1 //如果應用中需要處理長按鍵動作,則定義為1,否則定義為0(如果應用中不需要處理長按動作,則建議定義為0,以節省代碼空間) #define GPIO_KEY P1 |