windows Win 32 API弹跳球

f45qwnt8  于 2023-06-07  发布在  Windows
关注(0)|答案(1)|浏览(120)

这是我的代码关于球boucning在程序窗口,我想每次我点击球,一个新的球被创建,作为旧的球形状和移动屏幕上的程序是一样的。

#include <windows.h>
#include <vector>
#include<random>
LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam,
    LPARAM lParam);

struct Ball
{
    RECT rect; // Tọa độ của quả bóng
    int dX; // Tốc độ di chuyển theo trục X
    int dY; // Tốc độ di chuyển theo trục Y
};

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreInst,
    LPSTR lpszCmdLine, int nCmdShow)
{
    HWND hWnd;
    MSG msg;
    WNDCLASSEX wc;

    //fill the WNDCLASSEX structure with the appropriate values
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon(NULL, IDI_EXCLAMATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "WINCLASS";
    wc.hIconSm = LoadIcon(NULL, IDI_EXCLAMATION);

    //register the new class
    RegisterClassEx(&wc);

    //create a window
    hWnd = CreateWindowEx(
        NULL,
        "WINCLASS",
        "My First Window",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInst,
        NULL
    );

    //event loop - handle all messages
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    //standard return value
    return (msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam,
    LPARAM lParam)
{
    static int dX = 5, dY = 5;
    static int x = 0, y = 0, oldX = 0, oldY = 0;
    static std::vector<Ball> balls; // Danh sách quả bóng
    HDC hDC;
    HBRUSH brush;

    //find out which message is being sent
    switch (nMsg)
    {
    case WM_CREATE:
        SetTimer(hWnd, 1, 20, NULL);
        break;

    case WM_TIMER:
    {
        hDC = GetDC(hWnd);
        brush = (HBRUSH)SelectObject(hDC, GetStockObject(WHITE_BRUSH));

        RECT clientRect;
        GetClientRect(hWnd, &clientRect);

        for (size_t i = 0; i < balls.size(); i++)
        {
            Ball& ball1 = balls[i];
            FillRect(hDC, &ball1.rect, brush);
            OffsetRect(&ball1.rect, ball1.dX, ball1.dY);

            RECT temp; // Khai báo biến temp ở đây

            // Kiểm tra va chạm với các quả bóng khác
            for (size_t j = i + 1; j < balls.size(); j++)
            {
                Ball& ball2 = balls[j];

                if (IntersectRect(&temp, &ball1.rect, &ball2.rect))
                {
                    // Xử lý va chạm và thay đổi hướng di chuyển
                    ball1.dX = -ball1.dX;
                    ball1.dY = -ball1.dY;

                    ball2.dX = -ball2.dX;
                    ball2.dY = -ball2.dY;
                }
            }

            // Kiểm tra va chạm với cửa sổ
            if (ball1.rect.right > clientRect.right || ball1.rect.left < 0)
            {
                ball1.dX = -ball1.dX;
            }
            if (ball1.rect.bottom > clientRect.bottom || ball1.rect.top < 0)
            {
                ball1.dY = -ball1.dY;
            }

            brush = (HBRUSH)SelectObject(hDC, GetStockObject(GRAY_BRUSH));
            Ellipse(hDC, ball1.rect.left, ball1.rect.top, ball1.rect.right, ball1.rect.bottom);
        }

        ReleaseDC(hWnd, hDC);
    }
    break;

    break;

    case WM_DESTROY:
        //end timer
        KillTimer(hWnd, 1);
        //end the program
        PostQuitMessage(0);
        break;

    case WM_LBUTTONDOWN:
    {
        // Lấy tọa độ chuột
        POINT mousePos;
        mousePos.x = LOWORD(lParam);
        mousePos.y = HIWORD(lParam);

        // Tạo một quả bóng mới với tọa độ chuột hiện tại và tốc độ di chuyển ngẫu nhiên
        RECT newBall;
        newBall.left = mousePos.x;
        newBall.top = mousePos.y;
        newBall.right = newBall.left + 30;
        newBall.bottom = newBall.top + 30;

        std::random_device rd;
        std::mt19937 rng(rd());
        std::uniform_int_distribution<int> dist(-5, 5);
        int dX = dist(rng);
        int dY = dist(rng);

        balls.push_back({ newBall, dX, dY });
    }
    break;


    default:
        //let Windows handle every other message
        return(DefWindowProc(hWnd, nMsg, wParam, lParam));
    }

    return 0;
}

当程序创建超过2个球时,球有问题。

我该如何解决这个问题?创建第三个球时,屏幕上显示为灰色。当球移动时屏幕上没有灰色。

5tmbdcev

5tmbdcev1#

正如@molbdnilo所建议的,不要在循环中覆盖相同的变量。你需要在循环中声明一个新的画笔。

auto newbrush = (HBRUSH)SelectObject(hDC, GetStockObject(GRAY_BRUSH));
Ellipse(hDC, ball1.rect.left, ball1.rect.top, ball1.rect.right, ball1.rect.bottom);

相关问题