![]() |
#2
tsyking2011-10-26 10:24
|
1、按下空格之后,即便不动他,程序在一段时间后就会异常,是不是越界了。?
2、吃下一个豆子后,键盘的输入和处理就不协调了,是不是得得用多线程编写?
3、这也是我无法理解的,每一次吃下一颗豆子之后,右上角就会出现描绘出的一块,一段时间后会消失,但我没有这么设计啊
如果能够帮我在代码中修改,更好。谢谢各位高手

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.' \
version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' \
language='*'\"")
#include <windows.h>
const int MAX = 35;
const int INITIALLENGTH = 19;
const int iRectSide = 20;
const int IDT_TIMER1 = 1;
const int IDT_TIMER2 = 2;
enum SnakeDirection
{
UP = 0,
DOWN = 1,
LEFT = 2,
RIGHT = 3,
};
enum SnakeStatus
{
STOP = 0,
RUN = 1,
PAUSE = 2,
};
struct SnakeBody
{
int x;
int y;
};
struct Snake
{
SnakeDirection direction;
SnakeStatus status;
int iBodyNum;
int iHead;
int iTail;
SnakeBody bodys[MAX * MAX];
};
static Snake snake;
static SnakeBody bean;
static SnakeDirection keyboardInput = RIGHT;
static HRGN hRgnSnake;
static HRGN hRgnBean;
static HRGN hRgnEmpty = CreateRectRgn(0, 0, 0, 0);
HRGN hRgnNewBody;
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Snake"); // 添加
HWND hwnd;
MSG msg;
WNDCLASSEX wndclassex = {0};
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.lpfnWndProc = WndProc;
wndclassex.cbClsExtra = 0;
wndclassex.cbWndExtra = 0;
wndclassex.hInstance = hInstance;
wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclassex.lpszMenuName = NULL;
wndclassex.lpszClassName = szAppName;
wndclassex.hIconSm = wndclassex.hIcon;
if (!RegisterClassEx (&wndclassex))
{
MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,
szAppName,
TEXT ("Snake"), // 添加
WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
CW_USEDEFAULT,
CW_USEDEFAULT,
(MAX + 1) * iRectSide,
(MAX + 2) * iRectSide,
NULL,
NULL,
hInstance,
NULL);
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
VOID CreateSnake(HWND hwnd, Snake & snake);
VOID RunSnake(HWND hwnd, Snake & snake, SnakeBody & bean);
VOID FindSnakeRgn(HWND hwnd, Snake & snake);
VOID ThrowBean(HWND hwnd, SnakeBody & bean);
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HBRUSH hBrushGray = (HBRUSH) GetStockObject(GRAY_BRUSH);
HBRUSH hBrushGreen = CreateSolidBrush(RGB(0, 255, 0));
static int cxClient, cyClient;
switch (message)
{
case WM_CREATE:
hdc = GetDC (hwnd);
CreateSnake(hwnd, snake);
ReleaseDC (hwnd, hdc);
ThrowBean(hwnd, bean);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
for (int x = 1; x <= MAX; ++x)
{
MoveToEx(hdc, x * iRectSide, 0, NULL);
LineTo(hdc, x * iRectSide, MAX * iRectSide);
}
for (int y = 1; y <= MAX; ++y)
{
MoveToEx(hdc, 0, y * iRectSide, NULL);
LineTo(hdc, MAX * iRectSide, y * iRectSide);
}
FindSnakeRgn(hwnd, snake);
SelectObject(hdc, hRgnSnake);
FillRgn(hdc, hRgnSnake, hBrushGray);
SelectObject(hdc, hRgnBean);
FillRgn(hdc, hRgnBean, hBrushGreen);
EndPaint (hwnd, &ps);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_SPACE:
if (snake.status == PAUSE)
{
SetTimer(hwnd, IDT_TIMER2, 200, NULL);
snake.status = RUN;
}
else
{
KillTimer(hwnd, IDT_TIMER2);
snake.status = PAUSE;
}
break;
case VK_UP:
keyboardInput = UP;
break;
case VK_DOWN:
keyboardInput = DOWN;
break;
case VK_LEFT:
keyboardInput = LEFT;
break;
case VK_RIGHT:
keyboardInput = RIGHT;
break;
}
return 0;
case WM_TIMER:
if(snake.status)
{
RunSnake(hwnd, snake, bean);
InvalidateRect(hwnd, NULL, TRUE);
}
return 0;
case WM_CLOSE:
snake.status = PAUSE;
KillTimer(hwnd, IDT_TIMER2);
if(IDYES == MessageBox(hwnd, TEXT("你真的不玩了吗?"), TEXT("Snake"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
DestroyWindow(hwnd);
return 0;
case WM_DESTROY:
DeleteObject(hBrushGray);
DeleteObject(hBrushGreen);
DeleteObject(hRgnSnake);
DeleteObject(hRgnBean);
DeleteObject(hRgnEmpty);
DeleteObject(hRgnNewBody);
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
VOID CreateSnake(HWND hwnd, Snake & snake)
{
snake.status = PAUSE;
snake.direction = RIGHT;
snake.iBodyNum = INITIALLENGTH;
snake.iHead = INITIALLENGTH - 1;
snake.iTail = 0;
hRgnSnake = hRgnEmpty;
for (int i = 0; i < INITIALLENGTH; ++i)
{
snake.bodys[i].x = (MAX - INITIALLENGTH) / 2 - 1 + i;
snake.bodys[i].y = MAX / 2;
hRgnNewBody = CreateRectRgn(snake.bodys[i].x * iRectSide, snake.bodys[i].y * iRectSide, (snake.bodys[i].x + 1) * iRectSide, (snake.bodys[i].y + 1) * iRectSide);
CombineRgn(hRgnSnake, hRgnNewBody, hRgnSnake, RGN_OR);
}
//InvalidateRect(hwnd, NULL, TRUE);
}
VOID RunSnake(HWND hwnd, Snake & snake, SnakeBody & bean)
{
SnakeBody newBody, oldBody, tempBody;
switch (keyboardInput)
{
case UP:
if(snake.direction != DOWN)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y - 1;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
case DOWN:
if(snake.direction != UP)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y + 1;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
case LEFT:
if(snake.direction != RIGHT)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x - 1;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
case RIGHT:
if(snake.direction != LEFT)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x + 1;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
}
newBody.x = (tempBody.x + MAX) % MAX;
newBody.y = (tempBody.y + MAX) % MAX;
oldBody = snake.bodys[snake.iTail];
if(newBody.x == bean.x && newBody.y == bean.y)
{
snake.iBodyNum += 1;
hRgnBean = hRgnEmpty;
ThrowBean(hwnd, bean);
}
else
snake.iTail += 1;
for (int i = snake.iTail; i < snake.iHead; ++i)
if(newBody.x == snake.bodys[i].x && newBody.y == snake.bodys[i].y)
{
snake.status = STOP;
if(IDYES == MessageBox(hwnd, TEXT("你太贪吃了,都咬到自己了!你是否要重新开始?"), TEXT("Snake"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
{
SendMessage(hwnd, WM_CREATE, 0, 0);
return;
}
else
SendMessage(hwnd, WM_CLOSE, 0, 0);
}
if (snake.iHead == MAX * MAX - 1)
for (int i = 0, j = snake.iTail; j <= snake.iHead; ++i, ++j)
snake.bodys[i] = snake.bodys[j];
snake.bodys[snake.iBodyNum] = newBody;
snake.iBodyNum += 1;
snake.iHead += 1;
//InvalidateRect(hwnd, NULL, TRUE);
}
VOID FindSnakeRgn(HWND hwnd, Snake & snake)
{
hRgnSnake = CreateRectRgn(0, 0, 0, 0);
for (int i = snake.iTail; i <= snake.iHead; ++i)
{
hRgnNewBody = CreateRectRgn(snake.bodys[i].x * iRectSide, snake.bodys[i].y * iRectSide, (snake.bodys[i].x + 1) * iRectSide, (snake.bodys[i].y + 1) * iRectSide);
CombineRgn(hRgnSnake, hRgnNewBody, hRgnSnake, RGN_OR);
}
//InvalidateRect(hwnd, NULL, TRUE);
}
VOID ThrowBean(HWND hwnd, SnakeBody & bean)
{
loop:
bean.x = rand() % MAX;
bean.y = rand() % MAX;
for (int i = snake.iTail; i <= snake.iHead; ++i)
if(bean.x == snake.bodys[i].x && bean.y == snake.bodys[i].y)
goto loop;
hRgnBean = CreateRectRgn(bean.x * iRectSide, bean.y * iRectSide, (bean.x + 1) * iRectSide, (bean.y + 1) * iRectSide);
//InvalidateRect(hwnd, NULL, TRUE);
}
version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' \
language='*'\"")
#include <windows.h>
const int MAX = 35;
const int INITIALLENGTH = 19;
const int iRectSide = 20;
const int IDT_TIMER1 = 1;
const int IDT_TIMER2 = 2;
enum SnakeDirection
{
UP = 0,
DOWN = 1,
LEFT = 2,
RIGHT = 3,
};
enum SnakeStatus
{
STOP = 0,
RUN = 1,
PAUSE = 2,
};
struct SnakeBody
{
int x;
int y;
};
struct Snake
{
SnakeDirection direction;
SnakeStatus status;
int iBodyNum;
int iHead;
int iTail;
SnakeBody bodys[MAX * MAX];
};
static Snake snake;
static SnakeBody bean;
static SnakeDirection keyboardInput = RIGHT;
static HRGN hRgnSnake;
static HRGN hRgnBean;
static HRGN hRgnEmpty = CreateRectRgn(0, 0, 0, 0);
HRGN hRgnNewBody;
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Snake"); // 添加
HWND hwnd;
MSG msg;
WNDCLASSEX wndclassex = {0};
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.lpfnWndProc = WndProc;
wndclassex.cbClsExtra = 0;
wndclassex.cbWndExtra = 0;
wndclassex.hInstance = hInstance;
wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclassex.lpszMenuName = NULL;
wndclassex.lpszClassName = szAppName;
wndclassex.hIconSm = wndclassex.hIcon;
if (!RegisterClassEx (&wndclassex))
{
MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,
szAppName,
TEXT ("Snake"), // 添加
WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
CW_USEDEFAULT,
CW_USEDEFAULT,
(MAX + 1) * iRectSide,
(MAX + 2) * iRectSide,
NULL,
NULL,
hInstance,
NULL);
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
VOID CreateSnake(HWND hwnd, Snake & snake);
VOID RunSnake(HWND hwnd, Snake & snake, SnakeBody & bean);
VOID FindSnakeRgn(HWND hwnd, Snake & snake);
VOID ThrowBean(HWND hwnd, SnakeBody & bean);
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HBRUSH hBrushGray = (HBRUSH) GetStockObject(GRAY_BRUSH);
HBRUSH hBrushGreen = CreateSolidBrush(RGB(0, 255, 0));
static int cxClient, cyClient;
switch (message)
{
case WM_CREATE:
hdc = GetDC (hwnd);
CreateSnake(hwnd, snake);
ReleaseDC (hwnd, hdc);
ThrowBean(hwnd, bean);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
for (int x = 1; x <= MAX; ++x)
{
MoveToEx(hdc, x * iRectSide, 0, NULL);
LineTo(hdc, x * iRectSide, MAX * iRectSide);
}
for (int y = 1; y <= MAX; ++y)
{
MoveToEx(hdc, 0, y * iRectSide, NULL);
LineTo(hdc, MAX * iRectSide, y * iRectSide);
}
FindSnakeRgn(hwnd, snake);
SelectObject(hdc, hRgnSnake);
FillRgn(hdc, hRgnSnake, hBrushGray);
SelectObject(hdc, hRgnBean);
FillRgn(hdc, hRgnBean, hBrushGreen);
EndPaint (hwnd, &ps);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_SPACE:
if (snake.status == PAUSE)
{
SetTimer(hwnd, IDT_TIMER2, 200, NULL);
snake.status = RUN;
}
else
{
KillTimer(hwnd, IDT_TIMER2);
snake.status = PAUSE;
}
break;
case VK_UP:
keyboardInput = UP;
break;
case VK_DOWN:
keyboardInput = DOWN;
break;
case VK_LEFT:
keyboardInput = LEFT;
break;
case VK_RIGHT:
keyboardInput = RIGHT;
break;
}
return 0;
case WM_TIMER:
if(snake.status)
{
RunSnake(hwnd, snake, bean);
InvalidateRect(hwnd, NULL, TRUE);
}
return 0;
case WM_CLOSE:
snake.status = PAUSE;
KillTimer(hwnd, IDT_TIMER2);
if(IDYES == MessageBox(hwnd, TEXT("你真的不玩了吗?"), TEXT("Snake"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
DestroyWindow(hwnd);
return 0;
case WM_DESTROY:
DeleteObject(hBrushGray);
DeleteObject(hBrushGreen);
DeleteObject(hRgnSnake);
DeleteObject(hRgnBean);
DeleteObject(hRgnEmpty);
DeleteObject(hRgnNewBody);
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
VOID CreateSnake(HWND hwnd, Snake & snake)
{
snake.status = PAUSE;
snake.direction = RIGHT;
snake.iBodyNum = INITIALLENGTH;
snake.iHead = INITIALLENGTH - 1;
snake.iTail = 0;
hRgnSnake = hRgnEmpty;
for (int i = 0; i < INITIALLENGTH; ++i)
{
snake.bodys[i].x = (MAX - INITIALLENGTH) / 2 - 1 + i;
snake.bodys[i].y = MAX / 2;
hRgnNewBody = CreateRectRgn(snake.bodys[i].x * iRectSide, snake.bodys[i].y * iRectSide, (snake.bodys[i].x + 1) * iRectSide, (snake.bodys[i].y + 1) * iRectSide);
CombineRgn(hRgnSnake, hRgnNewBody, hRgnSnake, RGN_OR);
}
//InvalidateRect(hwnd, NULL, TRUE);
}
VOID RunSnake(HWND hwnd, Snake & snake, SnakeBody & bean)
{
SnakeBody newBody, oldBody, tempBody;
switch (keyboardInput)
{
case UP:
if(snake.direction != DOWN)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y - 1;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
case DOWN:
if(snake.direction != UP)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y + 1;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
case LEFT:
if(snake.direction != RIGHT)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x - 1;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
case RIGHT:
if(snake.direction != LEFT)
{
tempBody.x = snake.bodys[snake.iBodyNum - 1].x + 1;
tempBody.y = snake.bodys[snake.iBodyNum - 1].y;
snake.direction = keyboardInput;
}
else
tempBody = snake.bodys[snake.iBodyNum - 1];
break;
}
newBody.x = (tempBody.x + MAX) % MAX;
newBody.y = (tempBody.y + MAX) % MAX;
oldBody = snake.bodys[snake.iTail];
if(newBody.x == bean.x && newBody.y == bean.y)
{
snake.iBodyNum += 1;
hRgnBean = hRgnEmpty;
ThrowBean(hwnd, bean);
}
else
snake.iTail += 1;
for (int i = snake.iTail; i < snake.iHead; ++i)
if(newBody.x == snake.bodys[i].x && newBody.y == snake.bodys[i].y)
{
snake.status = STOP;
if(IDYES == MessageBox(hwnd, TEXT("你太贪吃了,都咬到自己了!你是否要重新开始?"), TEXT("Snake"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
{
SendMessage(hwnd, WM_CREATE, 0, 0);
return;
}
else
SendMessage(hwnd, WM_CLOSE, 0, 0);
}
if (snake.iHead == MAX * MAX - 1)
for (int i = 0, j = snake.iTail; j <= snake.iHead; ++i, ++j)
snake.bodys[i] = snake.bodys[j];
snake.bodys[snake.iBodyNum] = newBody;
snake.iBodyNum += 1;
snake.iHead += 1;
//InvalidateRect(hwnd, NULL, TRUE);
}
VOID FindSnakeRgn(HWND hwnd, Snake & snake)
{
hRgnSnake = CreateRectRgn(0, 0, 0, 0);
for (int i = snake.iTail; i <= snake.iHead; ++i)
{
hRgnNewBody = CreateRectRgn(snake.bodys[i].x * iRectSide, snake.bodys[i].y * iRectSide, (snake.bodys[i].x + 1) * iRectSide, (snake.bodys[i].y + 1) * iRectSide);
CombineRgn(hRgnSnake, hRgnNewBody, hRgnSnake, RGN_OR);
}
//InvalidateRect(hwnd, NULL, TRUE);
}
VOID ThrowBean(HWND hwnd, SnakeBody & bean)
{
loop:
bean.x = rand() % MAX;
bean.y = rand() % MAX;
for (int i = snake.iTail; i <= snake.iHead; ++i)
if(bean.x == snake.bodys[i].x && bean.y == snake.bodys[i].y)
goto loop;
hRgnBean = CreateRectRgn(bean.x * iRectSide, bean.y * iRectSide, (bean.x + 1) * iRectSide, (bean.y + 1) * iRectSide);
//InvalidateRect(hwnd, NULL, TRUE);
}