Hyluss

Szalona piłka

Jan 3rd, 2017
855
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <windows.h>
  2. #include <vector>
  3. TCHAR AppName[] = TEXT("Szalona piłka");
  4.  
  5. // funkcja rozszerzająca zwykłą rand o losowanie z przedziału ujemnych
  6. int random(int min, int max)
  7. {
  8.     int Random;
  9.     // losujemy w pętli, jeśli losuje 0, bo piłka utknie w miejscu wtedy
  10.     while  ((Random = min + (rand() / (RAND_MAX / (max - min) ) ) ) == 0);
  11.     return Random;
  12. }
  13. class ball
  14. {
  15. private:
  16.     int _x; // współrzędna X lewego górnego punktu (początek rysowania
  17.     int _y; // współrzędna Y lewego górnego punktu (początek rysowania
  18.     int _size;  // średnica piłki, dodając ją do X i Y otrzymujemy drugi punkt
  19.     int _przesuniecieX; // jednostkowe przesunięcię piłki po osi X
  20.     int _przesuniecieY; // jednostkowe przesunięcię piłki po osi Y
  21.     COLORREF _kolor;    // kolor piłki
  22. public:
  23.     ball() {};
  24.     //Settery
  25.     void Set_x(const int x) {
  26.         _x = x;
  27.     };
  28.     void Set_y(const int y) {
  29.         _y = y;
  30.     };
  31.     void Set_size(const int size) {
  32.         _size = size;
  33.     };
  34.     void Set_przesuniecieX(const int przesuniecieX) {
  35.         _przesuniecieX = przesuniecieX;
  36.     };
  37.     void Set_przesuniecieY(const int przesuniecieY) {
  38.         _przesuniecieY = przesuniecieY;
  39.     };
  40.     void Set_kolor(COLORREF kolor)
  41.     {
  42.         _kolor = kolor;
  43.     }
  44.     //Gettery
  45.     const int Get_x() {
  46.         return _x;
  47.     };
  48.     const int Get_y() const {
  49.         return _y;
  50.     };
  51.     const int Get_size() const {
  52.         return _size;
  53.     };
  54.     const int Get_przesuniecieX() const {
  55.         return _przesuniecieX;
  56.     };
  57.     const int Get_przesuniecieY() const {
  58.         return _przesuniecieY;
  59.     };
  60.     const COLORREF Get_kolor() const {
  61.         return _kolor;
  62.     };
  63.  
  64.     BOOLEAN TouchTop(const RECT &r) {
  65.         if (_y <= r.top)
  66.         {
  67.             _y = r.top;
  68.             return TRUE;
  69.         }
  70.         else return FALSE;
  71.     };
  72.     BOOLEAN TouchBottom(const RECT &r) {
  73.         if ((_y + _size) >= r.bottom)
  74.         {
  75.             _y = r.bottom - _size;
  76.             return TRUE;
  77.         }
  78.         else return FALSE;
  79.     };
  80.     BOOLEAN TouchLeft(const RECT &r) {
  81.         if (_x <= r.left)
  82.         {
  83.             _x = r.left;
  84.             return TRUE;
  85.         }
  86.         else return FALSE;
  87.     };
  88.     BOOLEAN TouchRight(const RECT &r) {
  89.         if ((_x + _size) >= r.right)
  90.         {
  91.             _x = r.right - _size;
  92.             return TRUE;
  93.         }
  94.         else return FALSE;
  95.     };
  96.     // sprawdza czy pilka znajduje sie w obszarze klienckim
  97.     //oraz czy koliduje z sciankami;
  98.     void odbicia(const RECT &ClientRect)
  99.     {
  100.         _x += _przesuniecieX;
  101.         _y += _przesuniecieY;
  102.  
  103.         if (TouchBottom(ClientRect) == TRUE) {
  104.             _przesuniecieX = random(-10, 10);
  105.             _przesuniecieY = random(-10, -1);
  106.         }
  107.         if (TouchRight(ClientRect) == TRUE) {
  108.             _przesuniecieX = random(-1, -10);
  109.             _przesuniecieY = random(-10, 10);
  110.         }
  111.         if (TouchLeft(ClientRect) == TRUE) {
  112.             _przesuniecieX = random(1, 10);
  113.             _przesuniecieY = random(-10, 10);
  114.         }
  115.         if (TouchTop(ClientRect) == TRUE) {
  116.             _przesuniecieX = random(-10, 10);
  117.             _przesuniecieY = random(1, 10);
  118.         }
  119.     };
  120. };
  121. // dodaje pilki do wektora
  122. void Pilki_dodaj(std::vector<ball> &pilka, const int numer, const RECT &ClientRect)
  123. {
  124.     int i = pilka.size();
  125.     const int end = i + numer;
  126.     for (i; i < end; i++)
  127.     {
  128.         pilka.push_back(ball());
  129.         pilka[i].Set_x(random(20, ClientRect.right - 100));
  130.         pilka[i].Set_y(random(20, ClientRect.bottom - 100));
  131.         pilka[i].Set_size(random(20, 100));
  132.         pilka[i].Set_przesuniecieX(random(-5, 5));
  133.         pilka[i].Set_przesuniecieY(random(-5, 5));
  134.         pilka[i].Set_kolor(RGB(rand() % 255, rand() % 255, rand() % 255) );
  135.     }
  136. }
  137. // sprawdzanie czy kliknięto w piłkę
  138. BOOLEAN klikniecie(ball &pilka, const int x, const int y, const HDC &hdc) {
  139.     if (GetPixel(hdc, x, y) == pilka.Get_kolor())
  140.     {
  141.         if (x >= pilka.Get_x() && x <= (pilka.Get_x() + pilka.Get_size()) && y >= pilka.Get_y() && y <= (pilka.Get_y() + pilka.Get_size()))
  142.         {
  143.             return TRUE;
  144.         }
  145.     }
  146.     else return FALSE;
  147. };
  148.  
  149. LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  150. {
  151.     static HDC hdc = GetDC(hwnd);
  152.     static int IdTimer = 1;
  153.     static RECT ClientRect;
  154.     GetClientRect(hwnd, &ClientRect);
  155.     static std::vector <ball> pilki;// tablica pilek
  156.     static HBRUSH brush = (HBRUSH)GetStockObject(DC_BRUSH); // brush stockowy
  157.     switch (message)
  158.     {
  159.         case WM_CREATE:
  160.         {
  161.             Pilki_dodaj(pilki, 1, ClientRect);// dodanie 'n' piłek
  162.             SetWindowTextA(hwnd, "LPM - Dodanie kola \t\t PPM - Usuniecie kola");
  163.             SetTimer(hwnd, IdTimer, 10, NULL); // timer co 10 ms
  164.         }break;
  165.         case WM_PAINT:
  166.         {
  167.             PAINTSTRUCT ps;
  168.             HDC hdcBuffor;  // buffor, w którym rysujemy piłki, a potem gotowy rysunek przenosimy do oryginalnego HDC
  169.             HBITMAP bitmapBuffor; // to jest jakby "płótno" HDC po którym się rysuje
  170.             HANDLE bitmapOld;       // uchwyt do poprzedniej bitmapy w hdcBuffor, trzeba o nim pamietać bo należy go zwolnić
  171.             BeginPaint(hwnd, &ps);
  172.             // tworzymy kompatybilny kontekst urządzenia
  173.             hdcBuffor = CreateCompatibleDC(ps.hdc); // tworzymy kompatybilny kontekst HDC do oryginału
  174.             bitmapBuffor = CreateCompatibleBitmap(ps.hdc, ClientRect.right, ClientRect.bottom); // kompatybilną bitmapę o takich smaych wymiarach
  175.             bitmapOld = SelectObject(hdcBuffor, bitmapBuffor);  // nanosimy kompatybilną bitmapę na kompatybilne HDC, a starą bitmapę przypisujemy do uchwytu
  176.             FillRect(hdcBuffor, &ClientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
  177.  
  178.             for (int i = 0; i < pilki.size(); i++)
  179.             {
  180.                 SetDCBrushColor(hdcBuffor, pilki[i].Get_kolor());
  181.                 SelectObject(hdcBuffor, brush);
  182.                 Ellipse(hdcBuffor, pilki[i].Get_x(), pilki[i].Get_y(), pilki[i].Get_x() + pilki[i].Get_size(), pilki[i].Get_y() + pilki[i].Get_size());
  183.             }
  184.             // przekopiowujemy gotowy obraz z naniesionymi wszystkimi piłkami z kompatybilnego HDC do oryginalnego, bo wtedy dopiero się pojawi na ekranie
  185.             BitBlt(ps.hdc, ClientRect.left, ClientRect.top, ClientRect.right, ClientRect.bottom, hdcBuffor, 0, 0, SRCCOPY);
  186.             //przypisujemy starą bitmapę na powrót to kompatybilnego HDC, żeby potem ją zwolnić razem z tym HDC
  187.             SelectObject(hdcBuffor, bitmapOld);
  188.             DeleteObject(bitmapBuffor);
  189.             DeleteDC(hdcBuffor);
  190.  
  191.             EndPaint(hwnd, &ps);
  192.         }break;
  193.         case WM_RBUTTONDOWN:
  194.         {
  195.             int x = LOWORD(lParam);
  196.             int y = HIWORD(lParam);
  197.             for (int i = 0; i < pilki.size();i++)
  198.             {
  199.                 if (klikniecie(pilki[i], x, y, hdc) == TRUE)
  200.                 {
  201.                     pilki.erase(pilki.begin() + i);
  202.                     break;
  203.                 }
  204.             }
  205.         }break;
  206.         case WM_LBUTTONDOWN:
  207.         {
  208.             Pilki_dodaj(pilki, 1, ClientRect);
  209.         }break;
  210.         case WM_TIMER:
  211.         {
  212.             switch (wParam)
  213.             {
  214.                 case 1:
  215.                 {
  216.                     for (int i = 0; i < pilki.size(); i++)
  217.                     {
  218.                         pilki[i].odbicia(ClientRect); // co 10 ms zmienia polozenie pilki
  219.                     }
  220.                     InvalidateRect(hwnd, NULL, FALSE);
  221.                 }break;
  222.             }
  223.         }break;
  224.         case WM_CLOSE:
  225.             KillTimer(hwnd, IdTimer);
  226.             pilki.clear();
  227.             ReleaseDC(hwnd, hdc);
  228.             DestroyWindow(hwnd);
  229.             break;
  230.  
  231.         case WM_DESTROY:
  232.             PostQuitMessage(0);
  233.             break;
  234.  
  235.         default:
  236.             return (DefWindowProc(hwnd, message, wParam, lParam));
  237.     }
  238.     return (0);
  239. }
  240.  
  241. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  242. {
  243.     MSG msg;
  244.     WNDCLASS wndclass;
  245.  
  246.     wndclass.style = CS_HREDRAW | CS_VREDRAW;
  247.     wndclass.lpfnWndProc = WindowProc;
  248.     wndclass.cbClsExtra = 0;
  249.     wndclass.cbWndExtra = 0;
  250.     wndclass.hInstance = hInstance;
  251.     wndclass.hIcon = NULL;
  252.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  253.     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  254.     wndclass.lpszMenuName = NULL;
  255.     wndclass.lpszClassName = AppName;
  256.  
  257.     if (RegisterClass(&wndclass) == 0)
  258.         return FALSE;
  259.  
  260.     HWND hwnd = CreateWindow(AppName, AppName, WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
  261.  
  262.     if (hwnd == NULL)
  263.         return FALSE;
  264.  
  265.     while (GetMessage(&msg, NULL, 0, 0) > 0)
  266.     {
  267.         TranslateMessage(&msg);
  268.         DispatchMessage(&msg);
  269.     }
  270.     return (int)msg.wParam;
  271. }
Advertisement