windows程序设计 GDI思考题2 十个小球在屏幕内运动

思路:

先算出每个小球下一个位置的x和y,并根据先后碰撞顺序决定每个小球最后的x和y值,同时还得考虑碰撞到边界反弹的问题。

一开始搞错了判断先后顺序的方法,浪费了贼多时间(逃

 

代码:

#include <windows.h>
#include <tchar.h>
#include <cmath>
#include <time.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  //窗口函数说明


//入口函数代码
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wcex;
    HWND hWnd;
    MSG msg;
    char szWindowClass[] = "窗口示例";  //窗口类名
    char szTitle[] = "My Windows";    //窗口标题名


//初始化窗口类
    wcex.cbSize = sizeof(WNDCLASSEX); //窗口类的大小
    wcex.style = 0; //窗口类型为默认类型
    wcex.lpfnWndProc = WndProc; //窗口处理函数为WndProc
    wcex.cbClsExtra = 0;  //窗口类无扩展
    wcex.cbWndExtra = 0;  //窗口实例无扩展
    wcex.hInstance = hInstance; //当前实例句柄
    wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION); //窗口的图标为默认图标

    wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //窗口采用箭头光标

    wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //窗口背景颜色
    wcex.lpszMenuName = NULL; //窗口中无菜单
    wcex.lpszClassName = szWindowClass; //窗口类名为 szWindowClass
    wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION); //窗口的小图标为默认图标


//窗口类的注册
    if(!RegisterClassEx(&wcex))
    {
        MessageBox(NULL, ("窗口类注册失败!"), ("窗口注册"), NULL);
        return 1;
    }

//创建窗口
    hWnd = CreateWindow(

        szWindowClass,  //窗口类名
        szTitle, //窗口实例的标题名
        WS_OVERLAPPEDWINDOW, //窗口的风格
        CW_USEDEFAULT, CW_USEDEFAULT, //窗口左上角坐标为默认值
        CW_USEDEFAULT, CW_USEDEFAULT, //窗口的高和宽为默认值
        NULL, //此窗口无父窗口
        NULL, //此窗口无主菜单
        hInstance, //创建此窗口应用程序的当前句柄
        NULL //不使用该值
    );

    if(!hWnd) //如果创建窗口失败则发出警告
    {

        MessageBox(NULL, "创建窗口失败!", ("创建窗口"), NULL);
        return 1;
    }

    ShowWindow(hWnd, nCmdShow); //显示窗口
    UpdateWindow(hWnd); //绘制用户区

    while(GetMessage(&msg, NULL, 0, 0)) //消息循环
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam; //程序终止时将信息返回系统


}

