已閱讀5頁,還剩69頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
VC+win32API游戲開發(fā),主講教師:李璟聯(lián)系電話-mail:lijing,VC+win32API游戲開發(fā),1.Windows編程2.Windows應(yīng)用程序的組成與編程3.游戲?qū)崿F(xiàn)原理與WindowGDI繪圖4.游戲?qū)嵗钠饰?1.Windows編程,1.1WindowsAPI編程基礎(chǔ)1.2窗口1.3事件驅(qū)動1.4句柄1.5消息1.6Windows應(yīng)用程序的常用消息,1.1WindowsAPI編程基礎(chǔ),Windows編程的方法主要有兩種方法:傳統(tǒng)編寫法:利用API函數(shù)。交互式方法:利用MFC類庫。為使程序員編寫具有Windows風(fēng)格的應(yīng)用程序,Windows提供了一個應(yīng)用程序編程接口(ApplicationProgrammingInterface,簡稱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,MicrosoftFoundationClassLibrary,微軟基礎(chǔ)類庫,約有200個類。MFC封裝了大部分API函數(shù),并提供了一個應(yīng)用程序框架,簡化了和標(biāo)準(zhǔn)了windows程序設(shè)計(jì)。但WindowsAPI編程方法始終是windows編程的基礎(chǔ)。,1.2窗口,編寫一個Windows應(yīng)用程序首先應(yīng)創(chuàng)建一個或多個窗口,而后應(yīng)用程序的運(yùn)行過程即是窗口內(nèi)部、窗口與窗口之間、窗口與系統(tǒng)之間進(jìn)行數(shù)據(jù)處理與數(shù)據(jù)交換的過程。,1.3事件驅(qū)動,Windows程序設(shè)計(jì)是針對事件或消息的,它的執(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對象的把柄。Windows中的句柄都是32位的指針變量,用來指向某個windows對象所占據(jù)的內(nèi)存區(qū)。句柄的使用,極大地方便了Windows管理其內(nèi)存中的各種windows對象。,常用句柄類型及其說明,1.5消息,消息是描述事件發(fā)生的信息。Windows應(yīng)用程序通過消息進(jìn)行信息交換。在Windows中,消息用結(jié)構(gòu)體MSG表示,其結(jié)構(gòu)如下:TypedefstructtagMSGHWNDhwnd;/窗口句柄UNITmessage;/消息號。WPARAMwParam;/用于提供消息的附加消息。LPARAMlParam;/用于提供消息的附加消息。DWORDtime;/指定消息送至隊(duì)列的時間POINTpt;/指定消息發(fā)送時屏幕光標(biāo)的位置MSG;,VC+中存在幾種系統(tǒng)定義的消息分類,不同的前綴符號經(jīng)常用于識別消息的分類,如下表所示:,1.6Windows應(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)閉窗口時產(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.4windows應(yīng)用程序的常用數(shù)據(jù)類型2.5API編程實(shí)例,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語言中的Main函數(shù),是Win32應(yīng)用程序入口函數(shù)。WinMain()函數(shù)主要完成創(chuàng)建主窗口,并產(chǎn)生和處理消息循環(huán)。,WinMain()函數(shù),因?yàn)閣indows是多任務(wù)系統(tǒng),所以同一應(yīng)用程序的多個窗口可能會同時存在。windows系統(tǒng)對每個窗口的執(zhí)行稱為一個實(shí)例,用一個實(shí)例句柄來唯一標(biāo)識。WinMain()函數(shù)與DOS程序的main()函數(shù)起同樣的作用,有一點(diǎn)不同的是,WinMain()函數(shù)必須帶有四個參數(shù),它們是系統(tǒng)傳遞給它的。WinMain()函數(shù)的原型如下:intPASCALWinMain(HINSTANCEhInstance,/當(dāng)前實(shí)例句柄HINSTANCEhPrevInstance,/前一個實(shí)例句柄LPSTRlpCmdLine,/命令行字符intnCmdShow)/窗口顯示方式,WinMain()函數(shù),第一個參數(shù)hInstance,是標(biāo)識該應(yīng)用程序當(dāng)前實(shí)例的句柄。第二個參數(shù)是hPrevInstance,它是用來標(biāo)識該應(yīng)用程序的前一個實(shí)例的句柄。第三個參數(shù)是lpCmdLine,是指向應(yīng)用程序命令行參數(shù)字符串的指針。最后一個參數(shù)是nCmdShow,是一個用來指定窗口顯示方式的整數(shù)。這個整數(shù)值可以是SW_SHOW、SW_HIDE、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED等。,WinMain()函數(shù)主要由2部分組成:窗口初始化消息循環(huán),窗口初始化包括以下主要步驟:,定義窗口類:通過給窗口類數(shù)據(jù)結(jié)構(gòu)WINDCLASS賦值,設(shè)置窗口類的各種屬性。如窗口邊框、窗口標(biāo)題欄文字、窗口大小和位置、鼠標(biāo)、背景色等。注冊窗口類:Win系統(tǒng)本身提供部分預(yù)定義的窗口類,程序員也可以自定義窗口類。窗口類必須先注冊后使用。窗口類的注冊由函數(shù)RegisterClass()實(shí)現(xiàn)。創(chuàng)建窗口實(shí)例:創(chuàng)建窗口類的實(shí)例由CreateWindows()函數(shù)實(shí)現(xiàn)。窗口顯示:窗口類的顯示是由ShowWindows()函數(shù)和UpdateWindows()函數(shù)實(shí)現(xiàn)的。ShowWindows()函數(shù):應(yīng)用程序通過調(diào)用ShowWindows()函數(shù)在屏幕上顯示窗口。UpdateWindows()函數(shù):顯示窗口后,應(yīng)用程序調(diào)用UpdateWindow更新并繪制用戶區(qū),并發(fā)出WM_PAINT消息。,消息循環(huán),Windows為當(dāng)前執(zhí)行的每個Windows程序維護(hù)一個消息隊(duì)列。在發(fā)生輸入事件之后,Windows將事件轉(zhuǎn)換為一個消息并將消息放入程序的消息隊(duì)列中。程序通過執(zhí)行一塊稱之為消息循環(huán)的程序代碼從消息隊(duì)列中取出消息。以下是WinMain()函數(shù)中消息循環(huán)的代碼:/消息循環(huán)以調(diào)用GetMessage()開始,它從消息隊(duì)列中取出/一個消息while(GetMessage(,WinMain()函數(shù)的大致結(jié)構(gòu),intPASCALWinMain()/定義窗口類:WNDCLASSwndclass;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)用程序接收到一個消息時,相應(yīng)的case語句被激活并執(zhí)行相應(yīng)的響應(yīng)程序模塊。窗口消息處理程序不予處理的所有消息被傳給名為DefWindowProc的Windows函數(shù)進(jìn)行默認(rèn)處理。,消息處理函數(shù)WndProc的大致結(jié)構(gòu),LRESULTCALLBACKWndProc(HWNDhMainwnd,UINTmessage,WPARAMwParam,LPARAMlParam)/窗口函數(shù)的定義switch(message)caseWM_KEYDOWN:/擊鍵消息;break;case:;break;caseWM_DESTROY:/關(guān)閉應(yīng)用程序窗口時發(fā)出的消息PostQuitMessage(0);/發(fā)出WM_QUIT消息,結(jié)束應(yīng)用程序return0;default:break;/調(diào)用缺省消息處理過程returnDefWindowProc(hMainwnd,message,wParam,lParam);,2.4windows應(yīng)用程序的常用數(shù)據(jù)類型,所有的Windows應(yīng)用程序中,都有一個程序初始化的過程。下面以一個實(shí)現(xiàn)最簡單功能的程序WinApiDemo為例,說明Windows程序的基本框架。操作步驟如下:(1)打開VisualC+6.0。選擇File菜單的New,在出現(xiàn)的對話框中,選擇Projects欄目(新建工程),并點(diǎn)取其下的Win32Application項(xiàng),表示使用Win32環(huán)境創(chuàng)建應(yīng)用程序。(2)在Locatin(路徑)中填入工程的路徑,然后在ProjectName(項(xiàng)目名稱)中填入“WinApiDemo”,其它按照缺省設(shè)置,單擊OK按鈕。(3)選擇File菜單的New,在出現(xiàn)的對話框中,選擇Files欄目(新建文件),并點(diǎn)取其下的C+SourceFile項(xiàng),表示新建一個C+源文件。在右邊的File欄中輸入“WinApiDemo”,最后確定讓Addtoproject檢查框打上勾,單擊OK按鈕。(4)在“WinApiDemo.cpp”文件中輸入以下程序代碼。,2.5API編程實(shí)例,WinApiDemo.cpp源代碼(1),#include/頭文件LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);/窗口函數(shù)聲明,這一函數(shù)將處理發(fā)往應(yīng)用程序窗口的各種消息charszClassName=windowclass;/窗口結(jié)構(gòu)體的名稱charszAppTitle=API建立窗口實(shí)例;/窗口的標(biāo)題INTPASCALWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpszCmdParam,INTnCmdShow)/WinMain()函數(shù)的定義HWNDhMainWnd;/窗口句柄MSGmsg;/消息結(jié)構(gòu)體WNDCLASSwinclass;/窗口結(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ū)嵗浔鷚inclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);/窗口圖標(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()函數(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_SHOWNORMAL);/顯示最大化窗口UpdateWindow(hMainWnd);/更新窗口/下面用While()循環(huán)來建立消息循環(huán)while(GetMessage(,WinApiDemo.cpp源代碼(3),LRESULTCALLBACKWndProc(HWNDhMainwnd,UINTmessage,WPARAMwParam,LPARAMlParam)/窗口函數(shù)的定義switch(message)caseWM_KEYDOWN:/擊鍵消息MessageBox(hMainwnd,鍵按下了!,Keyboard,MB_OK);break;caseWM_RBUTTONDOWN:/鼠標(biāo)消息MessageBox(hMainwnd,鼠標(biāo)右鍵按下了!,Mouse,MB_OK);break;caseWM_LBUTTONDOWN:/鼠標(biāo)消息MessageBox(hMainwnd,鼠標(biāo)左鍵按下了!,Mouse,MB_OK);break;caseWM_DESTROY:/關(guān)閉應(yīng)用程序窗口時發(fā)出的消息PostQuitMessage(0);/發(fā)出WM_QUIT消息,結(jié)束應(yīng)用程序return0;default:break;/調(diào)用缺省消息處理過程returnDefWindowProc(hMainwnd,message,wParam,lParam);,WinApiDemo.cpp源代碼(4),caseWM_RBUTTONDOWN:MessageBox(GetFocus(),messageright,API建立窗口實(shí)例,MB_OK|MB_ICONINFORMATION);break;caseWM_LBUTTONDOWN:MessageBox(GetFocus(),messageleft,API建立窗口實(shí)例,MB_OK|MB_ICONINFORMATION);break;caseWM_DESTROY:/關(guān)閉應(yīng)用程序窗口時發(fā)出的消息PostQuitMessage(0);/發(fā)出WM_QUIT消息,結(jié)束應(yīng)用程序return0;default:break;returnDefWindowProc(hMainwnd,message,wParam,lParam);/其它沒有處理的消息交給Windows做默認(rèn)處理,WinApiDemo的運(yùn)行畫面,3.游戲?qū)崿F(xiàn)原理與WindowGDI繪圖,3.1游戲?qū)崿F(xiàn)的基本原理3.2WindowGDI基本概念3.3利用GDI實(shí)現(xiàn)游戲中的繪圖,3.1游戲?qū)崿F(xiàn)的基本原理,3.2WindowGDI基本概念,GDI,GraphicsDeviceInterface,即圖形設(shè)備接口,是WindowsAPI的一個重要組成部分。GDI是Windows圖形顯示程序與實(shí)際物理設(shè)備之間的橋梁,GDI使得用戶無需關(guān)心具體設(shè)備的細(xì)節(jié),而只需在一個虛擬的環(huán)境(即邏輯設(shè)備)中進(jìn)行操作。GDI用一套通用的圖形對象來向屏幕,內(nèi)存甚至是打印機(jī)繪圖。,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、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è)備上下文(DC)展開。設(shè)備上下文,DeviceContext,簡稱DC,是Windows使用的一種結(jié)構(gòu),所有GDI操作前都需取得特定設(shè)備的上下文。設(shè)備上下文的句柄是HDC。HDC是一個你可以向其繪圖的句柄;它可以代表整個屏幕,一個窗口的客戶區(qū)域,一個存在內(nèi)存中的位圖,或是一個打印機(jī)。例如,如果你想在一個窗口上繪圖,首先你要用GetDC()來獲取代表這個窗口的HDC,然后你就可以用任何以HDC為參數(shù)的GDI函數(shù)來繪圖了。,位圖,位圖可以用LoadBitmap()來完成大多數(shù)的基本操作,比如簡單地裝入一個位圖資源。GDI不能直接用位圖對象來繪圖,因?yàn)槔L圖操作已經(jīng)被設(shè)備上下文抽象了,只能通過設(shè)備上下文來繪制位圖。利用位圖繪圖的大體思路是:把位圖對象裝入設(shè)備上下文,通過設(shè)備上下文把位圖顯示在屏幕上。,3.3利用GDI實(shí)現(xiàn)游戲中的繪圖,游戲中的繪圖主要通過是繪制位圖來實(shí)現(xiàn)的。在游戲中,因?yàn)榻巧粓D的位置是不斷變化的,所以設(shè)備上下文中的合成位圖的內(nèi)容也是不斷變化的。為了實(shí)現(xiàn)游戲畫面的刷新,通常是利用緩存設(shè)備上下文來保存下一幀的合成位圖對象。下一幀的合成位圖對象是根據(jù)角色位圖的實(shí)時位置和狀態(tài)重新渲染后的結(jié)果。,下面舉例給出了利用GDI實(shí)現(xiàn)位圖繪圖的主要步驟:定義windows屏幕設(shè)備句柄變量windowDC;定義窗口緩沖設(shè)備句柄變量bufferDC;定義一個位圖內(nèi)存設(shè)備句柄變量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()加載指定位圖資源,并獲取給該位圖資源的句柄值,賦給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)用特定運(yùn)算的BitBlt()函數(shù)來對位圖內(nèi)存設(shè)備picDC中的位圖進(jìn)行“去背”處理后,把結(jié)果保存在窗口緩沖設(shè)備bufferDC中。調(diào)用BitBlt()函數(shù)將窗口緩沖設(shè)備中的全部圖像內(nèi)容拷貝到屏幕設(shè)備windowDC上顯示。,GetDC()函數(shù),函數(shù)功能:該函數(shù)檢索一指定窗口的客戶區(qū)域或整個屏幕的顯示設(shè)備上下文環(huán)境的句柄,以后可以在GDI函數(shù)中使用該句柄來在設(shè)備上下文環(huán)境中繪圖。函數(shù)原型:HDCGetDC(HWNDhWnd);參數(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ù)原型:HDCCreateCompatibleDC(HDChdc);參數(shù):hdc:現(xiàn)有設(shè)備上下文環(huán)境的句柄,如果該句柄為NULL,該函數(shù)創(chuàng)建一個與應(yīng)用程序的當(dāng)前顯示器兼容的內(nèi)存設(shè)備上下文環(huán)境。返回值:如果成功,則返回內(nèi)存設(shè)備上下文環(huán)境的句柄;如果失敗,則返回值為NULL。,CreateCompatibleBitmap()函數(shù),函數(shù)功能:該函數(shù)創(chuàng)建與指定的設(shè)備環(huán)境相關(guān)的設(shè)備兼容的位圖。函數(shù)原型:HBITMAPCreateCompatibleBitmap(HDChdc,intnWidth,intnHeight);參數(shù):hdc:設(shè)備環(huán)境句柄。nWidth:指定位圖的寬度,單位為像素。nHeight:指定位圖的高度,單位為像素。返回值:如果函數(shù)執(zhí)行成功,那么返回值是位圖的位圖句柄;如果函數(shù)執(zhí)行失敗,那么返回值為NULL。,LoadBitmap()函數(shù),函數(shù)功能:該函數(shù)從模塊的可執(zhí)行文件中加載指定的位圖資源。函數(shù)原型:HBITMAPLoadBitmap(HINSTANCEhInstance,LPCTSTRlpBitmapName);參數(shù):hlnstance:指向模塊實(shí)例的句柄。lpBitmapName:指向字符串指針。該字符串包含了要加載的位圖資源名稱。返回值:如果函數(shù)執(zhí)行成功,則返回值是指向指定位圖的位圖句柄。如果函數(shù)執(zhí)行失敗,那么返回值是NULL。,SelectObject()函數(shù),函數(shù)功能:該函數(shù)選擇一對象到指定的設(shè)備上下文環(huán)境中。函數(shù)原型:HGDIOBJSelectObject(HDChdc,HGDIOBJhgdiobj);參數(shù):hdc:設(shè)備上下文環(huán)境的句柄。hgdiobj:被選擇的對象的句柄,這些對象包括位圖、畫刷、字體、筆、區(qū)域等。返回值:如果選擇對象不是區(qū)域并且函數(shù)執(zhí)行成功,那么返回值是對象的句柄。,BitBlt()函數(shù),函數(shù)功能:該函數(shù)對指定的源設(shè)備環(huán)境區(qū)域中的像素進(jìn)行位塊轉(zhuǎn)換,并傳送到目標(biāo)設(shè)備環(huán)境。函數(shù)原型:BOOLBitBlt(HDChdcDest,intnXDest,intnYDest,intnWidth,intnHeight,HDChdcSrc,intnXSrc,intnYSrc,DWORDdwRop);參數(shù):hdcDest:指向目標(biāo)設(shè)備環(huán)境的句柄。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ù)運(yùn)算以完成最后的顏色。,常見的光柵操作代碼(dwRop),SRCCOPY:將源矩形區(qū)域直接拷貝到目標(biāo)矩形區(qū)域。SRCAND:通過使用AND(與)操作符來將源和目標(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ū)域的顏色合并。NOTSRCCOPY:將源矩形區(qū)域顏色取反,于拷貝到目標(biāo)矩形區(qū)域。NOTSRCERASE:使用布爾類型的OR(或)操作符組合源和目標(biāo)矩形區(qū)域的顏色值,然后將合成的顏色取反。,計(jì)算機(jī)中的GRB顏色,在計(jì)算機(jī)中,使用的是數(shù)字圖像處理,每一種顏色都是由RGB表示的,RGB是指紅(RED)、綠(GREEN)、藍(lán)(BLUE)三原色。RGB顏色值是紅綠藍(lán)3種顏色的強(qiáng)度,每個原色的GRB顏色值的取值范圍為0(#00)255(#FF)。RGB16進(jìn)制顏色值即是紅綠藍(lán)三原色各自16進(jìn)制顏色值的組合。如(255,255,255)的16進(jìn)制顏色值為#FFFFFF。舉例:白色是三原色值均為最大時混合成的的顏色,所以顏色表示為(255,255,255),16進(jìn)制就用#FFFFFF表示。黑色是三原色值均為最小時混合成的的顏色,所以顏色表示為(0,0,0),16進(jìn)制就用#000000表示。,在數(shù)字圖像處理中可以實(shí)現(xiàn)OR、AND等邏輯運(yùn)算。運(yùn)算規(guī)律如下:任何顏色同白色(#FFFFFF)進(jìn)行OR運(yùn)算結(jié)果都為白色,進(jìn)行AND運(yùn)算結(jié)果都是該顏色本身。任何顏色同黑色(#000000)進(jìn)行OR運(yùn)算結(jié)果都為該顏色本身,進(jìn)行AND運(yùn)算結(jié)果都是黑色。例如,可以進(jìn)行對圖1所示的位圖進(jìn)行去“背景色”的處理:首先將“圖2”位圖同目標(biāo)地顏色進(jìn)行“或”(OR)運(yùn)算,得到的結(jié)果是:“圖2”白色處為白色,其他處為目標(biāo)地顏色。再將“圖1”位圖同目標(biāo)地顏色進(jìn)行“與”(AND)運(yùn)算,得到的結(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);/或運(yùn)算BitBlt(hdc,x_pos,y_pos,20,20,picDC,0,20,SRCAND);/與運(yùn)算以下兩條語句會會達(dá)到的效果:在屏幕(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,實(shí)現(xiàn)位圖繪圖的核心代碼,HDCwindowDC=NULL;/windows屏幕設(shè)備HDCbufferDC=NULL;/緩沖設(shè)備環(huán)境HDCpicDC=NULL;/位圖內(nèi)存設(shè)備HBITMAPpicBMP=NULL;/位圖句柄HBITMAPbufferBMP=NULL;/緩沖位圖句柄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);SelectObject(bufferDC,bufferBMP);/將窗口的初始畫面位圖選入緩沖DCSelectObject(picDC,picBMP);/將角色位圖選入選入角色位圖DCBitBlt(bufferDC,x_pos,y_pos,20,20,picDC,80,20,SRCPAINT);/或運(yùn)算BitBlt(bufferDC,x_pos,y_pos,20,20,picDC,0,20,SRCAND);/與運(yùn)算/將整個畫面從緩沖DC拷貝出屏幕BitBlt(windowDC,0,0,g_iClientWidth,g_iClientHeight,bufferDC,0,0,SRCCOPY);,4.游戲?qū)嵗饰?分析:貪吃蛇游戲是一個深受人們喜愛的游戲,一條蛇在密閉的圍墻內(nèi)沿當(dāng)前方向移動,在圍墻內(nèi)不斷隨機(jī)出現(xiàn)水果和毒果。玩家通過按鍵盤上的四個光標(biāo)鍵控制蛇頭向上下左右四個方向移動,如果蛇頭吃到水果,蛇的身體長一節(jié),分?jǐn)?shù)加100分。如果蛇頭撞到墻壁或蛇頭觸碰到其身體或吃到毒果,游戲結(jié)束。,程序的要點(diǎn):,用一個小矩形塊表示蛇的一節(jié)身體,身體每長一節(jié),增加一個矩形塊。移動時必須從蛇頭開始,所以蛇不能向相反方向移動。如不按任何鍵,蛇自行在當(dāng)前方向上前移。當(dāng)游戲者按了有效的方向鍵后,蛇頭朝著指定的方向移動,一步移動一節(jié)身體,所以當(dāng)按了有效的方向鍵后,先確定蛇頭的位置,然后蛇身體隨著蛇頭移動,圖形的實(shí)現(xiàn)是從蛇頭的新位置開始畫出蛇。根據(jù)以上分析,設(shè)計(jì)了兩個類:CTable類、CSnack類。,主要基本數(shù)據(jù)結(jié)構(gòu)及常量的定義(1),/節(jié)點(diǎn)圖像顯示運(yùn)動狀態(tài)(方向)enumBitmapStateM_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é)點(diǎn)運(yùn)動狀態(tài)(方向)enumMoveStateS_NONE,S_UP,S_DOWN,S_LEFT,S_RIGHT;/坐標(biāo)位置結(jié)構(gòu)structSPointintx;inty;#defineTB_STATE_OK0/正常#defineTB_STATE_FOOD1/食物#defineTB_STATE_BLOCK2/障礙毒果#defineTB_STATE_SBLOCK3/障礙墻,主要基本數(shù)據(jù)結(jié)構(gòu)及常量的定義(2),/游戲狀態(tài)定義#defineGAME_STATE_WAIT0/游戲等待狀態(tài)#defineGAME_STATE_RUN1/游戲運(yùn)行狀態(tài)#defineGAME_STATE_END2/游戲結(jié)束狀態(tài)/界面相關(guān)物件尺寸定義#defineWALL_WIDTH80/外墻從左部到游戲區(qū)的寬度#defineWALL_HEIGHT80/外墻從頂部到游戲區(qū)的高度#defineBMP_SCORE_BOARD_WIDTH256/分?jǐn)?shù)位圖板的寬度#defineBMP_SCORE_BOARD_HEIGHT55/分?jǐn)?shù)位圖板的高度#defineBMP_WALL_WIDTH16/墻位圖的寬度#defineBMP_WALL_HEIGHT16/墻位圖的高度,classCSnakestructSnake_Struct/定義蛇體狀態(tài)MoveStatehead;/頭部MoveState*body;/身體MoveStatetail;/尾部;private:intm_length;/蛇的長度Snake_Structm_newSnake;/蛇的新態(tài)的所有節(jié)點(diǎn)運(yùn)動狀態(tài)Snake_Structm_oldSnake;/蛇的原態(tài)的所有節(jié)點(diǎn)運(yùn)動狀態(tài)BitmapState*m_pStateArray;/蛇的所有節(jié)點(diǎn)顯示位圖的狀態(tài)SPoint*m_pPos;/蛇體坐標(biāo)private:BitmapStateGetRightState(MoveStateoldDirect,MoveStatenewDirect);/根據(jù)新舊兩個身體的運(yùn)動趨勢情況,返回當(dāng)前應(yīng)當(dāng)顯示的身體狀態(tài)public:voidMove(void);voidChangeDirect(MoveStated);/改變方向,條件:非對立方向voidAddBody(intn=1);/蛇的身體增長voidSetHeadPos(intx,inty);/設(shè)置蛇頭的坐標(biāo)BitmapState*GetStateArray(void);/取蛇的狀態(tài)標(biāo)識數(shù)組SPoint*GetPos(void);/取蛇的位置數(shù)組boolIsHeadTouchBody(intx,inty);/檢測蛇頭是否觸碰到其身體intGetLength(void);/取蛇身的長度voidInitial(void);/初始化用作游戲結(jié)束后重新開始public:CSnake(intx_pos=0,inty_pos=0,intlen=1);CSnake();,classCTableprivate:intm_width;/桌子的寬度intm_height;/桌子的高度intm_foodNumber;/水果的數(shù)目intm_blockNumber;/障礙物(毒果)的數(shù)目CSnakem_snake;/桌子上的蛇int*m_board;/桌子面板,二維數(shù)組public:CTable();CTable();voidInitialTable(intw,inth);/初始化桌子面板boolAddBlock(intx,inty);/在某個位置放置毒果boolAddFood(intx,inty);/在某個位置放置水果boolClearFood(intx,inty);/清除某個位置的果實(shí)CSnake*GetSnake(void);/獲取蛇對象int*GetBoard(void);/取桌子對象intGetData(intx,inty);/取桌子某個位置數(shù)據(jù)voidSnakeMove(void);/蛇的移動boolChangeSnakeDirect(MoveStated);/改變蛇的方向;,主程序(main.cpp)中的全局變量,CTabletable;/創(chuàng)建一個桌子inttableBlockWidth=0;/桌子的格子的寬度inttableBlockHeight=0;/桌子的格子的高度intiScores=0;/游戲的得分UINTuGameState=GAME_STATE_WAIT;/當(dāng)前游戲狀態(tài)HDCwindowDC=NULL;/windows屏幕設(shè)備HDCbufferDC=NULL;/緩沖設(shè)備環(huán)境HDCpicDC=NULL;/snake圖像內(nèi)存設(shè)備HDCendDC=NULL;/游戲終結(jié)圖像內(nèi)存設(shè)備HDCscoreDC=NULL;/分?jǐn)?shù)板內(nèi)存設(shè)備HWNDhAppWnd=NULL;/本application窗口句柄HBITMAPpicBMP=NULL;/snake圖像位圖句柄HBITMAPbufferBMP=NULL;/緩沖位圖句柄HBITMAPendBMP=NULL;/游戲終結(jié)圖像內(nèi)存句柄HBITMAPhbmpWall=NULL;/墻位圖句柄HBITMAPhbmpScore=NULL;/分?jǐn)?shù)板位圖句柄HBRUSHhbrushWall=NULL;/墻畫刷UINTuSnakeMoveTimer;/蛇移動的定時器標(biāo)識UINTuFoodAddTimer;/水果產(chǎn)生的定時器標(biāo)識/框架的位置數(shù)據(jù)定義RECTg_ClientRect;RECTg_GameValueRect;intg_iClientWidth;intg_iClientHeight;,intWINAPIWinMain(HINSTANCEhCurrentInst,HINSTANCEhPrevInstance,PSTRlpszCmdLine,intnCmdShow)WNDCLASSwndClass;HWNDhWnd;MSGmsg;UINTwidth,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);SelectObject(endDC,endBMP);SelectObject(scoreDC,hbmpScore);/建立畫刷與其名相對應(yīng)的圖像的關(guān)聯(lián),/以備用刷子將墻刷出來,用PatBlt()實(shí)現(xiàn)hbrushWall=CreatePatternBrush(hbmpWall);StartGame();while(GetMessage(,WndProc()方法-(1),LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)switch(message)caseWM_TIMER:OnTimer(UINT)wParam);break;caseWM_KEYDOWN:switch(wParam)caseVK_ESCAPE:exit(0);break;caseVK_UP:table.ChangeSnakeDirect(S_UP);break;caseVK_DOWN:table.ChangeSnakeDirect(S_DOWN);break;caseVK_LEFT:table.ChangeSnakeDirect(S_LEFT);break;caseVK_RIGHT:table.ChangeSnakeDirect(S_RIGHT);break;caseVK_SPACE:if(uGameState=GAME_STATE_END)StartGame();break;return0;,WndProc()方法-(2),caseWM_SETCURSOR:SetCursor(NULL);return0;caseWM_DESTROY:ReleaseDC(hWnd,picDC);ReleaseDC(hWnd,bufferDC);ReleaseDC(hWnd,windowDC);PostQuitMessage(0);return0;returnDefWindowProc(hWnd,message,wParam,lParam);,voidStartGame()iScores=0;/桌面的初始化table.InitialTable(tableBlockWidth,tableBlockHeight);table.GetSnake()-ChangeDirect(S_RIGHT);table.GetSnake()-SetHeadPos(tableBlockWidth/2,tableBlockHeight/2);/預(yù)先隨機(jī)產(chǎn)生幾個食物srand(unsigned)time(NULL);for(intiFoodNum=0;iFoodNumIsHeadTouchBody(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)caseTB_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;caseTB_STATE_BLOCK:caseTB_STATE_SBLOCK:EndGame();/檢測是否碰到障礙物,結(jié)束游戲break;DrawGame();/顯示elseif(uTIMER_ID=uFoodAddTimer)/定時加食物table.AddFood(rand()%tableBlockWidth,(rand()%tableBlockHeight);,voidDrawGame(void)ShellDraw(bufferDC);/繪制外殼區(qū)域到緩沖GameAreaDraw(bufferDC);/繪制游戲區(qū)域到緩沖/將整個畫面從緩沖DCbufferDC拷貝到屏幕BitBlt(windowDC,0,0,g_iClientWidth,g_iClientHeight,bufferDC,0,0,SRCCOPY);voidShellDraw(HDChdc)/分?jǐn)?shù)提示顯示文字charszText30=Score:;charszNum20;intiNowScore=iScores*100;itoa(iNowScore,szNum,10);strcat(szText,szNum);RECTrt,rect;GetClientRect(hAppWnd,GameAreaDraw()方法-(1),voidGameAreaDraw(HDChdc)inti,j;intx,y,x_pos,y_pos;BitmapStatestate;/繪制水果與毒果for(i=0;iGetPos()0.y;x_pos=x*20+WALL_WIDTH;y_pos=y*20+WALL_HEIGHT;state=table.GetSnake()-GetStateArray()0;switch(state)caseM_UP_UP:BitBlt(hdc,x_pos,y_pos,20,20,picDC,80,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,0,20,SRCAND);break;caseM_DOWN_DOWN:BitBlt(hdc,x_pos,y_pos,20,20,picDC,140,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,60,20,SRCAND);break;caseM_LEFT_LEFT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,100,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,20,20,SRCAND);break;caseM_RIGHT_RIGHT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,120,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,40,20,SRCAND);break;,GameAreaDraw()方法-(3),/根據(jù)各個蛇身
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年碳排放權(quán)交易與許可合同
- 2024年股東保密協(xié)議:保護(hù)商業(yè)秘密共創(chuàng)雙贏
- 2024年道路燈光設(shè)備安裝協(xié)議
- 2025年度離婚協(xié)議書爭議解決機(jī)制設(shè)計(jì)合同3篇
- 2024建筑工程整潔施工管理合同一
- 2024餐館廢棄物處理合作協(xié)議
- 2024年跨國健康產(chǎn)業(yè)投資與服務(wù)合同
- 2024軟件公司關(guān)于信息系統(tǒng)集成與運(yùn)維的合同
- 2025年度城鄉(xiāng)公司農(nóng)村電商服務(wù)平臺開發(fā)與運(yùn)營合同3篇
- 2024年礦區(qū)環(huán)境保護(hù)與修復(fù)協(xié)議
- 新人教版一年級數(shù)學(xué)下冊全冊導(dǎo)學(xué)案
- 2024年突發(fā)事件新聞發(fā)布與輿論引導(dǎo)合同
- 2025年中考語文復(fù)習(xí)之現(xiàn)代文閱讀:非連續(xù)性文本閱讀(10題)
- GB/T 9755-2024合成樹脂乳液墻面涂料
- (正式版)JBT 10437-2024 電線電纜用可交聯(lián)聚乙烯絕緣料
- 教科版三年級上冊科學(xué)期末測試卷(二)【含答案】
- 2-07端陽賽馬節(jié)的傳說
- 國家開放大學(xué)《土木工程力學(xué)(本)》章節(jié)測試參考答案
- 衣柜技術(shù)標(biāo)準(zhǔn)
- 某隧道二襯檢測報告范本(共13頁)
- (完整版)臨時用電施工合同
評論
0/150
提交評論