贪蛇小游戏开发
自己学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
有些地方也需改进







