|
100鱼币
代码如下
- #include <windows.h>
- #include <time.h>
- #include <stdlib.h>
- //定义4个方向
- #define UP 1 //向上,蛇头y坐标不断减小
- #define DOWN 2 //向下,蛇头y坐标不断增大
- #define LEFT 3 //向左,蛇头x坐标不断减小
- #define RIGHT 4 //向右,蛇头x坐标不断增大
- #define SNAKEWIDTH 10 //单节蛇的大小
- #define XWIDTH 20 //游戏区的宽度
- #define YHEIGHT 20 //游戏区的高度
- #define GETSCORE 10 //吃一个食物的得分
- #define ID_TIMER 1 //定时器ID
- #define TIMERSET 600 //定时间隔
- static int direct = RIGHT; //方向(注:方向由蛇头决定)
- static int Score; //吃到的食物数量
- bool IsOver = false, bEat = false;
- struct Snake
- {
- Snake() :next(NULL), before(NULL)
- {
- pt.x = 0; pt.y = 0;
- }
- Snake(const POINT &npt, Snake *, Snake *);
- POINT pt;
- Snake * next, *before;
- } snake; //定义蛇头
- Snake::Snake(const POINT &npt, Snake * nnext, Snake * nbefore) :
- pt(npt), next(nnext), before(nbefore) {}
- Snake * psLast = NULL, *food = NULL;
- bool GameClient[XWIDTH][YHEIGHT]; //定义游戏区坐标布尔值,表示相应点的蛇身以及是否有食物。
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- TCHAR szAppName[] = TEXT("Snake"),
- szWindowName[] = TEXT("贪吃蛇");
- WNDCLASS wndcls;
- wndcls.cbClsExtra = 0;
- wndcls.cbWndExtra = 0;
- wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndcls.hCursor = LoadCursor(hInstance, IDC_ARROW);
- wndcls.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
- wndcls.hInstance = hInstance;
- wndcls.lpfnWndProc = WndProc;
- wndcls.lpszClassName = szAppName;
- wndcls.lpszMenuName = NULL;
- wndcls.style = CS_HREDRAW | CS_VREDRAW;
- RegisterClass(&wndcls);
- HWND hwnd = CreateWindow(szAppName, szWindowName,
- WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU,
- CW_USEDEFAULT, CW_USEDEFAULT, (XWIDTH + 10) * SNAKEWIDTH, (YHEIGHT + 5) * SNAKEWIDTH,
- NULL, NULL, hInstance, NULL);
- ShowWindow(hwnd, nCmdShow);
- UpdateWindow(hwnd);
- MSG msg;
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
- //新食物刷新
- void NewFood(HWND hwnd)
- {
- food = new Snake();
- SYSTEMTIME st;
- GetLocalTime(&st);
- srand(st.wMilliseconds);
- food->pt.x = rand() % XWIDTH, food->pt.y = rand() % YHEIGHT;
- while (GameClient[food->pt.x][food->pt.y])
- {
- GetLocalTime(&st);
- srand(st.wMilliseconds);
- food->pt.x = rand() % XWIDTH, food->pt.y = rand() % YHEIGHT;
- }
- GameClient[food->pt.x][food->pt.y] = true;
- InvalidateRect(hwnd, NULL, TRUE);
- }
- //判断前方是否是食物
- inline bool IsFood()
- {
- if (snake.pt.x == food->pt.x && snake.pt.y == food->pt.y)
- return true;
- else
- return false;
- }
- //判断是否撞墙或者撞到自己身体
- bool TouchWall()
- {
- Snake * temp = psLast;
- //超越边界判断
- if (snake.pt.x >= XWIDTH ||
- snake.pt.x < 0 ||
- snake.pt.y < 0 ||
- snake.pt.y >= YHEIGHT)
- return true;
- //碰撞自身身体判断
- while (temp != &snake)
- {
- if (snake.pt.x == temp->pt.x &&
- snake.pt.y == temp->pt.y)
- return true;
- temp = temp->before;
- }
- return false;
- }
- void Move(HWND hwnd)
- {
- int x, y; //用于记录蛇头的当前位置(未前进时)
- //标记前方是否为食物,默认为不是食物,表示系通常的前进
- Snake * temp = psLast;
- //记录蛇头当前坐标
- x = snake.pt.x;
- y = snake.pt.y;
- //测试前进的地方是否是食物,同时将蛇头前进
- switch (direct)
- {
- case UP:
- --snake.pt.y;
- break;
- case DOWN:
- ++snake.pt.y;
- break;
- case LEFT:
- --snake.pt.x;
- break;
- case RIGHT:
- ++snake.pt.x;
- break;
- default:
- break;
- }
- //如果不是食物,作如下处理
- if (!IsFood())
- {
- //最后一节不是蛇头
- if (temp != &snake)
- {
- GameClient[temp->pt.x][temp->pt.y] = false;
- while (temp != snake.next)
- {
- temp->pt.x = temp->before->pt.x;
- temp->pt.y = temp->before->pt.y;
- temp = temp->before;
- }
- temp->pt.x = x;
- temp->pt.y = y;
- GameClient[temp->pt.x][temp->pt.y] = true;
- }
- else //psLast == &snake,即蛇只有蛇头
- GameClient[x][y] = false;
- if (TouchWall())
- IsOver = true; //则标记游戏结束
- else
- GameClient[snake.pt.x][snake.pt.y] = true; //不然移动后的蛇头位置标记为有方块了
- InvalidateRect(hwnd, NULL, TRUE); //刷新游戏区
- }
- //如果是食物,作如下处理
- else
- {
- ++Score;
- food->before = psLast;
- psLast->next = food;
- if (temp != &snake)
- {
- food->pt.x = psLast->pt.x;
- food->pt.y = psLast->pt.y;
- while (temp != snake.next)
- {
- temp->pt.x = temp->before->pt.x;
- temp->pt.y = temp->before->pt.y;
- temp = temp->before;
- }
- temp->pt.x = x;
- temp->pt.y = y;
- }
- else //psLast == &snake,即蛇只有蛇头
- {
- food->pt.x = x; food->pt.y = y;
- }
- psLast = food;
- NewFood(hwnd);
- }
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc;
- PAINTSTRUCT ps;
- TEXTMETRIC tm;
- static int cxChar, cyChar;
- TCHAR szScore[] = TEXT("得分:"),
- szGameOver[] = TEXT("游戏结束!"),
- szPause[] = TEXT("游戏暂停!"),
- szBuffer[20],
- *szText = NULL;
- int x, y;
- static bool pause = false;
- switch (message)
- {
- case WM_CREATE:
- direct = RIGHT; //游戏开局,默认方向向右
- snake.pt.x = XWIDTH / 2; //默认显示在游戏区中间位置
- snake.pt.y = YHEIGHT / 2;
- psLast = &snake;
- GameClient[snake.pt.x][snake.pt.y] = true;
- hdc = GetDC(hwnd);
- GetTextMetrics(hdc, &tm);
- cyChar = tm.tmExternalLeading + tm.tmHeight;
- ReleaseDC(hwnd, hdc);
- NewFood(hwnd);
- SetTimer(hwnd, ID_TIMER, TIMERSET, NULL);
- return 0;
- case WM_TIMER:
- if (pause) return 0;
- Move(hwnd);
- if (IsOver)
- {
- KillTimer(hwnd, ID_TIMER);
- InvalidateRect(hwnd, NULL, TRUE);
- }
- return 0;
- case WM_KEYDOWN:
- if (IsOver || pause) return 0;
- switch (wParam)
- {
- case VK_UP:
- if (direct != DOWN)
- {
- direct = UP;
- Move(hwnd);
- }
- break;
- case VK_DOWN:
- if (direct != UP)
- {
- direct = DOWN;
- Move(hwnd);
- }
- break;
- case VK_LEFT:
- if (direct != RIGHT)
- {
- direct = LEFT;
- Move(hwnd);
- }
- break;
- case VK_RIGHT:
- if (direct != LEFT)
- {
- direct = RIGHT;
- Move(hwnd);
- }
- break;
- default:
- break;
- }
- return 0;
- case WM_CHAR:
- if (IsOver && wParam != 'r') return 0;
- switch (wParam)
- {
- case 'p':
- {
- pause = !pause;
- InvalidateRect(hwnd, NULL, TRUE);
- }
- break;
- case 'r':
- {
- for (int x = 0; x < XWIDTH; ++x)
- for (int y = 0; y < YHEIGHT; ++y)
- GameClient[x][y] = false;
- }
- SetTimer(hwnd, ID_TIMER, TIMERSET, NULL);
- direct = RIGHT; //游戏开局,默认方向向右
- snake.pt.x = XWIDTH / 2; //默认显示在游戏区中间位置
- snake.pt.y = YHEIGHT / 2;
- psLast = &snake;
- IsOver = false;
- pause = false;
- GameClient[snake.pt.x][snake.pt.y] = true;
- NewFood(hwnd);
- break;
- default:
- break;
- }
- return 0;
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- SetViewportOrgEx(hdc, SNAKEWIDTH, SNAKEWIDTH, NULL);
- //画游戏区的边框
- MoveToEx(hdc, -1, -1, NULL);
- LineTo(hdc, XWIDTH * SNAKEWIDTH + 1, -1);
- LineTo(hdc, XWIDTH * SNAKEWIDTH + 1, YHEIGHT * SNAKEWIDTH + 1);
- LineTo(hdc, -1, YHEIGHT * SNAKEWIDTH + 1);
- LineTo(hdc, -1, -1);
- TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, 0, szScore, lstrlen(szScore));
- TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, cyChar,
- szBuffer, wsprintf(szBuffer, TEXT("%4d"), Score));
- if (pause)
- TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, 3 * cyChar, szPause, lstrlen(szPause));
- else if (IsOver)
- TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, 3 * cyChar, szGameOver, lstrlen(szGameOver));
- SelectObject(hdc, GetStockObject(BLACK_BRUSH));
- for (x = 0; x < XWIDTH; ++x)
- {
- for (y = 0; y < YHEIGHT; ++y)
- {
- if (GameClient[x][y])
- Rectangle(hdc, x * SNAKEWIDTH, y * SNAKEWIDTH,
- (x + 1) * SNAKEWIDTH, (y + 1) * SNAKEWIDTH);
- }
- }
- return 0;
- case WM_DESTROY:
- KillTimer(hwnd, ID_TIMER);
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
复制代码
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
复制代码
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
复制代码
这两句看不懂,想问一下,这部分需要补充什么内容的知识,然后这个代码我的编译器会报一些编译错误,他的main函数在哪里?
这是windows编程的内容,后面的MFC框架的基础
你可以去简单学习一下windows编程设计课程
|
最佳答案
查看完整内容
这是windows编程的内容,后面的MFC框架的基础
你可以去简单学习一下windows编程设计课程
|