Advertisement
alien_fx_fiend

GPT4 Mini Mod Curated Source

Jul 23rd, 2024
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.51 KB | None | 0 0
  1. #include <windows.h>
  2. #include <vector>
  3. #include <cmath>
  4. #include <ctime>
  5.  
  6. #define ID_TIMER 1
  7. #define BALL_RADIUS 10
  8. #define TABLE_WIDTH 800
  9. #define TABLE_HEIGHT 400
  10.  
  11. HINSTANCE hInst;
  12. HWND hwnd;
  13. HDC hdcMem, hdcBall;
  14. HBITMAP hbmMem, hbmOld;
  15. HPEN hPen;
  16. HBRUSH hBrush;
  17. RECT table = { 50, 50, 850, 450 };
  18. POINT cueStart, cueEnd;
  19. bool isDragging = false;
  20. float power = 0.0f;
  21.  
  22. struct Ball {
  23.     float x, y;
  24.     float vx, vy;
  25.     COLORREF color;
  26.     bool isPocketed;
  27. };
  28.  
  29. enum class PlayerColor {
  30.     None,
  31.     Solids,
  32.     Stripes,
  33. };
  34.  
  35. std::vector<Ball> balls;
  36. Ball cueBall;
  37. bool playerTurn = true;
  38. bool gameOver = false;
  39. PlayerColor playerColor = PlayerColor::None;
  40.  
  41. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  42. void InitBalls();
  43. void DrawTable(HDC);
  44. void DrawBalls(HDC);
  45. void DrawCue(HDC);
  46. void DrawPowerMeter(HDC);
  47. void UpdateBalls();
  48. void CheckCollisions();
  49. void CheckPockets();
  50. void AIMove();
  51. void ApplyEnglish(Ball&, float, float);
  52. bool CheckGameOver();
  53.  
  54. int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow) {
  55.     hInst = hInstance;
  56.     WNDCLASS wc = {};
  57.     wc.lpfnWndProc = WndProc;
  58.     wc.hInstance = hInstance;
  59.     wc.lpszClassName = L"8BallPool";
  60.     RegisterClass(&wc);
  61.  
  62.     hwnd = CreateWindowEx(0, L"8BallPool", L"8-Ball Pool", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 900, 600, nullptr, nullptr, hInstance, nullptr);
  63.     ShowWindow(hwnd, nCmdShow);
  64.  
  65.     MSG msg = {};
  66.     while (GetMessage(&msg, nullptr, 0, 0)) {
  67.         TranslateMessage(&msg);
  68.         DispatchMessage(&msg);
  69.     }
  70.     return (int)msg.wParam;
  71. }
  72.  
  73. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  74.     switch (message) {
  75.     case WM_CREATE:
  76.         srand((unsigned int)time(NULL));
  77.         InitBalls();
  78.         SetTimer(hwnd, ID_TIMER, 16, NULL);
  79.         break;
  80.     case WM_PAINT: {
  81.         PAINTSTRUCT ps;
  82.         HDC hdc = BeginPaint(hwnd, &ps);
  83.         if (!hdcMem) {
  84.             hdcMem = CreateCompatibleDC(hdc);
  85.             hbmMem = CreateCompatibleBitmap(hdc, 900, 600);
  86.             hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
  87.         }
  88.         FillRect(hdcMem, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
  89.         DrawTable(hdcMem);
  90.         DrawBalls(hdcMem);
  91.         if (!gameOver && playerTurn) {
  92.             DrawCue(hdcMem);
  93.             DrawPowerMeter(hdcMem);
  94.         }
  95.         BitBlt(hdc, 0, 0, 900, 600, hdcMem, 0, 0, SRCCOPY);
  96.         EndPaint(hwnd, &ps);
  97.         break;
  98.     }
  99.     case WM_LBUTTONDOWN:
  100.         if (gameOver || !playerTurn) break;
  101.  
  102.         if (LOWORD(lParam) >= 10 && LOWORD(lParam) <= 30 && HIWORD(lParam) >= 10 && HIWORD(lParam) <= 50) {
  103.             cueStart.x = 20;
  104.             cueStart.y = 30;
  105.         } else {
  106.             cueStart.x = LOWORD(lParam);
  107.             cueStart.y = HIWORD(lParam);
  108.         }
  109.         isDragging = true;
  110.         break;
  111.     case WM_MOUSEMOVE:
  112.         if (isDragging) {
  113.             if (cueStart.x == 20 && cueStart.y == 30) {
  114.                 cueStart.x = 20;
  115.                 cueStart.y = 30;
  116.             } else {
  117.                 cueEnd.x = LOWORD(lParam);
  118.                 cueEnd.y = HIWORD(lParam);
  119.                 power = min(sqrt(pow(cueEnd.x - cueStart.x, 2) + pow(cueEnd.y - cueStart.y, 2)) / 100.0f, 1.0f);
  120.                 InvalidateRect(hwnd, NULL, FALSE);
  121.             }
  122.         }
  123.         break;
  124.     case WM_LBUTTONUP:
  125.         if (isDragging) {
  126.             isDragging = false;
  127.             float dx = cueEnd.x - cueStart.x;
  128.             float dy = cueEnd.y - cueStart.y;
  129.             cueBall.vx = dx * power * 0.5f;
  130.             cueBall.vy = dy * power * 0.5f;
  131.             ApplyEnglish(cueBall, dx * power * 0.1f, dy * power * 0.1f);
  132.             playerTurn = false;
  133.             InvalidateRect(hwnd, NULL, FALSE);
  134.         }
  135.         break;
  136.     case WM_TIMER:
  137.         if (!gameOver) {
  138.             UpdateBalls();
  139.             CheckCollisions();
  140.             CheckPockets();
  141.             if (!playerTurn) AIMove();
  142.             if (CheckGameOver()) {
  143.                 gameOver = true;
  144.                 MessageBox(hwnd, L"Game Over! All balls are pocketed.", L"Game Over", MB_OK);
  145.             }
  146.             InvalidateRect(hwnd, NULL, FALSE);
  147.         }
  148.         break;
  149.     case WM_DESTROY:
  150.         KillTimer(hwnd, ID_TIMER);
  151.         SelectObject(hdcMem, hbmOld);
  152.         DeleteObject(hbmMem);
  153.         DeleteDC(hdcMem);
  154.         PostQuitMessage(0);
  155.         break;
  156.     default:
  157.         return DefWindowProc(hwnd, message, wParam, lParam);
  158.     }
  159.     return 0;
  160. }
  161.  
  162. void InitBalls() {
  163.     balls.clear();
  164.    
  165.     cueBall = { 450.0f, 250.0f, 0.0f, 0.0f, RGB(255, 255, 255), false };
  166.     balls.push_back(cueBall);
  167.     balls.push_back({ 600.0f, 250.0f, 0.0f, 0.0f, RGB(0, 0, 0), false });
  168.  
  169.     const float baseX = 600.0f;
  170.     const float baseY = 250.0f;
  171.     const float offset = 30.0f;
  172.  
  173.     balls[0].x = baseX;
  174.  
  175.     balls.push_back({ baseX - offset, baseY + offset, 0.0f, 0.0f, RGB(255, 255, 0), false });
  176.     balls.push_back({ baseX + offset, baseY + offset, 0.0f, 0.0f, RGB(255, 0, 0), false });
  177.  
  178.     balls.push_back({ baseX - 2 * offset, baseY + 2 * offset, 0.0f, 0.0f, RGB(255, 255, 0), false });
  179.     balls.push_back({ baseX, baseY + 2 * offset, 0.0f, 0.0f, RGB(255, 0, 0), false });
  180.     balls.push_back({ baseX + 2 * offset, baseY + 2 * offset, 0.0f, 0.0f, RGB(255, 255, 0), false });
  181.  
  182.     balls.push_back({ baseX - 3 * offset, baseY + 3 * offset, 0.0f, 0.0f, RGB(255, 0, 0), false });
  183.     balls.push_back({ baseX - offset, baseY + 3 * offset, 0.0f, 0.0f, RGB(255, 255, 0), false });
  184.     balls.push_back({ baseX + offset, baseY + 3 * offset, 0.0f, 0.0f, RGB(255, 0, 0), false });
  185.     balls.push_back({ baseX + 3 * offset, baseY + 3 * offset, 0.0f, 0.0f, RGB(255, 255, 0), false });
  186. }
  187.  
  188. void DrawTable(HDC hdc) {
  189.     HBRUSH hBrush = CreateSolidBrush(RGB(0, 128, 0));
  190.     FillRect(hdc, &table, hBrush);
  191.     DeleteObject(hBrush);
  192.  
  193.     HPEN hPenRed = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
  194.     SelectObject(hdc, hPenRed);
  195.     Rectangle(hdc, table.left, table.top, table.right, table.bottom);
  196.     DeleteObject(hPenRed);
  197.  
  198.     HBRUSH hBrushBlack = CreateSolidBrush(RGB(0, 0, 0));
  199.     SelectObject(hdc, hBrushBlack);
  200.     for (int i = 0; i < 2; ++i) {
  201.         for (int j = 0; j < 3; ++j) {
  202.             Ellipse(hdc, table.left + j * TABLE_WIDTH / 2 - BALL_RADIUS, table.top + i * TABLE_HEIGHT - BALL_RADIUS, table.left + j * TABLE_WIDTH / 2 + BALL_RADIUS, table.top + i * TABLE_HEIGHT + BALL_RADIUS);
  203.         }
  204.     }
  205.     DeleteObject(hBrushBlack);
  206. }
  207.  
  208. void DrawBalls(HDC hdc) {
  209.     for (const auto& ball : balls) {
  210.         if (!ball.isPocketed) {
  211.             hBrush = CreateSolidBrush(ball.color);
  212.             SelectObject(hdc, hBrush);
  213.             Ellipse(hdc, (int)(ball.x - BALL_RADIUS), (int)(ball.y - BALL_RADIUS), (int)(ball.x + BALL_RADIUS), (int)(ball.y + BALL_RADIUS));
  214.             DeleteObject(hBrush);
  215.         }
  216.     }
  217. }
  218.  
  219. void DrawCue(HDC hdc) {
  220.     MoveToEx(hdc, (int)cueBall.x, (int)cueBall.y, NULL);
  221.     LineTo(hdc, cueEnd.x, cueEnd.y);
  222.  
  223.     float dx = cueEnd.x - cueBall.x;
  224.     float dy = cueEnd.y - cueBall.y;
  225.     float length = sqrt(dx * dx + dy * dy);
  226.     if (length > 0) {
  227.         dx /= length;
  228.         dy /= length;
  229.     }
  230.  
  231.     float aimBallX = cueBall.x + dx * 100;
  232.     float aimBallY = cueBall.y + dy * 100;
  233.  
  234.     MoveToEx(hdc, cueBall.x, cueBall.y, NULL);
  235.     LineTo(hdc, aimBallX, aimBallY);
  236.  
  237.     for (const auto& ball : balls) {
  238.         if (!ball.isPocketed) {
  239.             float ballEdgeX = ball.x + (BALL_RADIUS * dx);
  240.             float ballEdgeY = ball.y + (BALL_RADIUS * dy);
  241.             float distToBall = sqrt(pow(ball.x - cueBall.x, 2) + pow(ball.y - cueBall.y, 2));
  242.             if (distToBall < 100 + BALL_RADIUS) {
  243.                 MoveToEx(hdc, ballEdgeX, ballEdgeY, NULL);
  244.                 LineTo(hdc, ballEdgeX + dx * 10, ballEdgeY + dy * 10);
  245.             }
  246.         }
  247.     }
  248. }
  249.  
  250. void DrawPowerMeter(HDC hdc) {
  251.     HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
  252.     RECT rect = { 10, 50, 30, 450 };
  253.     FillRect(hdc, &rect, hBrush);
  254.     DeleteObject(hBrush);
  255.  
  256.     hBrush = CreateSolidBrush(RGB(255, 255, 0));
  257.     rect.bottom = 450 - (int)(400 * power);
  258.     FillRect(hdc, &rect, hBrush);
  259.     DeleteObject(hBrush);
  260.  
  261.     hBrush = CreateSolidBrush(RGB(255, 0, 0));
  262.     rect.bottom = 450 - (int)(400 * power / 2);
  263.     FillRect(hdc, &rect, hBrush);
  264.     DeleteObject(hBrush);
  265.  
  266.     const int ballX = 20;
  267.     const int ballY = 30;
  268.     hBrush = CreateSolidBrush(RGB(255, 255, 255));
  269.     SelectObject(hdc, hBrush);
  270.     Ellipse(hdc, ballX - BALL_RADIUS * 2, ballY - BALL_RADIUS * 2, ballX + BALL_RADIUS * 2, ballY + BALL_RADIUS * 2);
  271.     DeleteObject(hBrush);
  272. }
  273.  
  274. void UpdateBalls() {
  275.     for (auto& ball : balls) {
  276.         if (!ball.isPocketed) {
  277.             ball.x += ball.vx;
  278.             ball.y += ball.vy;
  279.             ball.vx *= 0.99f;
  280.             ball.vy *= 0.99f;
  281.             if (fabs(ball.vx) < 0.01f) ball.vx = 0.0f;
  282.             if (fabs(ball.vy) < 0.01f) ball.vy = 0.0f;
  283.         }
  284.     }
  285. }
  286.  
  287. void CheckCollisions() {
  288.     for (size_t i = 0; i < balls.size(); ++i) {
  289.         for (size_t j = i + 1; j < balls.size(); ++j) {
  290.             Ball& b1 = balls[i];
  291.             Ball& b2 = balls[j];
  292.  
  293.             if (!b1.isPocketed && !b2.isPocketed) {
  294.                 float dx = b2.x - b1.x;
  295.                 float dy = b2.y - b1.y;
  296.                 float dist = sqrt(dx * dx + dy * dy);
  297.                 if (dist < BALL_RADIUS * 2) {
  298.                     float angle = atan2(dy, dx);
  299.                     float sinA = sin(angle);
  300.                     float cosA = cos(angle);
  301.  
  302.                     float v1 = (b1.vx * cosA + b1.vy * sinA);
  303.                     float v2 = (b2.vx * cosA + b2.vy * sinA);
  304.  
  305.                     b1.vx += v2;
  306.                     b2.vx += v1;
  307.  
  308.                     b1.vx *= 0.9f;
  309.                     b2.vx *= 0.9f;
  310.  
  311.                     b1.vy += v2;
  312.                     b2.vy += v1;
  313.  
  314.                     b1.vy *= 0.9f;
  315.                     b2.vy *= 0.9f;
  316.                 }
  317.             }
  318.         }
  319.     }
  320. }
  321.  
  322. void CheckPockets() {
  323.     for (auto& ball : balls) {
  324.         if (!ball.isPocketed) {
  325.             if (/* condition to check if the ball is pocketed */) {
  326.                 ball.isPocketed = true;
  327.  
  328.                 if (playerColor == PlayerColor::None) {
  329.                     if (ball.color == RGB(255, 0, 0)) {
  330.                         playerColor = PlayerColor::Solids;
  331.                     } else if (ball.color == RGB(255, 255, 0)) {
  332.                         playerColor = PlayerColor::Stripes;
  333.                     }
  334.                 } else {
  335.                     if (playerColor == PlayerColor::Solids && ball.color == RGB(255, 255, 0)) {
  336.                         MessageBox(hwnd, L"You can only pocket your assigned balls!", L"Invalid Shot", MB_OK);
  337.                         ball.isPocketed = false;
  338.                         return;
  339.                     } else if (playerColor == PlayerColor::Stripes && ball.color == RGB(255, 0, 0)) {
  340.                         MessageBox(hwnd, L"You can only pocket your assigned balls!", L"Invalid Shot", MB_OK);
  341.                         ball.isPocketed = false;
  342.                         return;
  343.                     }
  344.                 }
  345.             }
  346.         }
  347.     }
  348. }
  349.  
  350. void AIMove() {
  351.     // Simple AI logic for making a move; implement as needed
  352. }
  353.  
  354. void ApplyEnglish(Ball& ball, float ex, float ey) {
  355.     // Apply English effect to the ball; implement as needed
  356. }
  357.  
  358. bool CheckGameOver() {
  359.     for (const auto& ball : balls) {
  360.         if (!ball.isPocketed) return false;
  361.     }
  362.     return true;
  363. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement