win32遊戲編程——貪喫蛇遊戲

1.寫此貼的意圖

        剛開始學c++,編的是win32 console application,在黑框框裏進行輸入和輸出,覺得和自己想象的程序差好多,有點失望,後來接觸到win32程序,感覺和我們平時見到的程序差不多,然後想嘗試去編一些簡單的遊戲,參考了《Windows遊戲編程大師技巧》(作者Andre LaMothe)這本書,編了自己的貪喫蛇小遊戲,見圖1,在編程過程中發現其實核心就是去繪製圖形和讓圖形去移動,圖形移動其實就是繪圖,只不過相對於之前的圖形座標改變,加上刷新的速度(至少一秒鐘30幀)很快,人眼看起來就是很自然的移動。此處分享我學會的如何在win32程序下繪製多邊形並移動它.



                                                                                      圖一

2、言歸正傳,第一步:需要創建一個win32程序,步驟參照(http://blog.csdn.net/u010534406/article/details/49817575)。

                          第二步建立一個多邊形類:

class polygon{
public:
int state;//if state=1,the polygon has been initialized,and normal;state=0,no ini
int num;//the NO. of edges
POINT *points;//頂點
int vx,vy;//速度
POINT mid;//mid point;
polygon(POINT*p=NULL,int v1=0,int v2=0,int no=3);
void draw_polygon();
void move_poly();
~polygon (){
points=NULL;
}
};
polygon::polygon (POINT*p,int v1,int v2,int no){
num=no;
vx=v1;
vy=v2;
mid.x=0;
mid.y=0;
points=p;
if(points!=NULL)state=1; 
}


void polygon ::draw_polygon (){

if(state==1) Polygon (g_hdc,points,num);
}

void polygon ::move_poly (){
   if(state){
mid.x+=vx;
mid.y+=vy;
//make sure the poly is in the screeen
if(mid.x>590) mid.x=0;
if(mid.x<0) mid.x=590;
if(mid.y>410) mid.y=0;
if(mid.y<0) mid.y=410;
for(int index=0;index<num;index++){
points[index].x =mid.x+g_p[index].x;
        points[index].y =mid.y+g_p[index].y;

}
}//end index for

      polygon包括數據state,num,vx,vy,points,mid。state用於表徵多邊形的狀態,如果正常狀態,state=1;num是多邊形的邊數;vx,vy是多邊形的速度;points是多邊形的頂點左邊,mid是多邊形頂點參照系中的(0,0)點,什麼意思呢?就是mid加上最初的多邊形座標,就等於當下多邊形座標,那麼平移多邊形,只需要改變mid的座標就可以了,這樣可以比較好的控制多邊形整個圖形在屏幕內。

     函數操作包括poly_draw()、move_poly()和構造以及析構函數,poly_draw()中Polygon (g_hdc,points,num)是win32 API,第一個參數是hdc,第二個是多邊形頂點,第三個是頂點數,move_poly()就是根據vx、vy去改變mid,再保證mid在屏幕內,再改變points的座標。

   第三步,主函數內循環繪圖,

while(1){
if(PeekMessage(&msg,hwnd,NULL,NULL,PM_REMOVE)){
if(msg.message ==WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(KEYDOWN(VK_ESCAPE )) {
SendMessage(hwnd, WM_CLOSE, 0,0);
break;


 
  SelectObject(g_hdc,black_brush);
  PG.draw_polygon ();
  PG.move_poly ();
                   SelectObject(g_hdc,red_brush);
  PG.draw_polygon ();
Sleep (25);


}

紅色部分是畫圖,畫圖要分兩步,先把上次的圖片覆蓋成背景色,再移動多邊形,再繪製新圖形,注意需要延時, SelectObject()就是改變畫筆畫刷顏色的,畫筆畫刷是之前創建好的。

繪製圖形並移動的程序就完成了。

以下是全部代碼:

# define WIN32_LEAN_AND_MEAN
//include//////////////////////////////
#include <Windows.h>
#include<windowsx.h>
#include<stdio.h>
#include<math.h>
#include<tchar.h>
//define//////////////////////////////////////////////////////////////////////////


#define WINDOW_CLASS_NAME "window1"
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)




//globals/////////////////////////////////////////////////////////////////////////
HDC g_hdc;
POINTS g_p[6]={0,10,0,20,10,30,30,20,20,10,30,0};//the points of polygon






//class polygon///////////////////////////////////////////////////////////////////
class polygon{
public:
int state;//if state=1,the polygon has been initialized,and normal;state=0,no ini


int num;//the NO. of edges
POINT *points;//頂點
int vx,vy;//速度
POINT mid;//mid point;
polygon(POINT*p=NULL,int v1=0,int v2=0,int no=3);
void draw_polygon();
void move_poly();
~polygon (){
points=NULL;
}
};
polygon::polygon (POINT*p,int v1,int v2,int no){
num=no;
vx=v1;
vy=v2;
mid.x=0;
mid.y=0;
points=p;
if(points!=NULL)state=1; 


}


void polygon ::draw_polygon (){


if(state==1) Polygon (g_hdc,points,num);




}
void polygon ::move_poly (){
   if(state){
mid.x+=vx;
mid.y+=vy;
//make sure the poly is in the screeen
if(mid.x>590) mid.x=0;
if(mid.x<0) mid.x=590;
if(mid.y>410) mid.y=0;
if(mid.y<0) mid.y=410;




for(int index=0;index<num;index++){
points[index].x =mid.x+g_p[index].x;
        points[index].y =mid.y+g_p[index].y;

}
}//end index for
}
LRESULT CALLBACK WindowProc(HWND hwnd,
                       UINT msg,
WPARAM wparam,
LPARAM lparam
)  
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg){
case WM_CREATE:{
return 0;
 }break;
case WM_PAINT:{
hdc=BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return 0;
 }break;
case WM_DESTROY:{
PostQuitMessage(0);
return 0;
}break;
default:break;
}
return (DefWindowProc(hwnd,msg,wparam,lparam));


}




int WINAPI WinMain(HINSTANCE hinstance,
              HINSTANCE hpreinstance,
  LPSTR lpcmdline,
  int ncmdshow){
WNDCLASSEX winclass;
HWND hwnd;
MSG msg;
winclass.cbSize=sizeof(WNDCLASSEX);
winclass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
winclass.lpfnWndProc=WindowProc;
winclass.cbClsExtra=0;
winclass.cbWndExtra=0;
winclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.hCursor=LoadCursor(NULL,IDC_ARROW);
winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
winclass.hIconSm =LoadIcon(NULL,IDI_APPLICATION);
winclass.hInstance =hinstance;
winclass.lpszClassName =_T(WINDOW_CLASS_NAME);
winclass.lpszMenuName =NULL;


if(!(RegisterClassEx(&winclass))){
return 0;
}
if(!(hwnd=CreateWindowEx(NULL,
_T(WINDOW_CLASS_NAME),
_T("WP"),
WS_OVERLAPPEDWINDOW|WS_VISIBLE,
0,0,
640,480,
NULL,
NULL,
hinstance,
NULL)))
return 0;
g_hdc =GetDC (hwnd);
POINT p[6]={0,10,0,20,10,30,30,20,20,10,30,0};//the point of polygon

polygon  PG(p,2,2,6);
HBRUSH black_brush=CreateSolidBrush (RGB(0,0,0));
HBRUSH red_brush=CreateSolidBrush (RGB(255,0,0));


while(1){
if(PeekMessage(&msg,hwnd,NULL,NULL,PM_REMOVE)){
if(msg.message ==WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(KEYDOWN(VK_ESCAPE )) {
SendMessage(hwnd, WM_CLOSE, 0,0);
break;


 
  SelectObject(g_hdc,black_brush);
  PG.draw_polygon ();
  PG.move_poly ();
          SelectObject(g_hdc,red_brush);
  PG.draw_polygon ();
Sleep (25);

}
DeleteObject (black_brush );
DeleteObject(red_brush );



return (msg.wParam);
}

 


需要貪喫蛇代碼的朋友私信qq:1642484756。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章