peterzig

[PIU] Snake

Nov 8th, 2016
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.76 KB | None | 0 0
  1. #define SCREEN_WIDTH 600
  2. #define SCREEN_HEIGHT 500
  3. #define SQUARE_SIZE 20
  4. #define EAT_SQUARE_SIZE 30
  5. #define SPEED 10
  6.  
  7. #include <Windows.h>
  8. #include <time.h>
  9. #include <deque>
  10. #include <tchar.h>
  11.  
  12. using namespace std;
  13.  
  14. MSG msg;
  15. TCHAR className[] = TEXT("Snake");
  16. HWND hwnd;
  17. RECT clientRect;
  18.  
  19. UINT timer = 250;
  20. UINT score = 0;
  21.  
  22. RECT foodRect;
  23. COLORREF foodColor = RGB(255, 0, 0);
  24. COLORREF greenColor = RGB(0, 255, 0);
  25. COLORREF brownColor = RGB(139, 69, 19);
  26.  
  27. enum DIRECTION {UP, DOWN, LEFT, RIGHT};
  28. DIRECTION direction = UP;
  29.  
  30. struct Container {
  31.     RECT rect;
  32.     RECT safeOldRect;
  33.     COLORREF color;
  34.     DIRECTION direction;
  35.     DIRECTION oldDirection;
  36. };
  37.  
  38. deque<Container> posContainer;
  39.  
  40. void initFood() {
  41.     srand(time(NULL));
  42.  
  43.     foodColor = RGB(rand() % 255, rand() % 255, rand() % 255);
  44.  
  45.     int size = ((rand() % 3) + 2) * 10;
  46.     int x = (rand() % (clientRect.right - clientRect.left - size)) + clientRect.left;
  47.     int y = (rand() % (clientRect.bottom - clientRect.top - size)) + clientRect.top;
  48.  
  49.     foodRect.left = x;
  50.     foodRect.top = y;
  51.     foodRect.right = x + size;
  52.     foodRect.bottom = y + size;
  53. }
  54.  
  55. void initSnake() {
  56.     srand(time(NULL));
  57.  
  58.     int size = SQUARE_SIZE;
  59.     int x = clientRect.left + 300;
  60.     int y = clientRect.top + 300;
  61.  
  62.     Container container;
  63.     container.rect.left = x;
  64.     container.rect.top = y;
  65.     container.rect.right = x + size;
  66.     container.rect.bottom = y + size;
  67.     container.safeOldRect = container.rect;
  68.     container.direction = UP;
  69.     container.oldDirection = UP;
  70.     container.color = brownColor;
  71.  
  72.     posContainer.push_back(container);
  73. }
  74.  
  75. bool checkRectCollision(RECT rect1, RECT rect2) {
  76.     if (rect1.left < rect2.right &&
  77.         rect1.right > rect2.left &&
  78.         rect1.top < rect2.bottom &&
  79.         rect1.bottom > rect2.top) {
  80.         return true;
  81.     }
  82.  
  83.     return false;
  84. }
  85.  
  86. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
  87.     static PAINTSTRUCT ps;
  88.  
  89.     switch (msg)
  90.     {
  91.     case WM_CREATE:
  92.         SetTimer(hwnd, 1, timer, 0);
  93.         GetClientRect(hwnd, &clientRect);
  94.         initFood();
  95.         initSnake();
  96.         break;
  97.  
  98.     case WM_PAINT: {
  99.         HDC hdc = BeginPaint(hwnd, &ps);
  100.  
  101.         HBRUSH brushBox, brush;
  102.         HPEN penBox, pen;
  103.  
  104.         brush = CreateSolidBrush(foodColor);
  105.         brushBox = (HBRUSH)SelectObject(hdc, brush);
  106.  
  107.         pen = CreatePen(PS_SOLID, 1, foodColor);
  108.         penBox = (HPEN)SelectObject(hdc, pen);
  109.  
  110.         Rectangle(hdc, foodRect.left, foodRect.top, foodRect.right, foodRect.bottom);
  111.  
  112.         for (deque<Container>::iterator it = posContainer.begin(); it != posContainer.end(); ++it) {
  113.             brush = CreateSolidBrush(it->color);
  114.             brushBox = (HBRUSH)SelectObject(hdc, brush);
  115.  
  116.             pen = CreatePen(PS_SOLID, 3, it->color);
  117.             penBox = (HPEN)SelectObject(hdc, pen);
  118.  
  119.             Rectangle(hdc, it->rect.left, it->rect.top, it->rect.right, it->rect.bottom);
  120.             SelectObject(hdc, brushBox);
  121.             SelectObject(hdc, penBox);
  122.  
  123.             DeleteObject(brushBox);
  124.             DeleteObject(brush);
  125.             DeleteObject(penBox);
  126.             DeleteObject(pen);
  127.         }
  128.  
  129.         TCHAR buf[128];
  130.         _swprintf(buf, TEXT("SCORE: %i           SIZE: %i \n"), score, posContainer.size());
  131.  
  132.         SetTextColor(hdc, RGB(0, 0, 0));
  133.         TextOut(hdc, 50, 10, buf, wcslen(buf));
  134.  
  135.         EndPaint(hwnd, &ps);
  136.         }break;
  137.  
  138.     case WM_TIMER: {
  139.         posContainer[0].direction = direction;
  140.         posContainer[0].oldDirection = posContainer[0].direction;
  141.  
  142.         int counter = 0;
  143.  
  144.         for (deque<Container>::iterator it = posContainer.begin(); it != posContainer.end(); ++it) {
  145.             switch (it->direction) {
  146.             case UP: {
  147.                 it->rect.top -= (SPEED + SQUARE_SIZE);
  148.                 it->rect.bottom -= (SPEED + SQUARE_SIZE);
  149.  
  150.                 if (it->rect.top < clientRect.top) {
  151.                     it->rect.top = clientRect.bottom - SQUARE_SIZE - 10;
  152.                     it->rect.bottom = clientRect.bottom - 10;
  153.                 }
  154.                 }break;
  155.  
  156.             case DOWN:
  157.                 it->rect.top += (SPEED + SQUARE_SIZE);
  158.                 it->rect.bottom += (SPEED + SQUARE_SIZE);
  159.  
  160.                 if (it->rect.bottom > clientRect.bottom) {
  161.                     it->rect.top = clientRect.top + 10;
  162.                     it->rect.bottom = clientRect.top + SQUARE_SIZE + 10;
  163.                 }
  164.                 break;
  165.  
  166.             case RIGHT:
  167.                 it->rect.left += (SPEED + SQUARE_SIZE);
  168.                 it->rect.right += (SPEED + SQUARE_SIZE);
  169.  
  170.                 if (it->rect.right > clientRect.right) {
  171.                     it->rect.left = clientRect.left + 10;
  172.                     it->rect.right = clientRect.left + SQUARE_SIZE + 10;
  173.                 }
  174.                 break;
  175.  
  176.             case LEFT:
  177.                 it->rect.left -= (SPEED + SQUARE_SIZE);
  178.                 it->rect.right -= (SPEED + SQUARE_SIZE);
  179.  
  180.                 if (it->rect.left < clientRect.left) {
  181.                     it->rect.left = clientRect.right - SQUARE_SIZE - 10;
  182.                     it->rect.right = clientRect.right - 10;
  183.                 }
  184.                 break;
  185.             }
  186.         }
  187.  
  188.         for (UINT i = 1; i < posContainer.size(); i++) {
  189.             posContainer[i].oldDirection = posContainer[i].direction;
  190.             posContainer[i].direction = posContainer[i - 1].oldDirection;
  191.         }
  192.  
  193.         if (checkRectCollision(posContainer[0].rect, foodRect)) {
  194.             initFood();
  195.  
  196.             Container container;
  197.             container.direction = posContainer[posContainer.size() - 1].direction;
  198.  
  199.             if ((posContainer.size() + 1) % 2 == 0)
  200.                 container.color = greenColor;
  201.             else
  202.                 container.color = brownColor;
  203.  
  204.             RECT rect = posContainer[posContainer.size() - 1].rect;
  205.             switch (container.direction) {
  206.                 case UP:
  207.                     rect.top += (SPEED + SQUARE_SIZE);
  208.                     rect.bottom += (SPEED + SQUARE_SIZE);
  209.                     break;
  210.  
  211.                 case DOWN:
  212.                     rect.top -= (SPEED + SQUARE_SIZE);
  213.                     rect.bottom -= (SPEED + SQUARE_SIZE);
  214.                     break;
  215.  
  216.                 case RIGHT:
  217.                     rect.left -= (SPEED + SQUARE_SIZE);
  218.                     rect.right -= (SPEED + SQUARE_SIZE);
  219.                     break;
  220.  
  221.                 case LEFT:
  222.                     rect.left += (SPEED + SQUARE_SIZE);
  223.                     rect.right += (SPEED + SQUARE_SIZE);
  224.                     break;
  225.             }
  226.  
  227.             container.rect = rect;
  228.             posContainer.push_back(container);
  229.  
  230.            
  231.  
  232.             if (timer > 30) {
  233.                 timer -= 10;
  234.                 SetTimer(hwnd, 1, timer, 0);
  235.             }
  236.  
  237.             score += (300 - timer);
  238.         }
  239.  
  240.         if(posContainer.size() > 1)
  241.             for (deque<Container>::iterator it = posContainer.begin() + 1; it != posContainer.end(); ++it)
  242.                 if (checkRectCollision(posContainer[0].rect, it->rect)) {
  243.                     posContainer.clear();
  244.                     initSnake();
  245.                     timer = 250;
  246.  
  247.                     SetTimer(hwnd, 1, timer, 0);
  248.                     break;
  249.                 }
  250.  
  251.         InvalidateRect(hwnd, NULL, 1);
  252.         }break;
  253.  
  254.     case WM_KEYDOWN:
  255.         switch ((int)wParam) {
  256.             case VK_UP:
  257.                 direction = UP;
  258.                 break;
  259.  
  260.             case VK_DOWN:
  261.                 direction = DOWN;
  262.                 break;
  263.  
  264.             case VK_RIGHT:
  265.                 direction = RIGHT;
  266.                 break;
  267.  
  268.             case VK_LEFT:
  269.                 direction = LEFT;
  270.                 break;
  271.         }
  272.         break;
  273.  
  274.     case WM_DESTROY:
  275.         PostQuitMessage(0);
  276.         break;
  277.  
  278.     case WM_CLOSE:
  279.         DestroyWindow(hwnd);
  280.         break;
  281.  
  282.     default:
  283.         return DefWindowProc(hwnd, msg, wParam, lParam);
  284.     }
  285.  
  286.     return 0;
  287. }
  288.  
  289. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  290. {
  291.     WNDCLASSEX wc;
  292.     wc.cbSize = sizeof(WNDCLASSEX);
  293.     wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
  294.     wc.cbClsExtra = 0;
  295.     wc.cbWndExtra = 0;
  296.     wc.hInstance = hInstance;
  297.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  298.     wc.lpfnWndProc = WndProc;
  299.     wc.lpszClassName = className;
  300.     wc.lpszMenuName = NULL;
  301.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  302.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  303.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  304.  
  305.     if (!RegisterClassEx(&wc))
  306.     {
  307.         MessageBox(NULL, TEXT("Nie udało się zarejestrować klasy okna!"), TEXT("Error 404"), MB_OK | MB_ICONERROR);
  308.         return 1;
  309.     }
  310.  
  311.     hwnd = CreateWindowEx(0, className, TEXT("Snake"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT,NULL, NULL, hInstance, NULL);
  312.     if (hwnd == NULL){
  313.         MessageBox(NULL, TEXT("Nie udało się utworzyć okna !"), TEXT("CreateWindowEx"), MB_OK | MB_ICONERROR);
  314.         return 1;
  315.     }
  316.  
  317.     ShowWindow(hwnd, nCmdShow);
  318.     UpdateWindow(hwnd);
  319.  
  320.     while (GetMessage(&msg, NULL, 0, 0))
  321.     {
  322.         TranslateMessage(&msg);
  323.         DispatchMessage(&msg);
  324.     }
  325.  
  326.     UnregisterClass(className, hInstance);
  327.  
  328.     return msg.wParam;
  329. }
Add Comment
Please, Sign In to add comment