//窗口函数代码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    HPEN hpen;
    HBRUSH hbrush;
    PAINTSTRUCT ps;
    RECT rect;
    POINT pt;
    GetClientRect(hWnd, &rect);
    int i,j;

    static double x[10];
    static double y[10];
    static double vx[10], vy[10];
    static int r[10];
    static int uddis[10] = {1,1,1,1,1,1,1,1,1,1};
    static int lrdis[10] = {1,1,1,1,1,1,1,1,1,1};

    static double nextx[10];
    static double nexty[10];

    double xx[10];
    double yy[10];

    for(i = 0; i < 10; i++)
    {
        xx[i] = -1;
        yy[i] = -1;
        vx[i] = i > 3 ? i : i + 2;
        vy[i] = i > 3 ? i : i + 2;
    }

    for(i = 0; i < 10; i++)
    {
        r[i] = rect.right / 50 + rect.right / 500 * i;
    }


    x[0] = 0;
    y[0] = 0;
    for(i = 1; i < 10; i++)
    {
        x[i] = rect.right / 20 * i;
        y[i] = rect.bottom / 20 * i;
    }

    static int flag2 = 0;

    switch(message)
    {

        case WM_PAINT:

            hdc = BeginPaint(hWnd, &ps);
            hbrush = CreateSolidBrush(RGB(255,0,0));


            if(flag2 > 0)
            {
                for(i = 0; i < 10; i++)
                {
                    x[i] = nextx[i];
                    y[i] = nexty[i];
                }
            }


            for(i = 0; i < 5; i++)
            {
                 hbrush = CreateSolidBrush(RGB(255, 0, i * 50));
                 SelectObject(hdc, hbrush);
                 Ellipse(hdc, x[i] - r[i], y[i] - r[i], x[i] + r[i], y[i] + r[i]);
                 DeleteObject(hbrush);
            }

            for(i = 5; i < 10; i++)
            {
                 hbrush = CreateSolidBrush(RGB(0, 255, i * 50));
                 SelectObject(hdc, hbrush);
                 Ellipse(hdc, x[i] - r[i], y[i] - r[i], x[i] + r[i], y[i] + r[i]);
                 DeleteObject(hbrush);
            }


            for(i = 0; i < 10; i++)
            {
                nextx[i] = x[i] + lrdis[i] * vx[i];
                nexty[i] = y[i] + uddis[i] * vy[i];
            }

            for(i = 0; i < 10; i++)
            {
                double minx = rect.left + r[i];
                double miny = rect.top + r[i];
                double maxx = rect.right - r[i];
                double maxy = rect.bottom - r[i];

                for(j = 0; j < 10; j++)
                {

                    if(i == j)
                        continue;

                    int sum = pow(nextx[i] - nextx[j], 2) + pow(nexty[i] - nexty[j], 2);
                    double sum2 = sqrt(sum);

                    if(sum2 < r[i] + r[j] && nextx[i] > nextx[j])
                    {
                        if(nextx[j] - (nextx[j] - nextx[i]) * (r[i] + r[j]) / sum2 > minx)
                            minx = (double)(nextx[j] - (nextx[j] - nextx[i]) * (r[i] + r[j]) / sum2);

                        if(nexty[i] > nexty[j])
                        {
                            if(nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2 < maxy)
                            {
                                maxy = (double)nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2;
                            }
                        }

                        if(nexty[i] < nexty[j])
                        {
                            if(nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2 > miny)
                            {
                                miny = (double)nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2;
                            }
                        }
                    }

                    if(sum2 < r[i] + r[j] && nextx[i] < nextx[j])
                    {
                        if(nextx[j] - (nextx[j] - nextx[i]) * (r[i] + r[j]) / sum2 < maxx)
                            maxx = (double)nextx[j] - (nextx[j] - nextx[i]) * (r[i] + r[j]) / sum2;

                        if(nexty[i] > nexty[j])
                        {
                            if(nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2 < maxy)
                            {
                                maxy = (double)nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2;
                            }
                        }

                        if(nexty[i] < nexty[j])
                        {
                            if(nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2 > miny)
                            {
                                miny = (double)nexty[j] - (nexty[j] - nexty[i]) * (r[i] + r[j]) / sum2;
                            }
                        }
                    }

                }

                if(minx != rect.left + r[i])
                {
                    xx[i] = minx;
                    lrdis[i] = -lrdis[i];
                }
                else if(nextx[i] < rect.left + r[i])
                    {
                        xx[i] = rect.left + r[i];
                        lrdis[i] = -lrdis[i];
                    }

                if(maxx != rect.right - r[i])
                {
                    xx[i] = maxx;
                    lrdis[i] = -lrdis[i];
                }
                else if(nextx[i] > rect.right - r[i])
                    {
                        xx[i] = rect.right - r[i];
                        lrdis[i] = -lrdis[i];
                    }

                if(miny != rect.top + r[i])
                {
                    yy[i] = miny;
                    uddis[i] = -uddis[i];
                }
                else if(nexty[i] < rect.top + r[i])
                    {
                        yy[i] = rect.top + r[i];
                        uddis[i] = -uddis[i];
                    }


                if(maxy != rect.bottom - r[i])
                {
                    yy[i] = maxy;
                    uddis[i] = -uddis[i];
                }
                else if(nexty[i] > rect.bottom - r[i])
                    {
                        yy[i] = rect.bottom - r[i];
                        uddis[i] = -uddis[i];
                    }
            }


            for(i = 0; i < 10; i++)
            {
                if(xx[i] != -1)
                    nextx[i] = xx[i];
                if(yy[i] != -1)
                    nexty[i] = yy[i];
            }

            flag2 = 1;
            DeleteObject(hbrush);
            EndPaint(hWnd, &ps);


            Sleep(10);
            InvalidateRect(hWnd, NULL, 1);
            break;


        case WM_SIZE:
            InvalidateRect(hWnd, NULL, true);
            break;

        case WM_DESTROY:
            PostQuitMessage(0); //调用POSTQuitMessage发出WM_QUIT消息
            break;


        default:
            return DefWindowProc(hWnd, message, wParam, lParam); //默认时采用系统消息默认处理函数


            break;

    }

    return 0;
}

 

运行效果图:

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值