打地鼠程序說明文檔:
項目是一款打地鼠的游戲,程序用到了延時函數、LED、電阻屏、按鍵燈功能,這些功能的初始化例程里面都有,我們可以直接調用來完成初始化。
完成了初始化就開始程序的主干了,既然我們用到了電阻屏,肯定就需要對它進行校準,校準函數在觸摸屏例程也有,我們可以通過KEY0按鍵直接調用校準函數,用來防止觸摸屏不準。
然后我們先進行的是界面顯示,先通過圖片取模軟件取出一個背景圖,注意取模的時候由于例程顯示那里標注了,在液晶上畫圖(僅支持:從左到右,從上到下 or 從上到下,從左到右 的掃描方式!),圖片數據(必須包含圖片信息頭, 4096色/16位真彩色/18位真彩色/24位真彩色/32位真彩色的圖像數據頭),針對STM32,不能選擇image2lcd的"高位在前(MSB First)"選項,否則imginfo的數據將不正確!我們按照標注選擇了16位真彩色的取模方式,通過PS將圖片改為屏幕合適尺寸,就可以在屏幕上顯示出背景了。將前20行用來顯示分數,等級,生命屬性,他們通過字符串和數字變量的顯示函數來實現, 后面300行做成3*3的地鼠洞,地鼠洞通過例程里面的畫實心圓來表示,用一個for來遍歷每個圓心坐標,讓代碼簡介,在用個隨機數函數產生0-8的數字來代表老鼠出現的位置,然后通過同樣的方法取出老鼠的圖片,根據洞圓心的坐標,找到老鼠顯示的坐標顯示出老鼠,這里背景是指顯示一次的,老鼠變換一次刷新一次屏幕,刷新就只用刷新你目前的狀態,洞的顯示和老鼠的位置,讓洞把老鼠覆蓋就可以不用刷新背景了。再游戲結束之后再重新刷新背景顯示游戲結束和繼續就好了。
顯示完成了接下來就是觸摸,由于它的例程里面自帶觸摸函數,可以直接調用來返回當前的x,y坐標,這樣觸摸就很容易了
key_9=(tp_dev.x[0]+1)/80+3*(tp_dev.y[0]+1-20)/100;
用以上這段代碼就可以識別出觸摸的是之前分的3*3的那個位置,返回的1-9,然后再和老鼠對應的坐標進行判斷就可以知道打對與否,對就加分,分到就升級,升級了就提高地鼠刷新次數,錯就減分,減生命,分為0時就不減了,生命為0就游戲結束。還有不管對錯,只要點擊了屏幕地鼠的持續時間就會減短,馬上刷新下一只地鼠。就不用多余的等待。
單片機源程序如下:
- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "lcd.h"
- #include "key.h"
- #include "24cxx.h"
- #include "myiic.h"
- #include "touch.h"
- #include "stdlib.h"
- #ifndef __IMAGE2LCD_H
- #define __IMAGE2LCD_H
- #include "sys.h"
- __packed typedef struct _HEADCOLOR
- {
- unsigned char scan;
- unsigned char gray;
- unsigned short w;
- unsigned short h;
- unsigned char is565;
- unsigned char rgb;
- }HEADCOLOR;
- void image_display(u16 x,u16 y,u8 * imgx);//在指定位置顯示圖片
- void image_show(u16 xsta,u16 ysta,u16 xend,u16 yend,u8 scan,u8 *p);//在指定區域開始顯示圖片
- u16 image_getcolor(u8 mode,u8 *str);//獲取顏色
- extern const u8 gImage_1[];
- extern const u8 gImage_2[];
- #endif
- //ALIENTEK Mini STM32開發板范例代碼21
- //觸摸屏實驗
- //技術支持:www.openedv.com
- //廣州市星翼電子科技有限公司
- void Load_Drow_Dialog(void)
- {
- LCD_Clear(WHITE);//清屏
- //POINT_COLOR=BLUE;//設置字體為藍色
- //LCD_ShowString(lcddev.width-24,0,200,16,16,"RST");//顯示清屏區域
- POINT_COLOR=RED;//設置畫筆藍色
- }
- ////////////////////////////////////////////////////////////////////////////////
- //電容觸摸屏專有部分
- //畫水平線
- //x0,y0:坐標
- //len:線長度
- //color:顏色
- void gui_draw_hline(u16 x0,u16 y0,u16 len,u16 color)
- {
- if(len==0)return;
- LCD_Fill(x0,y0,x0+len-1,y0,color);
- }
- //畫實心圓
- //x0,y0:坐標
- //r:半徑
- //color:顏色
- void gui_fill_circle(u16 x0,u16 y0,u16 r,u16 color)
- {
- u32 i;
- u32 imax = ((u32)r*707)/1000+1;
- u32 sqmax = (u32)r*(u32)r+(u32)r/2;
- u32 x=r;
- gui_draw_hline(x0-r,y0,2*r,color);
- for (i=1;i<=imax;i++)
- {
- if ((i*i+x*x)>sqmax)// draw lines from outside
- {
- if (x>imax)
- {
- gui_draw_hline (x0-i+1,y0+x,2*(i-1),color);
- gui_draw_hline (x0-i+1,y0-x,2*(i-1),color);
- }
- x--;
- }
- // draw lines from inside (center)
- gui_draw_hline(x0-x,y0+i,2*x,color);
- gui_draw_hline(x0-x,y0-i,2*x,color);
- }
- }
- //兩個數之差的絕對值
- //x1,x2:需取差值的兩個數
- //返回值:|x1-x2|
- u16 my_abs(u16 x1,u16 x2)
- {
- if(x1>x2)return x1-x2;
- else return x2-x1;
- }
- //畫一條粗線
- //(x1,y1),(x2,y2):線條的起始坐標
- //size:線條的粗細程度
- //color:線條的顏色
- void lcd_draw_bline(u16 x1, u16 y1, u16 x2, u16 y2,u8 size,u16 color)
- {
- u16 t;
- int xerr=0,yerr=0,delta_x,delta_y,distance;
- int incx,incy,uRow,uCol;
- if(x1<size|| x2<size||y1<size|| y2<size)return;
- delta_x=x2-x1; //計算坐標增量
- delta_y=y2-y1;
- uRow=x1;
- uCol=y1;
- if(delta_x>0)incx=1; //設置單步方向
- else if(delta_x==0)incx=0;//垂直線
- else {incx=-1;delta_x=-delta_x;}
- if(delta_y>0)incy=1;
- else if(delta_y==0)incy=0;//水平線
- else{incy=-1;delta_y=-delta_y;}
- if( delta_x>delta_y)distance=delta_x; //選取基本增量坐標軸
- else distance=delta_y;
- for(t=0;t<=distance+1;t++ )//畫線輸出
- {
- gui_fill_circle(uRow,uCol,size,color);//畫點
- xerr+=delta_x ;
- yerr+=delta_y ;
- if(xerr>distance)
- {
- xerr-=distance;
- uRow+=incx;
- }
- if(yerr>distance)
- {
- yerr-=distance;
- uCol+=incy;
- }
- }
- }
- const u16 POINT_COLOR_TBL[CT_MAX_TOUCH]={RED,GREEN,BLUE,BROWN,GRED};
- ////////////////////////////////////////////////////////////////////////////////
- //5個觸控點的顏色
- //電阻觸摸屏測試函數
- u8 flag_1=5;
- void rtp_test(void)
- {
- u8 key;
- u8 i=0;
- u8 z=0;
- u16 o=rand()%9;
- u8 key_9=0;
- u16 score=0;
- u8 flag=1;
- u8 flag_2=1;
- u8 level=1;
- // for(z=0;z<9;z++)
- // {
- // gui_fill_circle((z%3)*80+40,(z/3)*100+70,40,BLUE);
- // }
- // LCD_ShowString(0,0,200,16,16,"SCORE");
-
- while(1)
- {
- key=KEY_Scan(0);
- tp_dev.scan(0);
- key_9=(tp_dev.x[0]+1)/80+3*(tp_dev.y[0]+1-20)/100;
- if(flag_1==5)
- {
-
- LCD_Clear(WHITE);
- image_display(0,0,(u8*)gImage_1);
- LCD_ShowString(0,0,200,16,16,"SCORE");
- LCD_ShowString(79,0,200,16,16,"LEVEL");
- LCD_ShowString(159,0,200,16,16,"LIFE");
- flag_1=0;
- }
- if(flag_1<=3)
- {
- if(i==0)
- {
- LCD_ShowNum(189,0,4-flag_1,4,16);
- LCD_ShowNum(29,0,score,4,16);
- LCD_ShowNum(109,0,level,4,16);
-
- for(z=0;z<9;z++)
- {
- gui_fill_circle((z%3)*80+40,(z/3)*100+70,25,BRRED);
- }
- delay_ms(10);
- //LCD_ShowNum(0,0,o,4,16);
- //LCD_ShowNum((o%3)*80+36,(o/3)*100+62,o,1,16);
- image_display((o%3)*80-17+40,(o/3)*100-17+70,(u8*)gImage_2);
- }
- //gui_fill_circle(119,159,40,BLUE);
- if(tp_dev.sta&TP_PRES_DOWN) //觸摸屏被按下
- {
- if(tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height)
- {
- // if(tp_dev.x[0]>(lcddev.width-24)&&tp_dev.y[0]<16)Load_Drow_Dialog();//清除
- // else
- // {
- // TP_Draw_Big_Point(tp_dev.x[0],tp_dev.y[0],POINT_COLOR_TBL[i%5]);
- //
- // } //畫圖
- // key_9=(tp_dev.x[0]+1)/80+3*(tp_dev.y[0]+1-20)/100;
-
- if((o+1)==key_9&&flag)
- {
- score++;
- flag=0;
- }
- else if(flag)
- {
- if(score>0)score--;
- flag=0;
- flag_1++;
- }
-
- i=(int)(100/(level*0.75)-15);
-
- }
- }else delay_ms(10); //沒有按鍵按下的時候
- if(key==KEY0_PRES) //KEY0按下,則執行校準程序
- {
- LCD_Clear(WHITE);//清屏
- TP_Adjust(); //屏幕校準
- TP_Save_Adjdata();
- Load_Drow_Dialog();
- }
-
- if(score>19){level++;score=0;}
- i++;
- if(i>(100/(level*0.75)))
- {
- o=rand()%9;
- LED0=!LED0;
- flag=1;
- i=0;
- }
- }
- if(flag_1>3)
- {
- if(flag_2){tp_dev.x[0]=0;tp_dev.y[0]=0;flag_2=0;
- LCD_Clear(WHITE);//清屏
- image_display(0,0,(u8*)gImage_1);
- if(tp_dev.touchtype!=0XFF)LCD_ShowString(90,130,200,16,16,"GAME OVER");
- if(tp_dev.touchtype!=0XFF)LCD_ShowString(110,160,200,16,16,"continue");
- }
- //LCD_Clear(WHITE);
- if(key_9==5)
- {
- flag_1=5;
- level=1;
- score=0;
- flag=1;
- flag_2=1;
- }
- }
- }
- }
-
- //電容觸摸屏測試函數
- void ctp_test(void)
- {
- u8 t=0;
- u8 i=0;
- u16 lastpos[5][2]; //最后一次的數據
- while(1)
- {
- tp_dev.scan(0);
- for(t=0;t<CT_MAX_TOUCH;t++)//最多5點觸摸
- {
- if((tp_dev.sta)&(1<<t))//判斷是否有點觸摸?
- {
- if(tp_dev.x[t]<lcddev.width&&tp_dev.y[t]<lcddev.height)//在LCD范圍內
- {
- if(lastpos[t][0]==0XFFFF)
- {
- lastpos[t][0] = tp_dev.x[t];
- lastpos[t][1] = tp_dev.y[t];
- }
- lcd_draw_bline(lastpos[t][0],lastpos[t][1],tp_dev.x[t],tp_dev.y[t],2,POINT_COLOR_TBL[t]);//畫線
- lastpos[t][0]=tp_dev.x[t];
- lastpos[t][1]=tp_dev.y[t];
- if(tp_dev.x[t]>(lcddev.width-24)&&tp_dev.y[t]<16)
- {
- Load_Drow_Dialog();//清除
- }
- }
- }else lastpos[t][0]=0XFFFF;
- }
-
- delay_ms(5);i++;
- if(i%20==0)LED0=!LED0;
- }
- }
- int main(void)
- {
- delay_init(); //延時函數初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
- uart_init(9600); //串口初始化為9600
- LED_Init(); //初始化與LED連接的硬件接口
- LCD_Init(); //初始化LCD
- KEY_Init(); //按鍵初始化
- tp_dev.init(); //觸摸屏初始化
- POINT_COLOR=RED;//設置字體為紅色
-
- Load_Drow_Dialog();
- if(tp_dev.touchtype&0X80)ctp_test(); //電容屏測試
- else rtp_test(); //電阻屏測試
-
- }
復制代碼
所有資料51hei提供下載(源碼+文檔):
打地鼠V1.0.7z
(414.54 KB, 下載次數: 136)
2018-12-13 21:50 上傳
點擊文件名下載附件
詳細工程 下載積分: 黑幣 -5
說明文檔.docx
(15.47 KB, 下載次數: 100)
2018-12-13 09:21 上傳
點擊文件名下載附件
說明文檔 下載積分: 黑幣 -5
|