- // <Copyright liaoqb>
- #include <windows.h>
- #include <stdlib.h>
- #include <time.h>
- const int LENGTH = 40;
- const int WIDTH = 10;
- const int RANGE = 50;
- const int BeginLength = 5;
- const int speed = 300;
- #define SNAKE_COLOR RGB(176, 196, 222)
- #define BACKGROUND_COLOR RGB(255, 255, 0)
- #define DRAW_SNAKE(x) (x) * WIDTH
- enum IsSnake {isSnake, isNotSnake, isFood};
- IsSnake map[LENGTH][LENGTH];
- struct snake {
- int x;
- int y;
- snake* next;
- snake(int x, int y, snake* n = NULL) {
- this -> x = x;
- this -> y = y;
- next = n;
- }
- }; // snake
- typedef struct snake Snake;
- Snake* head = NULL; // queue
- Snake* tail = NULL; // queue
- int direct = 0; // direction
- RECT playground; // district
- TCHAR szAppName[] = TEXT("-*- snake game -* "); // The project name
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // message function
- void Initializer();
- void Controller(Snake*); // control the snake
- void Move(HWND);
- void PutFood();
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, PSTR szCmdLine, int iCmdShow) {
- MSG msg;
- HWND hwnd;
- WNDCLASS wndclass;
- while (TRUE) {
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hInstance = hInstance;
- wndclass.lpfnWndProc = WndProc;
- wndclass.lpszClassName = szAppName;
- wndclass.lpszMenuName = NULL;
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- if (!RegisterClass(&wndclass)) {
- MessageBox(NULL, TEXT("Please try again!!!"), szAppName, MB_ICONERROR);
- return 0;
- }
- break;
- }
- hwnd = CreateWindow(szAppName, TEXT("<^_^> Snake Game <^_^>"), WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL);
- ShowWindow(hwnd, SW_NORMAL);
- UpdateWindow(hwnd);
- while (TRUE) {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT)
- break;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- } else {
- Move(hwnd);
- }
- }
- return msg.wParam;
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
- HDC hdc;
- PAINTSTRUCT ps;
- HBRUSH hBrush;
- switch (message) {
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- case WM_CREATE:
- Initializer();
- MoveWindow(hwnd, RANGE, RANGE, WIDTH * LENGTH + RANGE * 3, WIDTH * LENGTH + RANGE * 3, TRUE);
- return 0;
- case WM_KEYDOWN:
- switch (wParam) {
- case VK_LEFT:
- if (direct != VK_RIGHT)
- direct = VK_LEFT;
- break;
- case VK_RIGHT:
- if (direct != VK_LEFT)
- direct = VK_RIGHT;
- break;
- case VK_UP:
- if (direct != VK_DOWN)
- direct = VK_UP;
- break;
- case VK_DOWN:
- if (direct != VK_UP)
- direct = VK_DOWN;
- break;
- default:
- break;
- }
- return 0;
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- SetViewportOrgEx(hdc, RANGE, RANGE, NULL);
- hBrush = CreateSolidBrush(BACKGROUND_COLOR);
- SelectObject(hdc, hBrush);
- Rectangle(hdc,playground.left, playground.top, playground.right, playground.bottom);
- DeleteObject(hBrush);
- hBrush = CreateSolidBrush(SNAKE_COLOR);
- SelectObject(hdc,hBrush);
- for (int i = 0; i < LENGTH; ++i) {
- for (int j = 0; j < LENGTH; ++j) {
- if (map[i][j] == isSnake || map[i][j] == isFood) {
- Rectangle(hdc, DRAW_SNAKE(i), DRAW_SNAKE(j), DRAW_SNAKE(i + 1), DRAW_SNAKE(j + 1));
- }
- }
- }
- DeleteObject(hBrush);
- EndPaint(hwnd, &ps);
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- void Initializer() {
- for (int i = 0; i < LENGTH; ++i) {
- for (int j = 0; j < LENGTH; ++j) {
- map[i][j] = isNotSnake;
- }
- }
- for (int i = 0; i < BeginLength; ++i) {
- if (i == 0) {
- head = tail = new snake(i, 0);
- } else {
- snake* temp = new snake(i, 0);
- tail -> next = temp;
- tail = temp;
- }
- map[i][0] = isSnake;
- }
- playground.left = playground.top = 0;
- playground.right = playground.bottom = WIDTH * LENGTH;
- direct = VK_RIGHT;
- PutFood();
- }
- void PutFood() {
- srand(static_cast<unsigned>(time(NULL)));
- int x, y;
- do {
- x = rand() % LENGTH;
- y = rand() % LENGTH;
- } while (map[x][y] == isSnake);
- map[x][y] = isFood;
- } // put food
- void Move(HWND hwnd) {
- snake* temp;
- switch (direct) {
- case VK_LEFT:
- temp = new snake(tail -> x - 1, tail -> y);
- break;
- case VK_RIGHT:
- temp = new snake(tail -> x + 1, tail -> y);
- break;
- case VK_UP:
- temp = new snake(tail -> x, tail -> y - 1);
- break;
- case VK_DOWN:
- temp = new snake(tail -> x, tail -> y + 1);
- break;
- }
- Controller(temp);
- InvalidateRect(hwnd,NULL,FALSE);
- Sleep(speed); // control speed
- } // snake moving
- void Controller(Snake* temp) {
- if (temp -> x < 0 || temp -> x >= LENGTH || temp -> y < 0 || temp -> y >= LENGTH
- || map[temp -> x][temp -> y] == isSnake) { // the snake is died
- MessageBox(NULL,TEXT("<Copyright liaoqb> Sorry !!! Game Over !!! <Copyright liaoqb>"),szAppName,0);
- delete temp;
- while (head != NULL) {
- Snake* ptr = head;
- head = head -> next;
- delete ptr;
- }
- head = tail = temp = NULL;
- Initializer();
- return;
- } else if (map[temp -> x][temp -> y] == isNotSnake) { // move
- map[temp -> x][temp -> y] = isSnake;
- map[head -> x][head -> y] = isNotSnake;
- snake* ptr = head;
- head = head -> next;
- delete ptr;
- tail -> next = temp;
- tail = temp;
- } else { // if eat food
- map[temp -> x][temp -> y] = isSnake;
- tail -> next = temp;
- tail = temp;
- PutFood();
- }
- }
- //该片段来自于http://www.codesnippet.cn/detail/0708201410169.html
来源: http://www.codesnippet.cn/detail/0708201410169.html