贪蛇小游戏开发
自己学windows程序设计有一段时间了,决定自己编一个小游戏,就开始构思贪蛇小游戏的思路(在此以前没有参考过别人的思路)。我选择有c言语来编写;
直接有windows 的api函数来实现游戏功能;
开发工具是vc++6.0;
个人觉得在程序的开发过程中的难点就是:如何控制各方块的运动方向。程序中没有涉及到什么复杂的算法,一些代码也可以进一步简化(当时没考虑),以下是源码以及一些游戏截图
程序代码:
#include<windows.h> #include<stdlib.h> //#include<time.h> #define ZUO 1 #define YOU 2 #define SHANG 3 #define XIA 4 #define STEP (fStep?5:10) LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); void shuijijuxing(HWND); //产生随机矩形 BOOL panduanpz(HWND hwnd,RECT rect1,RECT rect2); //判断两矩形是否产生碰撞 BOOL pengz(HWND,RECT); //判断是否碰撞边界 RECT rect[100],rect1,rect3,rect2; int n=0,n1=0,n2,fx=2,n3=1; //n3保存已连接的矩形个数,n为产生的矩形个数 int cxClient,cyClient; BOOL fRect=TRUE,fZuo=TRUE,fYou=TRUE,fXia=TRUE,fShang=TRUE,fStep=TRUE; //控制上下左右方向 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { static TCHAR szAppName[]=TEXT("RandRect"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style =CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hInstance=hInstance; wndclass.hIcon =LoadIcon(hInstance,TEXT("tanse")); wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName=NULL; wndclass.lpszClassName=szAppName; if(!RegisterClass(&wndclass)) { MessageBox(NULL,TEXT("SHI BAI"),TEXT("ZHU CE SHI BAI"),MB_ICONERROR); return 0; } hwnd=CreateWindow(szAppName,TEXT("简单版贪蛇游戏"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,iCmdShow); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int i,j; TCHAR str[255]; switch(message) { case WM_CREATE: GetClientRect(hwnd,&rect1); cxClient=rect1.right; cyClient=rect1.bottom; shuijijuxing(hwnd); shuijijuxing(hwnd); SetTimer(hwnd,1,20,NULL); return 0; case WM_SIZE: cxClient=LOWORD(lParam); cyClient=HIWORD(lParam); return 0; case WM_TIMER: if(fx==ZUO) { if(panduanpz(hwnd,rect[n1],rect[n-1])) //判断碰撞 { rect[n-1].right=rect[n1].left; rect[n-1].bottom=rect[n1].bottom; rect[n-1].top=rect[n1].top; rect[n-1].left=rect[n1].left-20; //将两个矩形合并 rect3=rect[n-1]; //交换矩形使rect[0]始终位于头部 rect[n-1]=rect[n1]; rect[n1]=rect3; shuijijuxing(hwnd); if(2==n3) //实现矩形加速运动 fStep=FALSE; } else //判断每个矩形的移动方向 { rect[0].left-=STEP; rect[0].right-=STEP; for(i=1;i<n3;i++) { if(rect[i].top>rect[0].top) { if(rect[i].right<rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left+=STEP; rect[i].right+=STEP; } } else if(rect[i].right>rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left-=STEP; rect[i].right-=STEP; } } else { rect[i].top-=STEP; rect[i].bottom-=STEP; } } else if(rect[i].bottom<rect[0].bottom) { if(rect[i].right<rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left+=STEP; rect[i].right+=STEP; } } else if(rect[i].right>rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left-=STEP; rect[i].right-=STEP; } } else { rect[i].top+=STEP; rect[i].bottom+=STEP; } } else { rect[i].left-=STEP; rect[i].right-=STEP; } } } InvalidateRect(hwnd,NULL,TRUE); } if(fx==YOU) { if(panduanpz(hwnd,rect[n1],rect[n-1])) { rect[n-1].left=rect[n1].right; rect[n-1].bottom=rect[n1].bottom; rect[n-1].top=rect[n1].top; rect[n-1].right=rect[n1].right+20; rect3=rect[n-1]; rect[n-1]=rect[n1]; rect[n1]=rect3; shuijijuxing(hwnd); if(2==n3) fStep=FALSE; } else { rect[0].left+=STEP; rect[0].right+=STEP; for(i=1;i<n3;i++) { if(rect[i].top>rect[0].top) { if(rect[i].right<rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left+=STEP; rect[i].right+=STEP; } } else if(rect[i].right>rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left-=STEP; rect[i].right-=STEP; } } else { rect[i].top-=STEP; rect[i].bottom-=STEP; } } else if(rect[i].bottom<rect[0].bottom) { if(rect[i].right<rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left+=STEP; rect[i].right+=STEP; } } else if(rect[i].right>rect2.right) { if(rect[i].top<rect2.top) { rect[i].top+=STEP; rect[i].bottom+=STEP; } else if(rect[i].top>rect2.top) { rect[i].top-=STEP; rect[i].bottom-=STEP; } else { rect[i].left-=STEP; rect[i].right-=STEP; } } else { rect[i].top+=STEP; rect[i].bottom+=STEP; } } else { rect[i].left+=STEP; rect[i].right+=STEP; } } } InvalidateRect(hwnd,NULL,TRUE); } if(fx==SHANG) { if(panduanpz(hwnd,rect[n1],rect[n-1])) { rect[n-1].left=rect[n1].left; rect[n-1].bottom=rect[n1].top; rect[n-1].top=rect[n1].top-20; rect[n-1].right=rect[n1].right; rect3=rect[n-1]; rect[n-1]=rect[n1]; rect[n1]=rect3; shuijijuxing(hwnd); if(2==n3) fStep=FALSE; } else { rect[0].top-=STEP; rect[0].bottom-=STEP; for(i=1;i<n3;i++) { if(rect[i].left>rect[0].left) { if(rect[i].top>rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top-=STEP; rect[i].bottom-=STEP; } } else if(rect[i].top<rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top+=STEP; rect[i].bottom+=STEP; } } else { rect[i].left-=STEP; rect[i].right-=STEP; } } else if(rect[i].right<rect[0].right) { if(rect[i].top>rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top-=STEP; rect[i].bottom-=STEP; } } else if(rect[i].top<rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top+=STEP; rect[i].bottom+=STEP; } } else { rect[i].left+=STEP; rect[i].right+=STEP; } } else { rect[i].top-=STEP; rect[i].bottom-=STEP; } } } InvalidateRect(hwnd,NULL,TRUE); } if(fx==XIA) { if(panduanpz(hwnd,rect[n1],rect[n-1])) { rect[n-1].left=rect[n1].left; rect[n-1].bottom=rect[n1].bottom+20; rect[n-1].top=rect[n1].bottom; rect[n-1].right=rect[n1].right; rect3=rect[n-1]; rect[n-1]=rect[n1]; rect[n1]=rect3; shuijijuxing(hwnd); if(2==n3) fStep=FALSE; } else { rect[0].top+=STEP; rect[0].bottom+=STEP; for(i=1;i<n3;i++) { if(rect[i].left>rect[0].left) { if(rect[i].top>rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top-=STEP; rect[i].bottom-=STEP; } } else if(rect[i].top<rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top+=STEP; rect[i].bottom+=STEP; } } else { rect[i].left-=STEP; rect[i].right-=STEP; } } else if(rect[i].right<rect[0].right) { if(rect[i].top>rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top-=STEP; rect[i].bottom-=STEP; } } else if(rect[i].top<rect2.top) { if(rect[i].right<rect2.right) { rect[i].left+=STEP; rect[i].right+=STEP; } else if(rect[i].right>rect2.right) { rect[i].left-=STEP; rect[i].right-=STEP; } else { rect[i].top+=STEP; rect[i].bottom+=STEP; } } else { rect[i].left+=STEP; rect[i].right+=STEP; } } else { rect[i].top+=STEP; rect[i].bottom+=STEP; } } } InvalidateRect(hwnd,NULL,TRUE); } return 0; case WM_KEYDOWN: switch(wParam) { case VK_UP: if(fShang) { rect2.top=rect[0].top; //记录拐角位置 fZuo=TRUE;fYou=TRUE;fXia=FALSE;fShang=TRUE; //控制当往上运动的时候,不能按下 fx=SHANG; } break; case VK_DOWN: if(fXia) { rect2.top=rect[0].top; fZuo=TRUE;fYou=TRUE;fXia=TRUE;fShang=FALSE; fx=XIA; } break; case VK_LEFT: if(fZuo) { rect2.right=rect[0].right; fZuo=TRUE;fYou=FALSE;fXia=TRUE;fShang=TRUE; fx=ZUO; } break; case VK_RIGHT: if(fYou) { rect2.right=rect[0].right; fZuo=FALSE;fYou=TRUE;fXia=TRUE;fShang=TRUE; fx=YOU; } break; } return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); SelectObject(hdc,GetStockObject(GRAY_BRUSH)); TextOut(hdc,5,5,str,wsprintf(str,"左:%d 右:%d 顶:%d 低:%d 个数:%d",rect[0].left,rect[0].right,rect[0].top,rect[0].bottom,n3)); if(pengz(hwnd,rect[0])) { KillTimer(hwnd,1); j=MessageBox(NULL,TEXT("游戏结束"),TEXT("提示"),MB_YESNO); if(j==IDYES || j==IDNO) SendMessage(hwnd,WM_DESTROY,0,0); } else if(n3==17) { KillTimer(hwnd,1); j=MessageBox(NULL,TEXT("恭喜通关"),TEXT("提示"),MB_YESNO); if(j==IDYES || j==IDNO) SendMessage(hwnd,WM_DESTROY,0,0); } else for(i=0;i<n;i++) Rectangle(hdc, rect[i].left, rect[i].top, rect[i].right, rect[i].bottom); EndPaint(hwnd,&ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); } void shuijijuxing(HWND hwnd) { HDC hdc; HPEN hPen; if(cxClient==0||cyClient==0) return ; rect[n].left=rand()%cxClient; rect[n].top=rand()%cyClient; rect[n].right=rect[n].left+20; rect[n].bottom=rect[n].top+20; hPen=CreatePen(PS_DOT,2,RGB(255,255,255)); hdc=GetDC(hwnd); SelectObject(hdc,hPen); SelectObject(hdc,GetStockObject(GRAY_BRUSH)); if(n<=100) Rectangle(hdc, rect[n].left, rect[n].top, rect[n].right, rect[n].bottom); ReleaseDC(hwnd,hdc); n2=n; n++; } BOOL panduanpz(HWND hwnd,RECT rect1,RECT rect2) { if((rect2.right<=rect1.left && rect1.left<=rect2.right+10) && (rect2.bottom<=rect1.bottom && rect1.bottom<=rect2.bottom+10) ||(rect1.right>=rect2.left-10 && rect1.right<=rect2.left) && (rect2.bottom<=rect1.bottom && rect1.bottom<=rect2.bottom+10) ||(rect1.top>=rect2.bottom && rect1.top<=rect2.bottom+10) && (rect2.left<=rect1.left && rect1.left<=rect2.left+10) ||(rect1.bottom<=rect2.top && rect1.bottom>=rect2.top-10) && (rect2.left<=rect1.left && rect1.left<=rect2.left+10)) { n3++; fRect=TRUE; return fRect;} else {fRect=FALSE; return fRect;} } BOOL pengz(HWND hwnd,RECT rect) { if((rect.left>=0 && rect.left<=STEP-2) || (rect.right>=(cxClient-STEP+2) && rect.right<=cxClient) || (rect.top>=0 && rect.top<=STEP-2) || (rect.bottom>=(cyClient-STEP+2) && rect.bottom<=cyClient) ) { return TRUE; } else return FALSE; }
运行后的截图:
程序下载地址:
http://pan.baidu.com/share/link?shareid=929936507&uk=824474712
有些地方也需改进