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。