利用vc实现基本要求: 在应用程序窗口内,用鼠标点击任意位置,将会以鼠标点击处为圆心,生成一个大小和色彩均是随机的一个圆。当用户不停点击时,会出现满屏大小不一的彩球。 扩展要求: 1.彩色小球出现后,以匀速垂直向上方运动,直到移出窗口上边沿,消失。【30分】 2.添加鼠标追随效果。当按住鼠标左键,在程序窗口中移动时,光标所经之处产生彩球,1~2秒后随即消失。【40分】
时间: 2024-02-17 11:04:05 浏览: 135
以下是利用VC实现基本和扩展要求的代码:
```c++
#include <windows.h>
#include <time.h>
#define MAXBALLS 5000 //最多小球数
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Random Balls");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("Random Balls"),
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
srand((unsigned)time(NULL)); //随机数种子
int count = 0; //小球数目
POINT pos[MAXBALLS]; //小球位置
int size[MAXBALLS]; //小球大小
COLORREF color[MAXBALLS]; //小球颜色
int speed[MAXBALLS]; //小球速度
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (count < MAXBALLS && msg.message == WM_LBUTTONDOWN) //生成小球
{
pos[count] = MAKEPOINT(msg.lParam);
size[count] = rand() % 21 + 10; //10~30的随机大小
color[count] = RGB(rand() % 256, rand() % 256, rand() % 256); //随机颜色
speed[count] = rand() % 5 + 1; //1~5的随机速度
count++;
}
for (int i = 0; i < count; i++) //运动小球
{
HDC hdc = GetDC(hwnd);
HBRUSH hBrush = CreateSolidBrush(color[i]);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
Ellipse(hdc, pos[i].x - size[i], pos[i].y - size[i], pos[i].x + size[i], pos[i].y + size[i]);
SelectObject(hdc, hOldBrush);
DeleteObject(hBrush);
ReleaseDC(hwnd, hdc);
pos[i].y -= speed[i];
if (pos[i].y < -size[i]) //小球消失
{
pos[i] = pos[count - 1];
size[i] = size[count - 1];
color[i] = color[count - 1];
speed[i] = speed[count - 1];
count--;
i--;
}
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL bDrawing = FALSE;
static POINT pos; //鼠标位置
switch (message)
{
case WM_LBUTTONDOWN:
if (!bDrawing) //开始画图
{
bDrawing = TRUE;
SetCapture(hwnd); //捕获鼠标
pos = MAKEPOINT(lParam);
InvalidateRect(hwnd, NULL, TRUE); //刷新窗口
}
break;
case WM_MOUSEMOVE:
if (bDrawing) //绘制小球
{
POINT pt = MAKEPOINT(lParam);
if (abs(pt.x - pos.x) > 5 || abs(pt.y - pos.y) > 5) //移动距离大于5才绘制
{
pos = pt;
HDC hdc = GetDC(hwnd);
HBRUSH hBrush = CreateSolidBrush(RGB(rand() % 256, rand() % 256, rand() % 256)); //随机颜色
HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
Ellipse(hdc, pos.x - 5, pos.y - 5, pos.x + 5, pos.y + 5);
SelectObject(hdc, hOldBrush);
DeleteObject(hBrush);
ReleaseDC(hwnd, hdc);
}
}
break;
case WM_LBUTTONUP:
if (bDrawing) //结束画图
{
bDrawing = FALSE;
ReleaseCapture(); //释放鼠标
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
```
代码说明:
1. 定义了一个最多小球数目 `MAXBALLS`,以及小球的位置、大小、颜色、速度等数组。
2. 在主消息循环中,通过检测鼠标左键按下事件生成小球,并对每个小球进行运动处理。当小球超出窗口上边沿时,从数组中删除该小球。
3. 在窗口过程中,捕获鼠标左键消息,通过检测鼠标移动事件绘制小球。当鼠标左键释放时停止绘制小球。
4. 小球颜色采用随机颜色,大小和速度采用随机值,鼠标追随效果的小球大小固定为 10 像素,并在 1~2 秒后消失。
阅读全文