//-mwindows -lgdi32
#include <windows.h>
#include <stdio.h>
#include <time.h>
#define WIDTH 500
#define HEIGHT 500
#define TARGET_COUNT 3 // 3个球
// 靶子
int targetX[TARGET_COUNT];
int targetY[TARGET_COUNT];
int targetSize = 30;
int minSize = 10;
int maxSize = 80;
// 数据统计
int totalHits = 0;
int totalClicks = 0;
float hitRate = 0.0f;
clock_t startTime;
double totalTime = 0;
double perHitTime = 0;
// 双缓冲
HDC memDC;
HBITMAP memBitmap;
// 【核心修改】只在中心附近生成球(不会散开)
void SpawnOneTarget(int index)
{
// 限制在屏幕中心 250x250 范围内,球靠得非常近
int centerX = WIDTH / 2 - 125;
int centerY = HEIGHT / 2 - 125;
targetX[index] = centerX + rand() % 250;
targetY[index] = centerY + rand() % 250;
}
// 生成所有3个靶子
void SpawnAllTargets()
{
for (int i = 0; i < TARGET_COUNT; i++)
SpawnOneTarget(i);
}
// 初始化
void GameInit()
{
srand((unsigned)time(NULL));
totalHits = 0;
totalClicks = 0;
hitRate = 0;
startTime = clock();
SpawnAllTargets();
}
// 创建画布
void CreateCanvas(HWND hWnd)
{
HDC hdc = GetDC(hWnd);
memDC = CreateCompatibleDC(hdc);
memBitmap = CreateCompatibleBitmap(hdc, WIDTH, HEIGHT);
SelectObject(memDC, memBitmap);
ReleaseDC(hWnd, hdc);
}
// 窗口消息
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HFONT font;
switch(msg)
{
case WM_CREATE:
font = CreateFont(22,0,0,0, FW_BOLD, 0,0,0,0,0,0,0,0, "微软雅黑");
CreateCanvas(hWnd);
GameInit();
SetTimer(hWnd, 1, 30, NULL);
break;
case WM_TIMER:
InvalidateRect(hWnd, NULL, FALSE);
break;
// 鼠标点击
case WM_LBUTTONDOWN:
{
totalClicks++;
int mx = LOWORD(lParam);
int my = HIWORD(lParam);
// 判断击中哪个球 → 击中就刷新
for(int i=0; i<TARGET_COUNT; i++)
{
if(mx >= targetX[i] && mx <= targetX[i]+targetSize &&
my >= targetY[i] && my <= targetY[i]+targetSize)
{
totalHits++;
SpawnOneTarget(i);
break;
}
}
// 计算数据
hitRate = (totalClicks == 0) ? 0 : (totalHits * 100.0 / totalClicks);
totalTime = (double)(clock() - startTime) / CLOCKS_PER_SEC;
perHitTime = (totalHits == 0) ? 0 : (totalTime / totalHits);
break;
}
// + - 调节大小
case WM_KEYDOWN:
if(wParam == VK_ADD || wParam == '=')
{
if(targetSize < maxSize) targetSize += 4;
}
if(wParam == VK_SUBTRACT || wParam == '-')
{
if(targetSize > minSize) targetSize -= 4;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// 背景
HBRUSH black = CreateSolidBrush(RGB(0,0,0));
SelectObject(memDC, black);
Rectangle(memDC, 0,0, WIDTH,HEIGHT);
DeleteObject(black);
// 画3个红球
HBRUSH redBrush = CreateSolidBrush(RGB(255,50,50));
SelectObject(memDC, redBrush);
for(int i=0; i<TARGET_COUNT; i++)
Ellipse(memDC, targetX[i], targetY[i],
targetX[i]+targetSize, targetY[i]+targetSize);
DeleteObject(redBrush);
// 文字
SelectObject(memDC, font);
SetTextColor(memDC, RGB(255,255,255));
SetBkMode(memDC, TRANSPARENT);
char buf[256];
sprintf(buf, "得分:%d", totalHits);
TextOutA(memDC, 20, 20, buf, strlen(buf));
sprintf(buf, "命中率:%.1f%%", hitRate);
TextOutA(memDC, 20, 50, buf, strlen(buf));
sprintf(buf, "总时间:%.1f 秒", totalTime);
TextOutA(memDC, 20, 80, buf, strlen(buf));
sprintf(buf, "每球用时:%.2f 秒", perHitTime);
TextOutA(memDC, 20, 110, buf, strlen(buf));
sprintf(buf, "球大小:%d (+ 增大 | - 减小)", targetSize);
TextOutA(memDC, 20, 140, buf, strlen(buf));
// 显示画面
BitBlt(hdc,0,0,WIDTH,HEIGHT, memDC,0,0,SRCCOPY);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
KillTimer(hWnd,1);
DeleteObject(memBitmap);
DeleteDC(memDC);
DeleteObject(font);
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
// 入口
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmd, int nShow)
{
WNDCLASSA wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInst;
wc.lpszClassName = "AimTrainer3";
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
RegisterClassA(&wc);
HWND hWnd = CreateWindowA(
"AimTrainer3", "豆包超牛福;分不清已吓哭",
WS_CAPTION | WS_SYSMENU,
100,100, WIDTH+16, HEIGHT+38,
NULL,NULL,hInst,NULL
);
ShowWindow(hWnd, nShow);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}