win32游戏编程——贪吃蛇游戏

来源:互联网 发布:linux eth1 改为eth0 编辑:程序博客网 时间:2024/06/08 00:53

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。




0 0