学习c++快一年了,也想自己动手编一个小游戏。下面这个是我的处女作,不免有一些问题,望高手指点。
//cpp文件
#include<windows.h>
#include"resource.h"
#define LEFT 1
#define RIGHT 2
#define UP 3
#define DOWN 4
RECT rcSnake[100];
int pide;
int direction;
RECT rcFood;
bool bHave;
static int cxClient,cyClient;
UINT iGameSpeed;
HBRUSH hBrush;
BOOL CALLBACK SettingDlgProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
static int l;
switch(message)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BUTTON1:
switch(l)
{
case 1:
iGameSpeed=1000;
break;
case 2:
iGameSpeed=500;
break;
case 3:
iGameSpeed=250;
break;
case 4:
iGameSpeed=25;
break;
}
SetTimer(NULL,1,iGameSpeed,NULL);
EndDialog(hwnd,0);
return TRUE;
case IDC_RADIO1:
SendMessage((HWND)lParam,BM_SETCHECK,1,0);
l=1;
break;
case IDC_RADIO2:
SendMessage((HWND)lParam,BM_SETCHECK,1,0);
l=2;
break;
case IDC_RADIO3:
SendMessage((HWND)lParam,BM_SETCHECK,1,0);
l=3;
break;
case IDC_RADIO4:
SendMessage((HWND)lParam,BM_SETCHECK,1,0);
l=4;
break;
}
}
return 0;
};
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
void CreateFood(HWND hwnd,HDC hdc,RECT *rcFood)
{
int i,j;
while(1)
{
i=rand()%600/30*30;
j=rand()%400/30*30;
SetRect(rcFood,i,j,i+29,j+29);
for(i=0;i<pide;i++)
{
if(rcSnake[i].bottom==rcFood->bottom)
if(rcSnake[i].left==rcFood->left)
if(rcSnake[i].right==rcFood->right)
if(rcSnake[i].top==rcFood->top)
break;
}
if(i==pide) break;
}
}
void DrawFood(HWND hwnd,HDC hdc,RECT rcFood)
{
FillRect(hdc,&rcFood,CreateSolidBrush(RGB(255,0,0)));
};
void DrawSnake(HWND hwnd,HDC hdc,RECT rcSnake[100])
{
int i;
for(i=0;i<pide;i++)
{
FillRect(hdc,&rcSnake[i],CreateSolidBrush(RGB(255,0,0)));
}
};
void SnakeRun(RECT rcSnake[100])
{
int i;
for(i=pide-1;i>0;i--)
{
rcSnake[i]=rcSnake[i-1];
}
switch(direction)
{
case LEFT:
OffsetRect(&rcSnake[0],-30,0);
break;
case RIGHT:
OffsetRect(&rcSnake[0],30,0);
break;
case DOWN:
OffsetRect(&rcSnake[0],0,30);
break;
case UP:
OffsetRect(&rcSnake[0],0,-30);
break;
}
};
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iCmdShow)
{
static TCHAR *szAppName="Snake";
WNDCLASS wndclass;
HWND hwnd;
MSG msg;
hBrush=CreatePatternBrush(LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP1)));
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=hBrush;
wndclass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));
wndclass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=WndProc;
wndclass.lpszClassName=szAppName;
wndclass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);
wndclass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,"Programs requires Windows NT",szAppName,MB_ICONERROR);
return 0;
}
hwnd=CreateWindow(szAppName,szAppName,
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;
static HINSTANCE hInstance;
switch(message)
{
case WM_CREATE:
hInstance=((LPCREATESTRUCT)lParam)->hInstance;
return 0;
case WM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,600,400,NULL);
SetViewportExtEx(hdc,cxClient,cyClient,NULL);
EndPaint(hwnd,&ps);
return 0;
case WM_KEYDOWN:
switch(LOWORD(wParam))
{
case VK_LEFT:
if(direction!=RIGHT)
direction=LEFT;
break;
case VK_RIGHT:
if(direction!=LEFT)
direction=RIGHT;
break;
case VK_UP:
if(direction!=DOWN)
direction=UP;
break;
case VK_DOWN:
if(direction!=UP)
direction=DOWN;
break;
}
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_EXIT:
PostQuitMessage(0);
break;
case IDM_START:
//初始化蛇和食物
hdc=GetDC(hwnd);
SetRect(&rcSnake[0],90,60,119,89);
SetRect(&rcSnake[1],60,60,89,89);
SetRect(&rcSnake[2],30,60,59,89);
InvalidateRect(hwnd,NULL,TRUE);
pide=3;
DrawSnake(hwnd,hdc,rcSnake);
CreateFood(hwnd,hdc,&rcFood);
DrawFood(hwnd,hdc,rcFood);
bHave=1;
direction=RIGHT;
ReleaseDC(hwnd,hdc);
SetTimer(NULL,1,iGameSpeed,NULL);
break;
case IDM_PAUSE:
KillTimer(NULL,1);
break;
case IDM_CONTINUE:
SetTimer(NULL,1,iGameSpeed,NULL);
break;
case IDM_SETTING:
KillTimer(NULL,1);
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,SettingDlgProc);
break;
}
return 0;
case WM_TIMER:
int i;
hdc=GetDC(hwnd);
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,600,400,NULL);
SetViewportExtEx(hdc,cxClient,cyClient,NULL);
FillRect(hdc,&rcSnake[pide-1],hBrush);
SnakeRun(rcSnake);
//开始判断蛇是否碰墙或撞自己。食物
//撞墙
if(rcSnake[0].bottom>400)
SendMessage(hwnd,WM_COMMAND,IDM_START,0);
if(rcSnake[0].left<0)
SendMessage(hwnd,WM_COMMAND,IDM_START,0);
if(rcSnake[0].right>600)
SendMessage(hwnd,WM_COMMAND,IDM_START,0);
if(rcSnake[0].top<0)
SendMessage(hwnd,WM_COMMAND,IDM_START,0);
//撞自己
for(i=1;i<pide;i++)
{
if(rcSnake[i].bottom==rcSnake[0].bottom)
if(rcSnake[i].left==rcSnake[0].left)
if(rcSnake[i].right==rcSnake[0].right)
if(rcSnake[i].top==rcSnake[0].top)
SendMessage(hwnd,WM_COMMAND,IDM_START,0);
}
//撞到食物
if(rcSnake[0].bottom==rcFood.bottom)
if(rcSnake[0].left==rcFood.left)
if(rcSnake[0].right==rcFood.right)
if(rcSnake[0].top==rcFood.top)
{
pide+=1;
SetRect(&rcSnake[pide-1],0,0,0,0);
CreateFood(hwnd,hdc,&rcFood);
DrawFood(hwnd,hdc,rcFood);
}
DrawFood(hwnd,hdc,rcFood);
DrawSnake(hwnd,hdc,rcSnake);
ReleaseDC(hwnd,hdc);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
//rc文件
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/
#undef APSTUDIO_READONLY_SYMBOLS
/
// Chinese (P.R.C.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h/0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""/r/n"
"/0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"/r/n"
"/0"
END
#endif // APSTUDIO_INVOKED
/
//
// Bitmap
//
IDB_BITMAP1 BITMAP DISCARDABLE "bitmap1.bmp"
IDB_BITMAP2 BITMAP DISCARDABLE "bitmap2.bmp"
/
//
// Cursor
//
IDC_CURSOR1 CURSOR DISCARDABLE "cursor1.cur"
/
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "icon1.ico"
/
//
// Menu
//
IDR_MENU1 MENU DISCARDABLE
BEGIN
POPUP "游戏"
BEGIN
MENUITEM "开始", IDM_START
MENUITEM "暂停", IDM_PAUSE
MENUITEM "继续", IDM_CONTINUE
MENUITEM "退出", IDM_EXIT
END
MENUITEM "游戏设置...", IDM_SETTING
END
/
//
// Dialog
//
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 187, 94
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 10, "System"
BEGIN
LTEXT "请选择游戏级别:",IDC_STATIC,14,13,104,11
CONTROL "1",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,17,39,20,10
CONTROL "2",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,71,39,20,10
CONTROL "3",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,19,57,20,10
CONTROL "4",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,70,56,20,10
PUSHBUTTON "确定",IDC_BUTTON1,140,64,33,14
GROUPBOX "级别",IDC_STATIC,13,29,103,58
END
/
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_DIALOG1, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 180
TOPMARGIN, 7
BOTTOMMARGIN, 87
END
END
#endif // APSTUDIO_INVOKED
#endif // Chinese (P.R.C.) resources
/
#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
//
/
#endif // not APSTUDIO_INVOKED