[Win32] 打字游戏

这是我大学三年级时,学习Win32 SDK后,自己开发的一个打字练习程式

很简单的练习,随机出现英文字母,并往下掉

 

/* 一個很基本的打字練習程式,以前學校程式設計比賽的題目。 會出現英文字母往下掉,按相同的消掉。 用SDK打,想練習一下計時器的用法。 有設計得分和落下速度增快的功能。 若要compile此程式碼,請用VC++新增專案。 選擇Win32Application,在插入程式碼。 */ #include <windows.h> #include <stdlib.h> #include <time.h> #define ID_TIMER 1 #define TimeLong 300 //設定Timer最慢時間 #define MaxNum 15 //設定落下字母數上限 #define MaxGrade 210 //設定每成功消掉一個字可得的最高分 static TCHAR temp[]=TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd) { static TCHAR AppName[]=TEXT("TypeGame"); HWND hwnd; MSG msg; WNDCLASS wndcls={CS_SAVEBITS,WndProc,0,0,hInstance,//偷懶所以把視窗類別寫成這樣 LoadIcon(NULL,IDI_APPLICATION),LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH),NULL,AppName}; if(!RegisterClass(&wndcls)) { MessageBox(NULL,TEXT("註冊視窗失敗"),AppName,MB_ICONERROR); return 0; } hwnd=CreateWindowEx(WS_EX_TOPMOST,AppName,"打字練習",//利用CreateWindowEx讓程式保持最上曾 WS_CAPTION|WS_BORDER|WS_MINIMIZEBOX|WS_SYSMENU, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance, NULL); ShowWindow(hwnd,nShowCmd); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; TEXTMETRIC tm; int i,RandChoice; TCHAR szBuffer[10];//用來顯示一些數字的暫存區 static int cxChar,cyChar,cxClient,cyClient,//定義字體和顯示區域的x,y值 Life,Grade,TimeNow,Level;//生命值,分數,現在Timer間隔,等級只是用來判斷何時要讓速度變快 static TCHAR typer[MaxNum],Output[1],PlayerChoice;//因為TextOut要放指標進去,所以用這麼多有的沒的 static POINT pt[MaxNum];//字體的座標 srand(time(NULL)); switch(msg) { case WM_CREATE: hdc=GetDC(hwnd); GetTextMetrics(hdc,&tm); cxChar=tm.tmAveCharWidth;//取得字體寬度 cyChar=tm.tmHeight+tm.tmExternalLeading;//取得字體高度 ReleaseDC(hwnd,hdc); Life=MaxNum;//生命值等於最大字母數 Grade=0,Level=0;//分數一開始當然是0 for(i=0;i<MaxNum;i++) //初始化遊戲資料:起始字母 { typer[i]=temp[rand()%26]; } TimeNow=TimeLong;//設定Timer的間隔 SetTimer(hwnd,ID_TIMER,TimeNow,NULL);//設定計時器 return 0; case WM_SIZE: cxClient=LOWORD(lParam); cyClient=HIWORD(lParam); for(i=0;i<MaxNum;i++)//設定起始的位置 { //因為視窗建立時會發送WM_CREATE和WM_SIZE pt[i].x=cxClient/3+(cxClient/30*i); pt[i].y=10; } return 0; case WM_TIMER: srand(time(NULL)); RandChoice=rand()%MaxNum;//隨機挑取一個字下降 pt[RandChoice].y+=cyChar; if( pt[RandChoice].y >= (cyClient-155) &&typer[RandChoice]!=' ') { typer[RandChoice]=' ';//掉到線底下就扣1的生命 Life--; if(Life<1) { KillTimer(hwnd,ID_TIMER); MessageBox(hwnd,"遊戲結束","GameOver",MB_ICONERROR); PostMessage(hwnd,WM_CLOSE,wParam,lParam); } } InvalidateRect(hwnd,NULL,TRUE);//重繪顯示區域 return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); TextOut(hdc,15,10,TEXT("Grade:"),6);//顯示得分 TextOut(hdc,15+9*cxChar,10,szBuffer,wsprintf(szBuffer,TEXT("%8d"),Grade)); TextOut(hdc,15,10+cyChar,TEXT("Life:"),5);//顯示生命 TextOut(hdc,15+5*cxChar,10+cyChar,szBuffer,wsprintf(szBuffer,TEXT("%2d"),Life)); for(i=0;i<MaxNum;i++) { Output[0]=typer[i]; TextOut(hdc,pt[i].x,pt[i].y,Output,1); } MoveToEx(hdc,0,cyClient-150,NULL);//設定下降底限 LineTo(hdc,cxClient,cyClient-150); EndPaint(hwnd,&ps); return 0; case WM_CHAR: PlayerChoice=(TCHAR)wParam;//抓取鍵盤字元 if(PlayerChoice>='a'&&PlayerChoice<='z') PlayerChoice^=32; for(i=0;i<MaxNum;i++) { if(typer[i]==PlayerChoice) { typer[i]=temp[rand()%26]; Grade+=MaxGrade-pt[i].y; Level=Grade; if(Level>1000)//增加速度的判斷 { Level=0; TimeNow-=30; if(TimeNow>0) SetTimer(hwnd,ID_TIMER,TimeNow,NULL); } pt[i].y=10; InvalidateRect(hwnd,NULL,TRUE);//重繪顯示區域 break; } } return 0; case WM_DESTROY: KillTimer(hwnd,ID_TIMER); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,msg,wParam,lParam); }

你可能感兴趣的:(timer,null,application,callback,output,winapi)