Advertisement
peterzig

[PIU] Snake v2

Nov 22nd, 2016
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.96 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #define SCREEN_WIDTH 600
  3. #define SCREEN_HEIGHT 600
  4. #define SCALE 20
  5. #define TIMER_ID 1
  6. #define MAP_X 30
  7. #define MAP_Y 30
  8. #define START_X MAP_X/2
  9. #define START_Y MAP_Y/2
  10.  
  11. #include <windows.h>
  12. #include <deque>
  13.  
  14. TCHAR className[] = TEXT("Class");
  15. TCHAR appName[] = TEXT("SNAKE");
  16.  
  17. HWND hwnd;
  18. MSG msg;
  19.  
  20. enum DIRECTION { UP, RIGHT, DOWN, LEFT, STOP };
  21. DIRECTION direction = STOP;
  22.  
  23. COLORREF snakeColor = RGB(0, 192, 0);
  24. COLORREF foodColor = RGB(192, 0, 0);
  25.  
  26. struct Body {
  27.     DIRECTION direction;
  28.     DIRECTION saveOldDirection;
  29.     UINT x;
  30.     UINT y;
  31. };
  32.  
  33. std::deque<Body> body;
  34.  
  35. void initHead() {
  36.     Body b;
  37.  
  38.     b.x = START_X;
  39.     b.y = START_Y;
  40.     b.direction = b.saveOldDirection = direction;
  41.  
  42.     body.push_back(b);
  43. }
  44.  
  45. void initFood(UINT& foodX, UINT& foodY) {
  46.     foodX = rand() % MAP_X;
  47.     foodY = rand() % MAP_Y;
  48. }
  49.  
  50. void initBrushesAndPens(HBRUSH& snakeBrush, HBRUSH& foodBrush, HBRUSH& blackBrush, HPEN& snakePen, HPEN& foodPen, HPEN& blackPen) {
  51.     snakeBrush = CreateSolidBrush(snakeColor);
  52.     snakePen = CreatePen(PS_SOLID, 1, snakeColor);
  53.  
  54.     foodBrush = CreateSolidBrush(foodColor);
  55.     foodPen = CreatePen(PS_SOLID, 1, foodColor);
  56.  
  57.     blackBrush = CreateSolidBrush(RGB(0, 0, 0));
  58.     blackPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
  59. }
  60.  
  61. void initNextSegment() {
  62.     DIRECTION direction;
  63.     UINT x = 0, y = 0;
  64.  
  65.     if (body.empty()) {
  66.         direction = body[0].direction;
  67.         x = body[0].x;
  68.         y = body[0].y;
  69.     }
  70.     else {
  71.         direction = body.at(body.size() - 1).direction;
  72.         x = body[body.size() - 1].x;
  73.         y = body[body.size() - 1].y;
  74.     }
  75.  
  76.     switch (direction) {
  77.     case UP:    y++;    break;
  78.  
  79.     case RIGHT: x--;    break;
  80.  
  81.     case DOWN:  y--;    break;
  82.  
  83.     case LEFT:  x++;    break;
  84.     }
  85.  
  86.     Body b;
  87.     b.direction = b.saveOldDirection = direction;
  88.     b.x = x;
  89.     b.y = y;
  90.  
  91.     body.push_back(b);
  92. }
  93.  
  94. void movePoint(Body& body) {
  95.     switch (body.direction) {
  96.     case UP:    body.y--;   break;
  97.  
  98.     case RIGHT: body.x++;   break;
  99.  
  100.     case DOWN:  body.y++;   break;
  101.  
  102.     case LEFT:  body.x--;   break;
  103.     }
  104. }
  105.  
  106. void drawMapLines(const HDC hdc) {
  107.     for (UINT i = 0; i <= MAP_X; i++) {
  108.         MoveToEx(hdc, i * SCALE, 0, NULL);
  109.         LineTo(hdc, i * SCALE, MAP_Y * SCALE);
  110.     }
  111.  
  112.     for (UINT i = 0; i <= MAP_Y; i++) {
  113.         MoveToEx(hdc, 0, i * SCALE, NULL);
  114.         LineTo(hdc, MAP_X * SCALE, i * SCALE);
  115.     }
  116. }
  117.  
  118. void drawPauseInformation(bool pause) {
  119.     if (pause) {
  120.         HDC hdc = GetDC(hwnd);
  121.  
  122.         const int bufSize = 64;
  123.         TCHAR buf[bufSize];
  124.         _swprintf(buf, TEXT("Pałza skurwisyny"), bufSize);
  125.  
  126.         TextOut(hdc, (MAP_X * SCALE) / 2, (MAP_Y * SCALE) / 2, buf, wcslen(buf));
  127.  
  128.         ReleaseDC(hwnd, hdc);
  129.     }
  130. }
  131.  
  132. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  133.     static RECT clientRect;
  134.     static UINT foodX, foodY;
  135.     static PAINTSTRUCT ps;
  136.     static HBRUSH snakeBrush, foodBrush, blackBrush;
  137.     static HPEN snakePen, foodPen, blackPen;
  138.     static bool pause = false;
  139.  
  140.     switch (msg) {
  141.     case WM_CREATE: {
  142.         SetTimer(hwnd, TIMER_ID, 50, 0);
  143.         initHead();
  144.         initFood(foodX, foodY);
  145.         initBrushesAndPens(snakeBrush, foodBrush, blackBrush, snakePen, foodPen, blackPen);
  146.         GetClientRect(hwnd, &clientRect);
  147.     }break;
  148.  
  149.     case WM_SIZE:
  150.         GetClientRect(hwnd, &clientRect);
  151.         InvalidateRect(hwnd, NULL, 1);
  152.         break;
  153.  
  154.     case WM_TIMER: {
  155.         body[0].direction = body[0].saveOldDirection = direction;
  156.  
  157.         if (!pause && direction != STOP) {
  158.             if (body.size() > 0)
  159.                 for (std::deque<Body>::iterator it = body.begin(); it != body.end(); ++it)
  160.                     movePoint(*it);
  161.  
  162.             if (body.size() > 0)
  163.                 for (std::deque<Body>::iterator it = body.begin() + 1; it != body.end(); ++it) {
  164.                     it->saveOldDirection = it->direction;
  165.                     it->direction = (it - 1)->saveOldDirection;
  166.                 }
  167.  
  168.             if (body[0].x == foodX && body[0].y == foodY) {
  169.                 initNextSegment();
  170.                 initFood(foodX, foodY);
  171.             }
  172.  
  173.             if (body.size() > 0)
  174.                 for (std::deque<Body>::iterator it = body.begin() + 1; it != body.end(); ++it)
  175.                     if (body[0].x == it->x && body[0].y == it->y) {
  176.                         body.clear();
  177.                         initHead();
  178.                         break;
  179.                     }
  180.  
  181.             if (body[0].x < 0 || body[0].x >= MAP_X || body[0].y < 0 || body[0].y >= MAP_Y) {
  182.                 body.clear();
  183.                 direction = STOP;
  184.                 initHead();
  185.             }
  186.  
  187.             InvalidateRect(hwnd, NULL, 1);
  188.         }
  189.     }break;
  190.  
  191.     case WM_PAINT: {
  192.         HDC hdc = BeginPaint(hwnd, &ps);
  193.  
  194.         SetMapMode(hdc, MM_ANISOTROPIC);
  195.         SetViewportExtEx(hdc, clientRect.right, clientRect.bottom, NULL);
  196.         SetViewportOrgEx(hdc, 0, 0, NULL);
  197.         SetWindowExtEx(hdc, MAP_X * SCALE, MAP_Y * SCALE, NULL);
  198.         SetWindowOrgEx(hdc, 0, 0, NULL);
  199.  
  200.         SelectObject(hdc, foodBrush);
  201.         SelectObject(hdc, foodPen);
  202.  
  203.         Rectangle(hdc, foodX * SCALE, foodY * SCALE, (foodX + 1) * SCALE, (foodY + 1) * SCALE);
  204.  
  205.         SelectObject(hdc, snakeBrush);
  206.         SelectObject(hdc, snakePen);
  207.  
  208.         if (body.size() > 0)
  209.             for (std::deque<Body>::iterator it = body.begin(); it != body.end(); ++it)
  210.                 Rectangle(hdc, it->x * SCALE, it->y * SCALE, (it->x + 1) * SCALE, (it->y + 1) * SCALE);
  211.  
  212.         SelectObject(hdc, blackBrush);
  213.         SelectObject(hdc, blackPen);
  214.  
  215.         drawMapLines(hdc);
  216.  
  217.         EndPaint(hwnd, &ps);
  218.     }break;
  219.  
  220.     case WM_KEYDOWN:
  221.         switch ((int)wParam) {
  222.         case VK_UP:
  223.             if (direction != DOWN)
  224.                 direction = UP;
  225.             break;
  226.  
  227.         case VK_DOWN:
  228.             if (direction != UP)
  229.                 direction = DOWN;
  230.             break;
  231.  
  232.         case VK_RIGHT:
  233.             if (direction != LEFT)
  234.                 direction = RIGHT;
  235.             break;
  236.  
  237.         case VK_LEFT:
  238.             if (direction != RIGHT)
  239.                 direction = LEFT;
  240.             break;
  241.  
  242.         case 0x50:
  243.             pause = !pause;
  244.             drawPauseInformation(pause);
  245.             break;
  246.         }
  247.         break;
  248.  
  249.     case WM_CLOSE:  DestroyWindow(hwnd);    break;
  250.  
  251.     case WM_DESTROY: {
  252.         DeleteObject(foodBrush);
  253.         DeleteObject(foodPen);
  254.         DeleteObject(blackBrush);
  255.         DeleteObject(blackPen);
  256.         DeleteObject(snakeBrush);
  257.         DeleteObject(snakePen);
  258.  
  259.         KillTimer(hwnd, TIMER_ID);
  260.         PostQuitMessage(0);
  261.     }break;
  262.  
  263.     default:    return DefWindowProc(hwnd, msg, wParam, lParam);
  264.     }
  265.  
  266.     return 0;
  267. }
  268.  
  269. INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  270. {
  271.     WNDCLASSEX wc;
  272.     wc.cbSize = sizeof(WNDCLASSEX);
  273.     wc.style = 0;
  274.     wc.cbClsExtra = 0;
  275.     wc.cbWndExtra = 0;
  276.     wc.hInstance = hInstance;
  277.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 3);
  278.     wc.lpfnWndProc = WndProc;
  279.     wc.lpszClassName = className;
  280.     wc.lpszMenuName = NULL;
  281.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  282.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  283.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  284.  
  285.     if (RegisterClassEx(&wc) == 0) {
  286.         MessageBox(NULL, TEXT("Some problem with RegisterClassEx"), className, MB_OK);
  287.         return 1;
  288.     }
  289.  
  290.     hwnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_CLIENTEDGE, className, appName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, hInstance, 0);
  291.     if (hwnd == NULL) {
  292.         MessageBox(NULL, TEXT("Some problem with CreateWindowEx"), className, MB_OK);
  293.         return 1;
  294.     }
  295.  
  296.     ShowWindow(hwnd, nCmdShow);
  297.     UpdateWindow(hwnd);
  298.  
  299.     while (GetMessage(&msg, NULL, 0, 0) > 0)
  300.     {
  301.         TranslateMessage(&msg);
  302.         DispatchMessage(&msg);
  303.     }
  304.  
  305.     UnregisterClass(className, hInstance);
  306.  
  307.     return msg.wParam;
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement