C语言实现简易的别踩白块小游戏
游戏规则:正能点击最后一行的黑块后上面的区域就会自动下移,点击任何其他位置游戏结束,统计所用时间。
大致步骤为:
一:1、设计窗口类 2、创建、注册窗口 3、显示窗口 4、更新窗口 5、消息循环
二:然后是窗口处理函数,先进行绘图然后再设置点击事件;
利用 PAINTSTRUCT ps; hDC = BeginPaint(hWnd, &ps); 进行绘图;
利用srand((unsigned)time(NULL)); bw[i] = rand() % 4; 随机生成0、1、2、3然后进行画黑块:
for (int i = 0; i < 4; i++){
SetRect(&rect, bw[i] * BLOCK, i*BLOCK, bw[i] * BLOCK+100, i*BLOCK+100);
hBrush = CreateSolidBrush(RGB(0, 0, 0)); //创建画刷
SelectObject(hDC, hBrush); //选择刷的对象
Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
//释放资源
DeleteObject(hBrush);
}
利用lParam中的坐标判断点击区域是否正确:
point.x = LOWORD(lParam); //低位字节
point.y = HIWORD(lParam); //高位字节
if (point.x / BLOCK != bw[3] || point.y / BLOCK != 3){
wsprintf(szMesg, L"您输了! 用时:%d.%d秒 格数:%d个", tm / 100, tm - (tm / 100) * 100, n);
MessageBox(hWnd, szMesg, L"提示", MB_OK);
PostQuitMessage(0);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)//3:命令行参数 4:窗口最大最小化
{
//一、做一个窗口
//1.设计窗口类
TCHAR szAppClassName[] = TEXT("BaikuaiGuiFoundation");
WNDCLASS wc;
wc.cbClsExtra = 0; //窗口类扩展空间大小(存相同类型数据的空间)
wc.cbWndExtra = 0; //窗口扩展空间大小
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //加载白色背景画刷
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //加载系统光标
wc.hIcon = NULL; //加载图标
wc.hInstance = hInstance; //应用程序实例
wc.lpfnWndProc = WindowProc; //窗口处理函数
wc.lpszClassName = szAppClassName; //窗口类型名
wc.lpszMenuName = NULL; //菜单名
wc.style = CS_HREDRAW | CS_VREDRAW; //窗口类型风格
//2.注册窗口类
RegisterClass(&wc);
//3.创建窗口
HWND hWnd = CreateWindow(
szAppClassName, //窗口类型名
TEXT("别踩白块"), //窗口标题
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, //窗口风格
500, 200, //窗口左上角坐标
4 * BLOCK + 17, 4*BLOCK+39, //窗口宽和高
NULL, //父窗口句柄
NULL, //菜单句柄
hInstance, //应用程序实例句柄
NULL //参数
);
//4.显示窗口
ShowWindow(hWnd, SW_SHOW);
//5.更新窗口
UpdateWindow(hWnd);
//6.消息循环
MSG msg; //消息机制驱动运行
while (GetMessage(&msg, NULL, 0, 0)){ //将消息队列中所有消息用GetMessage取到msg中
//将虚拟键消息转换成字符消息
TranslateMessage(&msg);
//将消息分发给窗口处理函数
DispatchMessage(&msg);
}
return 0;//退出
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; //绘图的数据保存在ps
HDC hDC; //绘图句柄 DC GDI
static int bw[4]; //每屏有四个黑块,从上往下数
RECT rect; //矩形区域
HBRUSH hBrush; //画刷句柄
POINT point; //鼠标左键点击坐标
static int n = 0; //踩的格子数
static int tm = 0; //所耗时间
TCHAR szMesg[200];
switch (uMsg)
{
case WM_CREATE: //窗口创建的时候
{
srand((unsigned)time(NULL));
for (int i = 0; i < 4; i++){
bw[i] = rand() % 4;
}
//开启定时器
SetTimer(hWnd, 1, 10, NULL); //1号定时器,10ms定一次时
}
break;
case WM_TIMER: //定时器
tm++;
break;
case WM_PAINT: //窗口绘图消息
hDC = BeginPaint(hWnd, &ps);
//画图
//Rectangle(hDC, 0, 0, 100, 100);
for (int i = 0; i < 5; i++){
//水平
MoveToEx(hDC, 0, i*BLOCK, NULL);
LineTo(hDC, 4*BLOCK, i * BLOCK);
//竖直
MoveToEx(hDC, i*BLOCK, 0, NULL);
LineTo(hDC, i*BLOCK, 4*BLOCK);
}
//画黑块
for (int i = 0; i < 4; i++){
SetRect(&rect, bw[i] * BLOCK, i*BLOCK, bw[i] * BLOCK+100, i*BLOCK+100);
hBrush = CreateSolidBrush(RGB(0, 0, 0)); //创建画刷
SelectObject(hDC, hBrush); //选择刷的对象
Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
//释放资源
DeleteObject(hBrush);
}
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN: //左键点击
{
point.x = LOWORD(lParam); //低位字节
point.y = HIWORD(lParam); //高位字节
if (point.x / BLOCK != bw[3] || point.y / BLOCK != 3){
wsprintf(szMesg, L"您输了! 用时:%d.%d秒 格数:%d个", tm / 100, tm - (tm / 100) * 100, n);
MessageBox(hWnd, szMesg, L"提示", MB_OK);
PostQuitMessage(0);
}
//随机数
for (int i = 3; i >= 1; i--){
bw[i] = bw[i - 1];
}
bw[0] = rand() % 4;
n++;
//滚动窗口
ScrollWindow(hWnd, 0, BLOCK, NULL, NULL); //水平、竖直滚动BLOCK个像素,滚动区为NULL
}
break;
/*
case WM_KEYDOWN:
break;
case WM_RBUTTONDOWN:
break;
*/
case WM_CLOSE: //窗口关闭消息,关闭相当于窗口最小化,还可以恢复
DestroyWindow(hWnd);//销毁窗口,不可以恢复了
break;
case WM_DESTROY: //窗口销毁消息
PostQuitMessage(0);//退出进程
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}