嵌入式程序设计-打地鼠游戏设计嵌入式程序设计打地鼠2013年6月3日目录1开发背景 ..................................................................... ........................... 3 2功能描述 ..................................................................... ........................... 3 3.基本原理 ..................................................................... ........................... 3 4.系统总体设计 ..................................................................... . (4)4.1界面设计 ..................................................................... . (4)4.2 相关变量定义 ..................................................................... .. (6)4.3 内部类定义及方法说明 (6)5系统测试 ..................................................................... . (16)5.1 运行界面...................................................................... . (16)1开发背景打地鼠是一款常见的小游戏,简单有趣,深受人们的喜爱,本项目作为基于嵌入式WinCE课程设计和简单游戏编程而提出。
希望通过开发《打地鼠》游戏,了解并掌握WinCE软件开发工具的使用,同时提高嵌入式设计的能力。
2功能描述基本功能:地鼠随机出现在地图上,跟据鼠标点击事件捕获鼠标指针所在区域是否出现地鼠来判断玩家是否击中地鼠,玩家有10次失误机会。
3.基本原理玩家触发游戏后,地鼠会随机出现在地图上,玩家通过鼠标击打地鼠,地鼠每隔一段时间机会随机出现在地图某一块,若玩家反映不及没有触发鼠标事件,地鼠随机出现别的地方玩家分数不变;若已触发鼠标事件且没有击中地鼠,玩家分数减少;击中则分数增加。
系统流程图:(主要部分的流程图)4.系统总体设计4.1界面设计本系统设计了三个界面,一个是游戏运行界面,一个是成绩保存,一个历史最高纪录显示界面(玩家成绩)。
4.2 相关变量定义int scorce;//得分int randx=0,randy=0;//随机得到的地鼠坐标 int Total=10;//若有Total次击不中则游戏结束 typedef struct{TCHAR name[20];//姓名int score;//成绩}User;4.3 内部类定义及方法说明 void ReadScoreFile();//读取历史分数记录void WriteScoreFile();//将玩家的游戏分数写到文件中 void SortList();//对玩家分数排序void InitData();//初始化数据void EndGame();//游戏结束void clearPicture(); //还原背景图void drawPicture(int bmpNum);//画图 void chilkTrue(int x,int y);//判定是否击中BOOL CDadishuDlg::OnInitDialog()游戏初始化函数。
void CMengSnakeDlg::OnTimer(UINT nIDEvent)计时器函数,自动根据时间变量来执行程序,随机为地鼠生成一个坐标,并绘制到地图上。
void CDadishuDlg::OnLButtonDown(UINT nFlags, CPoint point)消息处理函数,鼠标左键点击触发,主要用来打击地鼠。
void CDadishuDlg::OnPaint()重绘函数,实现地图区域的绘制游戏界面部分相关代码:OOL CDadishuDlg::OnInitDialog(){CDialog::OnInitDialog();// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small iconCenterWindow(GetDesktopWindow()); // center to the hpc screen// TODO: Add extra initialization hereHWND hwndCB;hwndCB = CommandBar_Create(AfxGetInstanceHandle(), GetSafeHwnd(),0);CommandBar_InsertMenubar(hwndCB, AfxGetInstanceHandle(), IDR_MENU1, 0);return TRUE; // return TRUE unless you set the focus to a control }//还原背景图void CDadishuDlg::clearPicture(){PDC = GetDC();CDC bmpDC;bmpDC.CreateCompatibleDC(PDC);CBitmap bmp;bmp.LoadBitmap(IDB_BITMAP3);BITMAP bm;bmp.GetBitmap(&bm);bmpDC.SelectObject(bmp);int px=40+randx*80+1;int py=40+randy*80+1;PDC->StretchBlt (px,py,78,78,&bmpDC,0,0,bm.bmWidth, bm.bmHeight,SRCCOPY);}//画图void CDadishuDlg::drawPicture(int bmpNum){PDC = GetDC();CDC bmpDC;bmpDC.CreateCompatibleDC(PDC);CBitmap bmp;if(bmpNum==1)bmp.LoadBitmap(IDB_BITMAP1);elsebmp.LoadBitmap(IDB_BITMAP2);BITMAP bm;bmp.GetBitmap(&bm);bmpDC.SelectObject(bmp);int px=40+randx*80+1;int py=40+randy*80+1;PDC->StretchBlt (px,py,78,78,&bmpDC,0,0,bm.bmWidth, bm.bmHeight,SRCCOPY);}//判定是否击中void CDadishuDlg::chilkTrue(int x,int y){int px_min=40+randx*80;int px_max=40+(randx+1)*80;int py_min=40+randy*80;int py_max=40+(randy+1)*80;if(x>=px_min&&x<=px_max&&y>=py_min&&y<=py_max){ scorce+=10;drawPicture(2);}else{Total--;scorce-=10;clearPicture();}if(Total==0){EndGame();TS *ts=new TS;ts->m_Value=scorce;ts->DoModal();}}//void CDadishuDlg::OnPaint(){CPaintDC dc(this); // device context for painting// TODO: Add your message handler code hereCDC *pDC=new CClientDC(this);CPen pen;//画笔pen.CreatePen(PS_SOLID,1,RGB(0,0,0));CPen *poldpen=pDC->SelectObject(&pen);pDC->Rectangle(40,40,280,280);pDC->SelectObject(poldpen);//new出来的一般都需要delete来回收内存。
delete pDC;// Do not call CDialog::OnPaint() for painting messages}//鼠标点击事件void CDadishuDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call default if(!start)return;chilkTrue(point.x,point.y);CDialog::OnLButtonDown(nFlags, point);}//void CDadishuDlg::OnTimer(UINT nIDEvent){// TODO: Add your message handler code here and/or call default switch(nIDEvent){case 1:clearPicture();randx=rand()%3;randy=rand()%3;drawPicture(1);break;case 2:m_score=scorce;UpdateData(FALSE);break;case 3:_time++;char temp[10];CString time;int second=_time%60;int minut=_time/60%60;int hour=_time/3600%24;_itoa(hour,temp,10);if(hour>9)time+=temp;elsetime=time+"0"+temp;_itoa(minut,temp,10);if(minut>9)time=time+":"+temp;elsetime=time+":0"+temp;_itoa(second,temp,10);if(second>9)time=time+":"+temp;elsetime=time+":0"+temp;m_time=time;UpdateData(FALSE);break;}CDialog::OnTimer(nIDEvent); } //初始化数据void CDadishuDlg::InitData() { Total=10;start=true;SetTimer(1,timer,NULL);scorce=0;SetTimer(2,100,NULL);_time=0;SetTimer(3,1000,NULL); }//void CDadishuDlg::EndGame() {KillTimer(1);KillTimer(2);KillTimer(3);start=false;}//重新开始void CDadishuDlg::OnMENUITEMRestart(){// TODO: Add your command handler code here EndGame();InitData();}//开始游戏void CDadishuDlg::OnMENUITEMStart(){// TODO: Add your command handler code here InitData();}//void CDadishuDlg::OnMENUITEMSeachRecord() {// TODO: Add your command handler code hereSerachRecord *sr=new SerachRecord;sr->DoModal();}保存记录的相关代码:User list[11];int UserListLength=0;//////////////////////////////////////////////////////////////////// /////////// TS message handlersvoid TS::ReadScoreFile(){CString filename="\\scores.dat";HANDLEhFile=CreateFile(filename,GENERIC_READ,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);SetFilePointer(hFile,0,NULL,FILE_BEGIN);User us;DWORD aa;int i=0;do{ZeroMemory(&us,sizeof(us));if(ReadFile(hFile,&us,sizeof(us),&aa,NULL)){if(aa!=0)list[i++]=us;}}while(aa==sizeof(us));UserListLength=i;CloseHandle(hFile);}//写到文件里void TS::WriteScoreFile(){CString filename="\\scores.dat";int i;//文件句柄HANDLEhFile=CreateFile(filename,GENERIC_WRITE,FILE_SHARE_WRITE,NULL, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);//设置文件开始处SetFilePointer(hFile,0,NULL,FILE_BEGIN);DWORD aa;//将数据写到文件for(i=0;i<UserListLength&&i<10;i++){WriteFile(hFile,&list[i],sizeof(list[i]),&aa,NULL); }CloseHandle(hFile);}//安分数从大到小排序void TS::SortList(){int i,j,k;for(i=0;i<UserListLength-1;i++){k=i;for(j=i+1;j<UserListLength;j++)if(list[j].score>list[k].score)k=j;if(k!=i){User temp=list[k];list[k]=list[i];list[i]=temp;}}}void TS::OnOK(){// TODO: Add extra validation here// TODO: Add extra validation hereUpdateData(TRUE);ReadScoreFile();int i=0;User us;ZeroMemory(&us,sizeof(us));//将值更新到变量UpdateData(TRUE);wcscpy(,m_UserName);us.score=m_Value;list[UserListLength]=us;UserListLength++;SortList();for(i=0;i<UserListLength-1;i++){if(list[i].name==&&list[i].score==us.score&&i>=10) {AfxMessageBox(_T("对不起你的名次最低,没有突破前10名")); return;}}WriteScoreFile();CDialog::OnOK();}查看记录相关代码void SerachRecord::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(SerachRecord)DDX_Control(pDX, IDC_LIST1, m_list);CRect rt;m_list.GetClientRect(&rt);m_list.InsertColumn(0,_T("名次"),LVCFMT_LEFT,(int)(rt.Width()*0.35));m_list.InsertColumn(1,_T("得分"),LVCFMT_LEFT,(int)(rt.Width()*0.35));m_list.InsertColumn(2,_T("姓名"),LVCFMT_LEFT,(int)(rt.Width()*0.3));//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(SerachRecord, CDialog)//{{AFX_MSG_MAP(SerachRecord)//}}AFX_MSG_MAPEND_MESSAGE_MAP()//////////////////////////////////////////////////////////////////// /////////// SerachRecord message handlersvoid SerachRecord::OnOK(){// TODO: Add extra validation herem_list.DeleteAllItems();CString filename="\\scores.dat";HANDLEhFile=CreateFile(filename,GENERIC_READ,FILE_SHARE_WRITE,NULL, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);SetFilePointer(hFile,0,NULL,FILE_BEGIN);User us;User usList[10];DWORD aa;int i=0;do{ZeroMemory(&us,sizeof(us));if(ReadFile(hFile,&us,sizeof(us),&aa,NULL)){if(aa!=0){usList[i++]=us;}}}while(aa==sizeof(us));for(int j=i-1;j>=0;j--){m_list.InsertItem(0,_T("test"));char temp[10];_itoa(j+1, temp, 10);CString num=temp;m_list.SetItemText(0,0,num);m_list.SetItemText(0,2,usList[j].name); _itoa(usList[j].score, temp, 10); CString sc=temp;m_list.SetItemText(0,1,sc);}CloseHandle(hFile);//CDialog::OnOK();}5系统测试5.1 运行界面1游戏开始界面2(中间游戏进行界面3(游戏结束界面4(刷新显示记录:。