版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、VC+ win32 API 游戲開發(fā),VC+ win32 API 游戲開發(fā),1.Windows 編程 2.Windows應(yīng)用程序的組成與編程 3. 游戲?qū)崿F(xiàn)原理與Window GDI繪圖 4.游戲?qū)嵗钠饰?1.Windows編程,1.1 Windows API編程基礎(chǔ) 1.2 窗口 1.3 事件驅(qū)動 1.4 句柄 1.5 消息 1.6 Windows應(yīng)用程序的常用消息,1.1 Windows API編程基礎(chǔ),Windows編程的方法主要有兩種方法: 傳統(tǒng)編寫法:利用API函數(shù)。 交互式方法:利用MFC類庫。 為使程序員編寫具有Windows風(fēng)格的應(yīng)用程序,Windows提供了一個應(yīng)用程序編程
2、接口(Application Programming Interface,簡稱API),它是Windows系統(tǒng)與Windows應(yīng)用程序間的標(biāo)準(zhǔn)程序接口。 上千個API函數(shù)包含了各種窗口類和系統(tǒng)資源。 API可以為應(yīng)用程序提供windows系統(tǒng)特殊函數(shù)及數(shù)據(jù)結(jié)構(gòu)。 windows應(yīng)用程序可以利用大量API函數(shù)調(diào)用系統(tǒng)功能。,MFC,MFC, Microsoft Foundation Class Library,微軟基礎(chǔ)類庫,約有200個類。 MFC封裝了大部分API函數(shù),并提供了一個應(yīng)用程序框架,簡化了和標(biāo)準(zhǔn)了windows程序設(shè)計。 但Windows API編程方法始終是windows編程的基
3、礎(chǔ)。,1.2 窗口,編寫一個Windows應(yīng)用程序首先應(yīng)創(chuàng)建一個或多個窗口,而后應(yīng)用程序的運行過程即是窗口內(nèi)部、窗口與窗口之間、窗口與系統(tǒng)之間進行數(shù)據(jù)處理與數(shù)據(jù)交換的過程。,1.3 事件驅(qū)動,Windows程序設(shè)計是針對事件或消息的,它的執(zhí)行順序取決于事件發(fā)生的順序。 在Windows環(huán)境下,應(yīng)用程序啟動后,系統(tǒng)等待用戶在圖形用戶界面內(nèi)的輸入選擇,如鼠標(biāo)按鍵、鍵盤按鍵、窗口被創(chuàng)建、關(guān)閉、改變大小、移動等,對系統(tǒng)來說,這都是事件,都會產(chǎn)生相應(yīng)的windows消息。 事件驅(qū)動編程方法對于編寫交互式程序很有用處,它避免了死板的操作模式。,1.4 句柄,句柄,顧名思義,指的是一個windows對象的把
4、柄。 Windows中的句柄都是32位的指針變量,用來指向某個windows對象所占據(jù)的內(nèi)存區(qū)。 句柄的使用,極大地方便了Windows管理其內(nèi)存中的各種windows對象。,常用句柄類型及其說明,1.5 消息,消息是描述事件發(fā)生的信息。 Windows應(yīng)用程序通過消息進行信息交換。 在Windows中,消息用結(jié)構(gòu)體MSG表示,其結(jié)構(gòu)如下: Typedef struct tagMSG HWND hwnd; /窗口句柄 UNIT message; /消息號。 WPARAM wParam;/用于提供消息的附加消息。 LPARAM lParam;/用于提供消息的附加消息。 DWORD time;/指
5、定消息送至隊列的時間 POINT pt; /指定消息發(fā)送時屏幕光標(biāo)的位置 MSG;,VC+中存在幾種系統(tǒng)定義的消息分類,不同的前綴符號經(jīng)常用于識別消息的分類,如下表所示:,1.6 Windows應(yīng)用程序的常用消息,1.鼠標(biāo)消息,主要有: WM_LBUTTONDOWN:產(chǎn)生單擊鼠標(biāo)左鍵的消息。 WM_LBUTTONUP:放開鼠標(biāo)左鍵時產(chǎn)生的消息。 2.鍵盤消息,主要有: WM_KEYDOWN:按下一個系統(tǒng)鍵時產(chǎn)生的消息。 WM_KEYUP:放開一個系統(tǒng)鍵時產(chǎn)生的消息。 3.窗口消息,主要有: WM_CREATE:窗口創(chuàng)建時,由CreateWindows函數(shù)發(fā)出的消息。 WM_CLOSE:關(guān)閉窗口
6、時產(chǎn)生的消息。 WM_QUIT:退出應(yīng)用程序時,由PostQuitMessage函數(shù)發(fā)出消息。 ,2.Windows應(yīng)用程序的組成與編程,2.1 典型的Windows程序結(jié)構(gòu) 2.2 入口函數(shù)WinMain() 2.3 窗口函數(shù)WinProc() 2.4 windows應(yīng)用程序的常用數(shù)據(jù)類型 2.5 API編程實例,2.1 典型的Windows程序結(jié)構(gòu),Windows應(yīng)用程序的主體由以下兩個函數(shù)完成: WinMain()函數(shù)負(fù)責(zé)建立窗口和建立消息循環(huán)。 WinProc()函數(shù)負(fù)責(zé)消息的處理。,2.1 典型的Windows程序結(jié)構(gòu),2.2 入口函數(shù)WinMain(),WinMain()函數(shù)類似C
7、語言中的Main函數(shù),是Win32應(yīng)用程序入口函數(shù)。 WinMain()函數(shù)主要完成創(chuàng)建主窗口,并產(chǎn)生和處理消息循環(huán)。,WinMain()函數(shù),因為windows是多任務(wù)系統(tǒng),所以同一應(yīng)用程序的多個窗口可能會同時存在。 windows系統(tǒng)對每個窗口的執(zhí)行稱為一個實例,用一個實例句柄來唯一標(biāo)識。 WinMain()函數(shù)與DOS程序的main()函數(shù)起同樣的作用,有一點不同的是,WinMain()函數(shù)必須帶有四個參數(shù),它們是系統(tǒng)傳遞給它的。 WinMain()函數(shù)的原型如下: int PASCAL WinMain( HINSTANCE hInstance, /當(dāng)前實例句柄 HINSTANCE hP
8、revInstance, /前一個實例句柄 LPSTR lpCmdLine, /命令行字符 int nCmdShow) /窗口顯示方式,WinMain()函數(shù),第一個參數(shù)hInstance,是標(biāo)識該應(yīng)用程序當(dāng)前實例的句柄。 第二個參數(shù)是hPrevInstance,它是用來標(biāo)識該應(yīng)用程序的前一個實例的句柄。 第三個參數(shù)是lpCmdLine,是指向應(yīng)用程序命令行參數(shù)字符串的指針。 最后一個參數(shù)是nCmdShow,是一個用來指定窗口顯示方式的整數(shù)。這個整數(shù)值可以是SW_SHOW、SW_HIDE、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED等。,WinMain()函數(shù)主要由2部分
9、組成: 窗口初始化 消息循環(huán),窗口初始化包括以下主要步驟:,定義窗口類: 通過給窗口類數(shù)據(jù)結(jié)構(gòu)WINDCLASS賦值,設(shè)置窗口類的各種屬性。如窗口邊框、窗口標(biāo)題欄文字、窗口大小和位置、鼠標(biāo)、背景色等。 注冊窗口類: Win系統(tǒng)本身提供部分預(yù)定義的窗口類,程序員也可以自定義窗口類。窗口類必須先注冊后使用。窗口類的注冊由函數(shù)RegisterClass()實現(xiàn)。 創(chuàng)建窗口實例: 創(chuàng)建窗口類的實例由CreateWindows()函數(shù)實現(xiàn)。 窗口顯示: 窗口類的顯示是由ShowWindows()函數(shù)和UpdateWindows()函數(shù)實現(xiàn)的。 ShowWindows()函數(shù):應(yīng)用程序通過調(diào)用ShowWi
10、ndows()函數(shù)在屏幕上顯示窗口。 UpdateWindows()函數(shù):顯示窗口后,應(yīng)用程序調(diào)用UpdateWindow更新并繪制用戶區(qū),并發(fā)出WM_PAINT消息。,消息循環(huán),Windows為當(dāng)前執(zhí)行的每個Windows程序維護一個消息隊列。 在發(fā)生輸入事件之后,Windows將事件轉(zhuǎn)換為一個消息并將消息放入程序的消息隊列中。 程序通過執(zhí)行一塊稱之為消息循環(huán)的程序代碼從消息隊列中取出消息。 以下是WinMain()函數(shù)中消息循環(huán)的代碼: /消息循環(huán)以調(diào)用GetMessage()開始,它從消息隊列中取出/一個消息 while (GetMessage ( ,WinMain()函數(shù)的大致結(jié)構(gòu),i
11、nt PASCAL WinMain( ) /定義窗口類: WNDCLASS wndclass; wndclass.style=CS_HREDRAW|CS_VREDRAW; 十個字段 wndclass.lpszClassName=”Lei”; /注冊窗口類: RegisterClass( ,2.3 窗口函數(shù)WndProc(),窗口函數(shù)WndProc()就是Windows應(yīng)用程序的消息處理程序。 窗口函數(shù)WndProc()定義了應(yīng)用程序?qū)邮盏降牟煌⒌捻憫?yīng),包含了對各種可能接收到的消息的處理過程。 WndProc函數(shù)由一個或多個switch語句組成。每一條case語句對應(yīng)一種消息,當(dāng)應(yīng)用程序接
12、收到一個消息時,相應(yīng)的case語句被激活并執(zhí)行相應(yīng)的響應(yīng)程序模塊。 窗口消息處理程序不予處理的所有消息被傳給名為DefWindowProc的Windows函數(shù)進行默認(rèn)處理。,消息處理函數(shù)WndProc的大致結(jié)構(gòu),LRESULT CALLBACK WndProc(HWND hMainwnd, UINT message, WPARAM wParam, LPARAM lParam) /窗口函數(shù)的定義 switch( message ) case WM_KEYDOWN:/擊鍵消息 ; break; case : ; break; case WM_DESTROY:/關(guān)閉應(yīng)用程序窗口時發(fā)出的消息 Post
13、QuitMessage(0);/發(fā)出WM_QUIT消息,結(jié)束應(yīng)用程序 return 0; default : break; /調(diào)用缺省消息處理過程 return DefWindowProc(hMainwnd, message, wParam, lParam); ,2.4 windows應(yīng)用程序的常用數(shù)據(jù)類型,所有的Windows應(yīng)用程序中,都有一個程序初始化的過程。 下面以一個實現(xiàn)最簡單功能的程序WinApiDemo為例,說明Windows程序的基本框架。操作步驟如下: (1)打開Visual C+ 6.0。 選擇File菜單的New,在出現(xiàn)的對話框中,選擇Projects欄目(新建工程),并
14、點取其下的Win32 Application項,表示使用Win32環(huán)境創(chuàng)建應(yīng)用程序。 (2)在Locatin(路徑)中填入工程的路徑,然后在Project Name(項目名稱)中填入“WinApiDemo”,其它按照缺省設(shè)置,單擊OK按鈕。 (3)選擇File菜單的New,在出現(xiàn)的對話框中,選擇Files欄目(新建文件),并點取其下的C+ Source File項,表示新建一個C+源文件。在右邊的File欄中輸入“WinApiDemo”,最后確定讓Add to project檢查框打上勾,單擊OK按鈕。 (4)在“WinApiDemo.cpp”文件中輸入以下程序代碼。,2.5 API編程實例,
15、WinApiDemo.cpp源代碼(1),#include /頭文件 LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); /窗口函數(shù)聲明,這一函數(shù)將處理發(fā)往應(yīng)用程序窗口的各種消息 char szClassName=windowclass;/窗口結(jié)構(gòu)體的名稱 char szAppTitle=API建立窗口實例;/窗口的標(biāo)題 INT PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam , INT nCmdShow) /WinMain()函數(shù)的
16、定義 HWND hMainWnd;/窗口句柄 MSG msg;/消息結(jié)構(gòu)體 WNDCLASS winclass;/窗口結(jié)構(gòu)體 if(!hPrevInstance) winclass.style=CS_HREDRAW|CS_VREDRAW;/窗口風(fēng)格 winclass.lpfnWndProc=WndProc; winclass.cbClsExtra=0;/附加參數(shù) winclass.cbWndExtra=0;/附加參數(shù) winclass.hInstance=hInstance;/當(dāng)前應(yīng)用程序?qū)嵗浔?winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);/窗
17、口圖標(biāo) winclass.hCursor=LoadCursor(NULL,IDC_ARROW);/窗口光標(biāo) winclass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH); /窗口背景色為淺灰色 winclass.lpszMenuName=NULL;/窗口菜單 winclass.lpszClassName=szClassName; /給窗口結(jié)構(gòu)體命名, /CreateWindow()函數(shù)將根據(jù)窗口結(jié)構(gòu)體的名稱來建立窗口 RegisterClass(/注冊窗口 ,WinApiDemo.cpp源代碼(2),/下面用CreateWindow()
18、函數(shù)來建立窗口,并返回所建立窗口的句柄 hMainWnd=CreateWindow( szClassName,/窗口結(jié)構(gòu)體的名稱 szAppTitle,/窗口的標(biāo)題 WS_OVERLAPPEDWINDOW,/窗口風(fēng)格為可重疊窗口 /下面四個參數(shù)代表窗口左上角x,y坐標(biāo)和窗口的寬度與高度,都使 /用缺省值 CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, /下面參數(shù)分別為父窗口句柄、窗口菜單句柄、應(yīng)用程序?qū)嵗浔?/和附加參數(shù) NULL,NULL,hInstance,NULL); ShowWindow(hMainWnd,SW_SH
19、OWNORMAL); /顯示最大化窗口 UpdateWindow(hMainWnd);/更新窗口 /下面用While()循環(huán)來建立消息循環(huán) while(GetMessage( ,WinApiDemo.cpp源代碼(3),LRESULT CALLBACK WndProc(HWND hMainwnd, UINT message, WPARAM wParam, LPARAM lParam) /窗口函數(shù)的定義 switch( message ) case WM_KEYDOWN:/擊鍵消息 MessageBox(hMainwnd,鍵按下了!,Keyboard,MB_OK); break; case WM
20、_RBUTTONDOWN:/鼠標(biāo)消息 MessageBox(hMainwnd,鼠標(biāo)右鍵按下了!,Mouse,MB_OK); break; case WM_LBUTTONDOWN:/鼠標(biāo)消息 MessageBox(hMainwnd,鼠標(biāo)左鍵按下了!,Mouse,MB_OK); break; case WM_DESTROY:/關(guān)閉應(yīng)用程序窗口時發(fā)出的消息 PostQuitMessage(0);/發(fā)出WM_QUIT消息,結(jié)束應(yīng)用程序 return 0; default : break; /調(diào)用缺省消息處理過程 return DefWindowProc(hMainwnd, message, wPara
21、m, lParam); ,WinApiDemo.cpp源代碼(4),case WM_RBUTTONDOWN: MessageBox(GetFocus(),messageright,API建立窗口實例,MB_OK|MB_ICONINFORMATION); break; case WM_LBUTTONDOWN: MessageBox(GetFocus(),messageleft,API建立窗口實例,MB_OK|MB_ICONINFORMATION); break; case WM_DESTROY:/關(guān)閉應(yīng)用程序窗口時發(fā)出的消息 PostQuitMessage(0); /發(fā)出WM_QUIT消息,結(jié)束
22、應(yīng)用程序 return 0; default :break; return DefWindowProc(hMainwnd,message,wParam,lParam); /其它沒有處理的消息交給Windows做默認(rèn)處理 ,WinApiDemo的運行畫面,3.游戲?qū)崿F(xiàn)原理與Window GDI繪圖,3.1 游戲?qū)崿F(xiàn)的基本原理 3.2 Window GDI基本概念 3.3 利用GDI實現(xiàn)游戲中的繪圖,3.1 游戲?qū)崿F(xiàn)的基本原理,3.2 Window GDI基本概念,GDI,Graphics Device Interface,即圖形設(shè)備接口,是Windows API的一個重要組成部分。 GDI是Wi
23、ndows圖形顯示程序與實際物理設(shè)備之間的橋梁,GDI使得用戶無需關(guān)心具體設(shè)備的細(xì)節(jié),而只需在一 個虛擬的環(huán)境(即邏輯設(shè)備)中進行操作。 GDI用一套通用的圖形對象來向屏幕,內(nèi)存甚至是打印機繪圖。,GDI函數(shù)大致可分類為: 設(shè)備上下文函數(shù):如GetDC、CreateDC、DeleteDC。 畫線函數(shù):如LineTo、Polyline、Arc。 填充畫圖函數(shù):如Ellipse、FillRect、Pie。 畫圖屬性函數(shù):如 SetBkColor、SetBkMode、SetTextColor。 文本、字體函數(shù):如TextOut、GetFontData。 位圖函數(shù):如 SetPixel、BitBlt、
24、StretchBlt。 坐標(biāo)函數(shù):如DPtoLP、LPtoDP、ScreenToClient、 ClientToScreen。 映射函數(shù):如SetMapMode、SetWindowExtEx、SetViewportExtEx。 元文件函數(shù):如PlayMetaFile、SetWinMetaFileBits。 區(qū)域函數(shù):如FillRgn、FrameRgn、InvertRgn。 路徑函 數(shù):如BeginPath、EndPath、StrokeAndFillPath。 裁剪函數(shù):如SelectClipRgn、 SelectClipPath。,設(shè)備上下文,在GDI編程中,幾乎所有的操作都圍繞設(shè)備上下文(D
25、C)展開。 設(shè)備上下文,Device Context,簡稱DC,是Windows 使用的一種結(jié)構(gòu),所有GDI操作前都需取得特定設(shè)備的上下文。 設(shè)備上下文的句柄是HDC。 HDC是一個你可以向其繪圖的句柄;它可以代表整個屏幕,一個窗口的客戶區(qū)域,一個存在內(nèi)存中的位圖,或是一個打印機。 例如,如果你想在一個窗口上繪圖,首先你要用GetDC()來獲取代表這個窗口的HDC,然后你就可以用任何以HDC為參數(shù)的GDI函數(shù)來繪圖了。,位圖,位圖可以用LoadBitmap()來完成大多數(shù)的基本操作,比如簡單地裝入一個位圖資源。 GDI不能直接用位圖對象來繪圖,因為繪圖操作已經(jīng)被設(shè)備上下文抽象了,只能通過設(shè)備上
26、下文來繪制位圖。 利用位圖繪圖的大體思路是:把位圖對象裝入設(shè)備上下文,通過設(shè)備上下文把位圖顯示在屏幕上。,3.3 利用GDI實現(xiàn)游戲中的繪圖,游戲中的繪圖主要通過是繪制位圖來實現(xiàn)的。 在游戲中,因為角色位圖的位置是不斷變化的,所以設(shè)備上下文中的合成位圖的內(nèi)容也是不斷變化的。 為了實現(xiàn)游戲畫面的刷新,通常是利用緩存設(shè)備上下文來保存下一幀的合成位圖對象。 下一幀的合成位圖對象是根據(jù)角色位圖的實時位置和狀態(tài)重新渲染后的結(jié)果。,下面舉例給出了利用GDI實現(xiàn)位圖繪圖的主要步驟: 定義windows屏幕設(shè)備句柄變量windowDC; 定義窗口緩沖設(shè)備句柄變量bufferDC; 定義一個位圖內(nèi)存設(shè)備句柄變量
27、picDC; 定義一個位圖句柄變量picBMP; 定義一個緩沖位圖句柄變量bufferBMP; 調(diào)用GetDC()獲取當(dāng)前整個屏幕設(shè)備的句柄值,賦給windowDC; 調(diào)用CreateCompatibleDC()創(chuàng)建與windowDC兼容的內(nèi)存設(shè)備,并將其句柄值賦給位圖內(nèi)存設(shè)備變量picDC。 調(diào)用CreateCompatibleDC()創(chuàng)建與windowDC兼容的內(nèi)存設(shè)備,并其句柄值賦給窗口緩沖設(shè)備變量bufferDC。 調(diào)用CreateCompatibleBitmap()創(chuàng)建與windowDC兼容的位圖對象,并將該位圖的句柄值賦給bufferBMP。 調(diào)用LoadBitmap()加載指定位
28、圖資源,并獲取給該位圖資源的句柄值,賦給picBMP。 調(diào)用SelectObject()將緩沖位圖句柄bufferBMP和窗口緩沖設(shè)備句柄bufferDC關(guān)聯(lián)。 調(diào)用SelectObject()將位圖句柄picBMP和位圖內(nèi)存設(shè)備picDC關(guān)聯(lián)。 兩次調(diào)用特定運算的BitBlt()函數(shù)來對位圖內(nèi)存設(shè)備picDC中的位圖進行“去背”處理后,把結(jié)果保存在窗口緩沖設(shè)備bufferDC中。 調(diào)用BitBlt()函數(shù)將窗口緩沖設(shè)備中的全部圖像內(nèi)容拷貝到屏幕設(shè)備windowDC上顯示。,GetDC()函數(shù),函數(shù)功能:該函數(shù)檢索一指定窗口的客戶區(qū)域或整個屏幕的顯示設(shè)備上下文環(huán)境的句柄,以后可以在GDI函數(shù)中
29、使用該句柄來在設(shè)備上下文環(huán)境中繪圖。 函數(shù)原型:HDC GetDC(HWND hWnd); 參數(shù): hWnd:設(shè)備上下文環(huán)境被檢索的窗口的句柄,如果該值為NULL,GetDC則檢索整個屏幕的設(shè)備上下文環(huán)境。 返回值:如果成功,返回指定窗口客戶區(qū)的設(shè)備上下文環(huán)境;如果失敗,返回值為Null。,CreateCompatibleDC()函數(shù),函數(shù)功能:該函數(shù)創(chuàng)建一個與指定設(shè)備兼容的內(nèi)存設(shè)備上下文環(huán)境(DC)。 函數(shù)原型:HDC CreateCompatibleDC(HDC hdc); 參數(shù): hdc:現(xiàn)有設(shè)備上下文環(huán)境的句柄,如果該句柄為NULL,該函數(shù)創(chuàng)建一個與應(yīng)用程序的當(dāng)前顯示器兼容的內(nèi)存設(shè)備上
30、下文環(huán)境。 返回值:如果成功,則返回內(nèi)存設(shè)備上下文環(huán)境的句柄;如果失敗,則返回值為NULL。,CreateCompatibleBitmap()函數(shù),函數(shù)功能:該函數(shù)創(chuàng)建與指定的設(shè)備環(huán)境相關(guān)的設(shè)備兼容的位圖。 函數(shù)原型:HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight); 參數(shù): hdc: 設(shè)備環(huán)境句柄。 nWidth:指定位圖的寬度,單位為像素。 nHeight:指定位圖的高度,單位為像素。 返回值:如果函數(shù)執(zhí)行成功,那么返回值是位圖的位圖句柄;如果函數(shù)執(zhí)行失敗,那么返回值為NULL。,LoadBitmap()函數(shù),函數(shù)
31、功能:該函數(shù)從模塊的可執(zhí)行文件中加載指定的位圖資源。 函數(shù)原型:HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName); 參數(shù): hlnstance:指向模塊實例的句柄。 lpBitmapName:指向字符串指針。該字符串包含了要加載的位圖資源名稱。 返回值:如果函數(shù)執(zhí)行成功,則返回值是指向指定位圖的位圖句柄。如果函數(shù)執(zhí)行失敗,那么返回值是NULL。,SelectObject()函數(shù),函數(shù)功能:該函數(shù)選擇一對象到指定的設(shè)備上下文環(huán)境中。 函數(shù)原型:HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hg
32、diobj); 參數(shù): hdc:設(shè)備上下文環(huán)境的句柄。 hgdiobj:被選擇的對象的句柄,這些對象包括位圖、畫刷、字體、筆、區(qū)域等。 返回值:如果選擇對象不是區(qū)域并且函數(shù)執(zhí)行成功,那么返回值是對象的句柄。,BitBlt()函數(shù),函數(shù)功能:該函數(shù)對指定的源設(shè)備環(huán)境區(qū)域中的像素進行位塊轉(zhuǎn)換,并傳送到目標(biāo)設(shè)備環(huán)境。 函數(shù)原型:BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop); 參數(shù): hdcDest:指向目標(biāo)設(shè)備環(huán)境的句柄。
33、 nXDest:指定目標(biāo)矩形區(qū)域左上角的X軸邏輯坐標(biāo)。 nYDest:指定目標(biāo)矩形區(qū)域左上角的Y軸邏輯坐標(biāo)。 nWidth:指定源和目標(biāo)矩形區(qū)域的邏輯寬度。 nHeight:指定源和目標(biāo)矩形區(qū)域的邏輯高度。 hdcSrc:指向源設(shè)備環(huán)境的句柄。 nXSrc:指定源矩形區(qū)域左上角的X軸邏輯坐標(biāo)。 nYSrc:指定源矩形區(qū)域左上角的Y軸邏輯坐標(biāo)。 dwRop:指定光柵操作代碼。這些代碼將定義源矩形區(qū)域的顏色數(shù)據(jù),如何與目標(biāo)矩形區(qū)域的顏色數(shù)據(jù)運算以完成最后的顏色。,常見的光柵操作代碼( dwRop ),SRCCOPY:將源矩形區(qū)域直接拷貝到目標(biāo)矩形區(qū)域。 SRCAND:通過使用AND(與)操作符來將
34、源和目標(biāo)矩形區(qū)域內(nèi)的顏色合并。 SRCPAINT:通過使用布爾型的OR(或)操作符將源和目標(biāo)矩形區(qū)域的顏色合并。 WHITENESS:使用與物理調(diào)色板中索引1有關(guān)的顏色填充目標(biāo)矩形區(qū)域。(對于缺省物理調(diào)色板來說,這個顏色就是白色)。 BLACKNESS:表示使用與物理調(diào)色板的索引0相關(guān)的色彩來填充目標(biāo)矩形區(qū)域,(對缺省的物理調(diào)色板而言,該顏色為黑色)。 DSTINVERT:表示使目標(biāo)矩形區(qū)域顏色取反。 MERGECOPY:表示使用布爾型的AND(與)操作符將源矩形區(qū)域的顏色與特定模式組合一起。 MERGEPAINT:通過使用布爾型的OR(或)操作符將反向的源矩形區(qū)域的顏色與目標(biāo)矩形區(qū)域的顏色合
35、并。 NOTSRCCOPY:將源矩形區(qū)域顏色取反,于拷貝到目標(biāo)矩形區(qū)域。 NOTSRCERASE:使用布爾類型的OR(或)操作符組合源和目標(biāo)矩形區(qū)域的顏色值,然后將合成的顏色取反。,計算機中的GRB顏色,在計算機中,使用的是數(shù)字圖像處理,每一種顏色都是由RGB表示的,RGB是指紅(RED)、綠(GREEN)、藍(lán)(BLUE)三原色。 RGB顏色值是紅綠藍(lán)3種顏色的強度,每個原色的GRB顏色值的取值范圍為0(#00)255(#FF)。 RGB 16進制顏色值即是紅綠藍(lán)三原色各自16進制顏色值的組合。如(255,255,255)的16進制顏色值為#FFFFFF。 舉例: 白色是三原色值均為最大時混合
36、成的的顏色,所以顏色表示為(255,255,255),16進制就用#FFFFFF表示。 黑色是三原色值均為最小時混合成的的顏色,所以顏色表示為(0,0,0),16進制就用#000000表示。,在數(shù)字圖像處理中可以實現(xiàn)OR、AND等邏輯運算。運算規(guī)律如下: 任何顏色同白色(#FFFFFF)進行OR運算結(jié)果都為白色,進行AND運算結(jié)果都是該顏色本身。 任何顏色同黑色(#000000)進行OR運算結(jié)果都為該顏色本身,進行AND運算結(jié)果都是黑色。 例如,可以進行對圖1所示的位圖進行去“背景色”的處理: 首先將“圖2”位圖同目標(biāo)地顏色進行“或”(OR)運算,得到的結(jié)果是:“圖2”白色處為白色,其他處為目
37、標(biāo)地顏色。 再將“圖1”位圖同目標(biāo)地顏色進行“與”(AND)運算,得到的結(jié)果是:“圖1”位圖水果處為原顏色,而其他處為目標(biāo)地顏色,從而達(dá)到了精確“去背”的效果。,圖1,圖2,假設(shè),圖1所示的尺寸為160px80px,hdc為內(nèi)存句柄,picDC為該位圖的內(nèi)存位圖句柄。則: 以下兩條語句會達(dá)到的效果:在屏幕(x_pos,y_pos)上顯示“蛇頭朝上”位圖”: BitBlt(hdc,x_pos,y_pos,20,20,picDC,80,20,SRCPAINT);/或運算 BitBlt(hdc,x_pos,y_pos,20,20,picDC,0,20,SRCAND);/與運算 以下兩條語句會會達(dá)到的
38、效果:在屏幕(x_pos,y_pos)上顯示“蛇頭朝下”位圖: BitBlt(hdc,x_pos,y_pos,20,20,picDC,140,20,SRCPAINT); BitBlt(hdc,x_pos,y_pos,20,20,picDC,60,20,SRCAND);,圖1,實現(xiàn)位圖繪圖的核心代碼, HDC windowDC = NULL; /windows屏幕設(shè)備 HDC bufferDC = NULL; /緩沖設(shè)備環(huán)境 HDC picDC=NULL; /位圖內(nèi)存設(shè)備 HBITMAP picBMP = NULL; /位圖句柄 HBITMAP bufferBMP = NULL; /緩沖位圖句柄
39、 windowDC=GetDC(NULL); bufferDC=CreateCompatibleDC(windowDC); picDC=CreateCompatibleDC(windowDC); /g_iClientWidth,g_iClientHeight分別是窗口的寬和高。 bufferBMP=CreateCompatibleBitmap(windowDC,g_iClientWidth,g_iClientHeight); picBMP=(HBITMAP)LoadImage(NULL,snake.bmp,IMAGE_BITMAP,160,80,LR_LOADFROMFILE); Select
40、Object(bufferDC,bufferBMP);/將窗口的初始畫面位圖選入緩沖DC SelectObject(picDC,picBMP);/將角色位圖選入選入角色位圖DC BitBlt(bufferDC,x_pos,y_pos,20,20,picDC,80,20,SRCPAINT);/或運算 BitBlt(bufferDC,x_pos,y_pos,20,20,picDC,0,20,SRCAND);/與運算 /將整個畫面從緩沖DC拷貝出屏幕 BitBlt(windowDC,0,0,g_iClientWidth,g_iClientHeight,bufferDC,0,0,SRCCOPY);,4
41、.游戲?qū)嵗饰?分析:貪吃蛇游戲是一個深受人們喜愛的游戲,一條蛇在密閉的圍墻內(nèi)沿當(dāng)前方向移動,在圍墻內(nèi)不斷隨機出現(xiàn)水果和毒果。 玩家通過按鍵盤上的四個光標(biāo)鍵控制蛇頭向上下左右四個方向移動, 如果蛇頭吃到水果,蛇的身體長一節(jié),分?jǐn)?shù)加100分。 如果蛇頭撞到墻壁或蛇頭觸碰到其身體或吃到毒果,游戲結(jié)束。,程序的要點:,用一個小矩形塊表示蛇的一節(jié)身體,身體每長一節(jié),增加一個矩形塊。 移動時必須從蛇頭開始,所以蛇不能向相反方向移動。 如不按任何鍵,蛇自行在當(dāng)前方向上前移。 當(dāng)游戲者按了有效的方向鍵后,蛇頭朝著指定的方向移動,一步移動一節(jié)身體,所以當(dāng)按了有效的方向鍵后,先確定蛇頭的位置,然后蛇身體隨著蛇頭
42、移動,圖形的實現(xiàn)是從蛇頭的新位置開始畫出蛇。 根據(jù)以上分析,設(shè)計了兩個類:CTable類、CSnack類。,主要基本數(shù)據(jù)結(jié)構(gòu)及常量的定義(1),/節(jié)點圖像顯示運動狀態(tài)(方向) enum BitmapState M_NONE,M_UP_UP,M_DOWN_DOWN, M_LEFT_LEFT,M_RIGHT_RIGHT,M_UP_LEFT,M_UP_RIGHT, M_LEFT_UP,M_LEFT_DOWN,M_RIGHT_UP,M_RIGHT_DOWN, M_DOWN_RIGHT,M_DOWN_LEFT ; /節(jié)點運動狀態(tài)(方向) enum MoveStateS_NONE,S_UP,S_DOWN,
43、S_LEFT,S_RIGHT; /坐標(biāo)位置結(jié)構(gòu) struct SPoint int x; int y; ; #define TB_STATE_OK 0 /正常 #define TB_STATE_FOOD 1 /食物 #define TB_STATE_BLOCK 2 /障礙毒果 #define TB_STATE_SBLOCK 3 /障礙墻,主要基本數(shù)據(jù)結(jié)構(gòu)及常量的定義(2),/游戲狀態(tài)定義 #define GAME_STATE_WAIT 0 /游戲等待狀態(tài) #define GAME_STATE_RUN 1 /游戲運行狀態(tài) #define GAME_STATE_END 2 /游戲結(jié)束狀態(tài) /界面相
44、關(guān)物件尺寸定義 #define WALL_WIDTH 80 /外墻從左部到游戲區(qū)的寬度 #define WALL_HEIGHT 80 /外墻從頂部到游戲區(qū)的高度 #define BMP_SCORE_BOARD_WIDTH 256 /分?jǐn)?shù)位圖板的寬度 #define BMP_SCORE_BOARD_HEIGHT 55 /分?jǐn)?shù)位圖板的高度 #define BMP_WALL_WIDTH 16 /墻位圖的寬度 #define BMP_WALL_HEIGHT 16 /墻位圖的高度,class CSnake struct Snake_Struct/定義蛇體狀態(tài) MoveState head; /頭部 Mo
45、veState *body; /身體 MoveState tail; /尾部 ; private:int m_length; /蛇的長度 Snake_Struct m_newSnake; /蛇的新態(tài)的所有節(jié)點運動狀態(tài) Snake_Struct m_oldSnake; /蛇的原態(tài)的所有節(jié)點運動狀態(tài) BitmapState *m_pStateArray; /蛇的所有節(jié)點顯示位圖的狀態(tài) SPoint *m_pPos; /蛇體坐標(biāo) private:BitmapState GetRightState(MoveState oldDirect,MoveState newDirect);/根據(jù)新舊兩個身體的運
46、動趨勢情況,返回當(dāng)前應(yīng)當(dāng)顯示的身體狀態(tài) public:void Move(void); void ChangeDirect(MoveState d); /改變方向,條件:非對立方向 void AddBody(int n=1);/蛇的身體增長 void SetHeadPos(int x,int y);/設(shè)置蛇頭的坐標(biāo) BitmapState* GetStateArray(void);/取蛇的狀態(tài)標(biāo)識數(shù)組 SPoint* GetPos(void);/取蛇的位置數(shù)組 bool IsHeadTouchBody(int x,int y);/檢測蛇頭是否觸碰到其身體 int GetLength( void
47、 );/取蛇身的長度 void Initial( void ); /初始化 用作游戲結(jié)束后重新開始 public:CSnake(int x_pos=0,int y_pos=0,int len=1); CSnake(); ;,class CTable private: int m_width; /桌子的寬度 int m_height; /桌子的高度 int m_foodNumber; /水果的數(shù)目 int m_blockNumber; /障礙物(毒果)的數(shù)目 CSnake m_snake; /桌子上的蛇 int *m_board; /桌子面板,二維數(shù)組 public: CTable(); CTa
48、ble(); void InitialTable(int w,int h); /初始化桌子面板 bool AddBlock(int x,int y); / 在某個位置放置毒果 bool AddFood(int x,int y); / 在某個位置放置水果 bool ClearFood(int x,int y);/清除某個位置的果實 CSnake* GetSnake(void);/ 獲取蛇對象 int* GetBoard(void); / 取桌子對象 int GetData(int x,int y);/ 取桌子某個位置數(shù)據(jù) void SnakeMove(void);/ 蛇的移動 bool Chan
49、geSnakeDirect(MoveState d);/ 改變蛇的方向 ;,主程序(main.cpp)中的全局變量,CTable table; /創(chuàng)建一個桌子 int tableBlockWidth = 0; /桌子的格子的寬度 int tableBlockHeight = 0; /桌子的格子的高度 int iScores = 0; /游戲的得分 UINT uGameState = GAME_STATE_WAIT; /當(dāng)前游戲狀態(tài) HDC windowDC = NULL; /windows屏幕設(shè)備 HDC bufferDC = NULL; /緩沖設(shè)備環(huán)境 HDC picDC = NULL; /
50、snake圖像內(nèi)存設(shè)備 HDC endDC = NULL; /游戲終結(jié)圖像內(nèi)存設(shè)備 HDC scoreDC = NULL; /分?jǐn)?shù)板內(nèi)存設(shè)備 HWND hAppWnd = NULL; /本application窗口句柄 HBITMAP picBMP = NULL; /snake圖像位圖句柄 HBITMAP bufferBMP = NULL; /緩沖位圖句柄 HBITMAP endBMP = NULL; /游戲終結(jié)圖像內(nèi)存句柄 HBITMAP hbmpWall = NULL; /墻位圖句柄 HBITMAP hbmpScore = NULL; /分?jǐn)?shù)板位圖句柄 HBRUSH hbrushWall
51、= NULL; /墻畫刷 UINT uSnakeMoveTimer; /蛇移動的定時器標(biāo)識 UINT uFoodAddTimer; /水果產(chǎn)生的定時器標(biāo)識 /框架的位置數(shù)據(jù)定義 RECT g_ClientRect; RECT g_GameValueRect; int g_iClientWidth; int g_iClientHeight;,int WINAPI WinMain(HINSTANCE hCurrentInst,HINSTANCE hPrevInstance, PSTR lpszCmdLine,int nCmdShow) WNDCLASS wndClass; HWND hWnd; M
52、SG msg; UINT width,height; /定義窗口 wndClass.style=CS_HREDRAW | CS_VREDRAW; wndClass.lpszClassName=Snake_CLASS; /注冊窗口 RegisterClass(,WinMain()方法 -(1),WinMain()方法 -(2),/獲取窗體大小 GetClientRect(hAppWnd, ,WinMain()方法 -(3),/聲明位圖與設(shè)備環(huán)境的關(guān)聯(lián) SelectObject(bufferDC,bufferBMP); SelectObject(picDC,picBMP); SelectObjec
53、t(endDC,endBMP); SelectObject(scoreDC,hbmpScore); /建立畫刷與其名相對應(yīng)的圖像的關(guān)聯(lián), /以備用刷子將墻刷出來,用PatBlt()實現(xiàn) hbrushWall = CreatePatternBrush(hbmpWall); StartGame(); while(GetMessage( ,WndProc()方法-(1),LRESULT CALLBACK WndProc(HWND hWnd,UINT message, WPARAM wParam,LPARAM lParam) switch(message) case WM_TIMER : OnTime
54、r(UINT)wParam); break; case WM_KEYDOWN: switch(wParam) case VK_ESCAPE: exit(0);break; case VK_UP: table.ChangeSnakeDirect(S_UP);break; case VK_DOWN: table.ChangeSnakeDirect(S_DOWN); break; case VK_LEFT: table.ChangeSnakeDirect(S_LEFT); break; case VK_RIGHT:table.ChangeSnakeDirect(S_RIGHT); break; ca
55、se VK_SPACE: if(uGameState = GAME_STATE_END ) StartGame(); break; return 0;,WndProc()方法-(2),case WM_SETCURSOR: SetCursor(NULL); return 0; case WM_DESTROY: ReleaseDC(hWnd,picDC); ReleaseDC(hWnd,bufferDC); ReleaseDC(hWnd,windowDC); PostQuitMessage(0); return 0; return DefWindowProc(hWnd,message,wParam
56、,lParam); ,void StartGame() iScores=0; /桌面的初始化 table.InitialTable(tableBlockWidth,tableBlockHeight); table.GetSnake()-ChangeDirect(S_RIGHT); table.GetSnake()-SetHeadPos(tableBlockWidth/2,tableBlockHeight/2); /預(yù)先隨機產(chǎn)生幾個食物 srand( (unsigned)time(NULL) ); for(int iFoodNum=0; iFoodNum4; iFoodNum+) table.A
57、ddFood(rand()%tableBlockWidth,(rand()%tableBlockHeight); /打開定時器 uSnakeMoveTimer = SetTimer(hAppWnd,500,100,NULL); uFoodAddTimer = SetTimer(hAppWnd,600,7000,NULL); uGameState = GAME_STATE_RUN; ,void OnTimer(UINT uTIMER_ID) if ( uTIMER_ID = uSnakeMoveTimer ) table.SnakeMove(); /移動蛇 /檢測是否碰到身體(環(huán)繞),結(jié)束游戲
58、if(table.GetSnake()-IsHeadTouchBody(table.GetSnake()-GetPos()0.x,table.GetSnake()-GetPos()0.y) EndGame(); /根據(jù)蛇頭所在的區(qū)域作出相應(yīng)的處理 switch(table.GetData(table.GetSnake()-GetPos()0.x,table.GetSnake()-GetPos()0.y) case TB_STATE_FOOD: table.ClearFood(table.GetSnake()-GetPos()0.x,table.GetSnake()-GetPos()0.y); table.AddBlock(rand()%tableBlockWidth,(rand()%tableBlockHeight); table.GetSnake()-AddBody(); +iScores; break; case TB_STATE_BLOCK: case TB_ST
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年高職種子生產(chǎn)與經(jīng)營(種子加工技術(shù))試題及答案
- 2025年中職(新能源汽車技術(shù))新能源汽車概論實務(wù)試題及答案
- 2025年中職商務(wù)助理(公文寫作)試題及答案
- 2025年大學(xué)植物學(xué)(應(yīng)用實操)試題及答案
- 2025年大學(xué)生物(微生物基礎(chǔ))試題及答案
- 2025年大學(xué)石油煉制生產(chǎn)操作(操作規(guī)范)試題及答案
- 2025年大學(xué)環(huán)境工程(環(huán)境工程施工)試題及答案
- 2025年中職無人機駕駛(植保)(植保作業(yè)操作)試題及答案
- 養(yǎng)老院老人請假制度
- 養(yǎng)老院老人生活娛樂活動組織人員職業(yè)發(fā)展規(guī)劃制度
- 設(shè)計質(zhì)量、進度、保密等保證措施
- 《電力建設(shè)工程施工安全管理導(dǎo)則》(NB∕T 10096-2018)
- 2024年黑龍江省哈爾濱市中考語文試題
- 《底層邏輯》劉潤
- 幼兒園《企鵝遇險記》原繪本故事
- 多波多分量地震勘探規(guī)范
- (高清版)TDT 1057-2020 國土調(diào)查數(shù)據(jù)庫標(biāo)準(zhǔn)
- 管道工培訓(xùn)課件
- 2024版未來食品加工技術(shù)趨勢:智能化與自動化培訓(xùn)課件
- 無人機測繪操控員培訓(xùn)計劃及大綱
- 動角問題專項訓(xùn)練(30道)
評論
0/150
提交評論