Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <vector>
- TCHAR AppName[] = TEXT("Szalona piłka");
- // funkcja rozszerzająca zwykłą rand o losowanie z przedziału ujemnych
- int random(int min, int max)
- {
- int Random;
- // losujemy w pętli, jeśli losuje 0, bo piłka utknie w miejscu wtedy
- while ((Random = min + (rand() / (RAND_MAX / (max - min) ) ) ) == 0);
- return Random;
- }
- class ball
- {
- private:
- int _x; // współrzędna X lewego górnego punktu (początek rysowania
- int _y; // współrzędna Y lewego górnego punktu (początek rysowania
- int _size; // średnica piłki, dodając ją do X i Y otrzymujemy drugi punkt
- int _przesuniecieX; // jednostkowe przesunięcię piłki po osi X
- int _przesuniecieY; // jednostkowe przesunięcię piłki po osi Y
- COLORREF _kolor; // kolor piłki
- public:
- ball() {};
- //Settery
- void Set_x(const int x) {
- _x = x;
- };
- void Set_y(const int y) {
- _y = y;
- };
- void Set_size(const int size) {
- _size = size;
- };
- void Set_przesuniecieX(const int przesuniecieX) {
- _przesuniecieX = przesuniecieX;
- };
- void Set_przesuniecieY(const int przesuniecieY) {
- _przesuniecieY = przesuniecieY;
- };
- void Set_kolor(COLORREF kolor)
- {
- _kolor = kolor;
- }
- //Gettery
- const int Get_x() {
- return _x;
- };
- const int Get_y() const {
- return _y;
- };
- const int Get_size() const {
- return _size;
- };
- const int Get_przesuniecieX() const {
- return _przesuniecieX;
- };
- const int Get_przesuniecieY() const {
- return _przesuniecieY;
- };
- const COLORREF Get_kolor() const {
- return _kolor;
- };
- BOOLEAN TouchTop(const RECT &r) {
- if (_y <= r.top)
- {
- _y = r.top;
- return TRUE;
- }
- else return FALSE;
- };
- BOOLEAN TouchBottom(const RECT &r) {
- if ((_y + _size) >= r.bottom)
- {
- _y = r.bottom - _size;
- return TRUE;
- }
- else return FALSE;
- };
- BOOLEAN TouchLeft(const RECT &r) {
- if (_x <= r.left)
- {
- _x = r.left;
- return TRUE;
- }
- else return FALSE;
- };
- BOOLEAN TouchRight(const RECT &r) {
- if ((_x + _size) >= r.right)
- {
- _x = r.right - _size;
- return TRUE;
- }
- else return FALSE;
- };
- // sprawdza czy pilka znajduje sie w obszarze klienckim
- //oraz czy koliduje z sciankami;
- void odbicia(const RECT &ClientRect)
- {
- _x += _przesuniecieX;
- _y += _przesuniecieY;
- if (TouchBottom(ClientRect) == TRUE) {
- _przesuniecieX = random(-10, 10);
- _przesuniecieY = random(-10, -1);
- }
- if (TouchRight(ClientRect) == TRUE) {
- _przesuniecieX = random(-1, -10);
- _przesuniecieY = random(-10, 10);
- }
- if (TouchLeft(ClientRect) == TRUE) {
- _przesuniecieX = random(1, 10);
- _przesuniecieY = random(-10, 10);
- }
- if (TouchTop(ClientRect) == TRUE) {
- _przesuniecieX = random(-10, 10);
- _przesuniecieY = random(1, 10);
- }
- };
- };
- // dodaje pilki do wektora
- void Pilki_dodaj(std::vector<ball> &pilka, const int numer, const RECT &ClientRect)
- {
- int i = pilka.size();
- const int end = i + numer;
- for (i; i < end; i++)
- {
- pilka.push_back(ball());
- pilka[i].Set_x(random(20, ClientRect.right - 100));
- pilka[i].Set_y(random(20, ClientRect.bottom - 100));
- pilka[i].Set_size(random(20, 100));
- pilka[i].Set_przesuniecieX(random(-5, 5));
- pilka[i].Set_przesuniecieY(random(-5, 5));
- pilka[i].Set_kolor(RGB(rand() % 255, rand() % 255, rand() % 255) );
- }
- }
- // sprawdzanie czy kliknięto w piłkę
- BOOLEAN klikniecie(ball &pilka, const int x, const int y, const HDC &hdc) {
- if (GetPixel(hdc, x, y) == pilka.Get_kolor())
- {
- if (x >= pilka.Get_x() && x <= (pilka.Get_x() + pilka.Get_size()) && y >= pilka.Get_y() && y <= (pilka.Get_y() + pilka.Get_size()))
- {
- return TRUE;
- }
- }
- else return FALSE;
- };
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HDC hdc = GetDC(hwnd);
- static int IdTimer = 1;
- static RECT ClientRect;
- GetClientRect(hwnd, &ClientRect);
- static std::vector <ball> pilki;// tablica pilek
- static HBRUSH brush = (HBRUSH)GetStockObject(DC_BRUSH); // brush stockowy
- switch (message)
- {
- case WM_CREATE:
- {
- Pilki_dodaj(pilki, 1, ClientRect);// dodanie 'n' piłek
- SetWindowTextA(hwnd, "LPM - Dodanie kola \t\t PPM - Usuniecie kola");
- SetTimer(hwnd, IdTimer, 10, NULL); // timer co 10 ms
- }break;
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdcBuffor; // buffor, w którym rysujemy piłki, a potem gotowy rysunek przenosimy do oryginalnego HDC
- HBITMAP bitmapBuffor; // to jest jakby "płótno" HDC po którym się rysuje
- HANDLE bitmapOld; // uchwyt do poprzedniej bitmapy w hdcBuffor, trzeba o nim pamietać bo należy go zwolnić
- BeginPaint(hwnd, &ps);
- // tworzymy kompatybilny kontekst urządzenia
- hdcBuffor = CreateCompatibleDC(ps.hdc); // tworzymy kompatybilny kontekst HDC do oryginału
- bitmapBuffor = CreateCompatibleBitmap(ps.hdc, ClientRect.right, ClientRect.bottom); // kompatybilną bitmapę o takich smaych wymiarach
- bitmapOld = SelectObject(hdcBuffor, bitmapBuffor); // nanosimy kompatybilną bitmapę na kompatybilne HDC, a starą bitmapę przypisujemy do uchwytu
- FillRect(hdcBuffor, &ClientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
- for (int i = 0; i < pilki.size(); i++)
- {
- SetDCBrushColor(hdcBuffor, pilki[i].Get_kolor());
- SelectObject(hdcBuffor, brush);
- 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());
- }
- // przekopiowujemy gotowy obraz z naniesionymi wszystkimi piłkami z kompatybilnego HDC do oryginalnego, bo wtedy dopiero się pojawi na ekranie
- BitBlt(ps.hdc, ClientRect.left, ClientRect.top, ClientRect.right, ClientRect.bottom, hdcBuffor, 0, 0, SRCCOPY);
- //przypisujemy starą bitmapę na powrót to kompatybilnego HDC, żeby potem ją zwolnić razem z tym HDC
- SelectObject(hdcBuffor, bitmapOld);
- DeleteObject(bitmapBuffor);
- DeleteDC(hdcBuffor);
- EndPaint(hwnd, &ps);
- }break;
- case WM_RBUTTONDOWN:
- {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- for (int i = 0; i < pilki.size();i++)
- {
- if (klikniecie(pilki[i], x, y, hdc) == TRUE)
- {
- pilki.erase(pilki.begin() + i);
- break;
- }
- }
- }break;
- case WM_LBUTTONDOWN:
- {
- Pilki_dodaj(pilki, 1, ClientRect);
- }break;
- case WM_TIMER:
- {
- switch (wParam)
- {
- case 1:
- {
- for (int i = 0; i < pilki.size(); i++)
- {
- pilki[i].odbicia(ClientRect); // co 10 ms zmienia polozenie pilki
- }
- InvalidateRect(hwnd, NULL, FALSE);
- }break;
- }
- }break;
- case WM_CLOSE:
- KillTimer(hwnd, IdTimer);
- pilki.clear();
- ReleaseDC(hwnd, hdc);
- DestroyWindow(hwnd);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return (DefWindowProc(hwnd, message, wParam, lParam));
- }
- return (0);
- }
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- MSG msg;
- WNDCLASS wndclass;
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WindowProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = NULL;
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = AppName;
- if (RegisterClass(&wndclass) == 0)
- return FALSE;
- HWND hwnd = CreateWindow(AppName, AppName, WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
- if (hwnd == NULL)
- return FALSE;
- while (GetMessage(&msg, NULL, 0, 0) > 0)
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return (int)msg.wParam;
- }
Advertisement