#include<windows.h>
#include<strsafe.h>
#include<time.h>
RECT Rect[16];
int cxClient, cyClient;
int a[4][4] = { 0 };
int score = 0;
void GameOver(HWND hwnd)
{
int i, j;
int gameover = 0;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
{
if (a[i][j] == a[i][j + 1])
gameover++;
}
for (j = 0; j < 4; j++)
for (i = 0; i < 3; i++)
{
if (a[i][j] == a[i + 1][j])
gameover++;
}
//判断格子中有没有空格
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
if (a[i][j] == 0)
gameover++;
if (gameover == 0)
{
MessageBox(NULL,"你已无路可走,游戏结束!","提示",MB_OK);
DestroyWindow(hwnd);
}
}
void Win(HWND hwnd)
{
int i, j;
for (i = 0; i < 4; i++)//如果完成了2048
for (j = 0; j < 4; j++)
if (a[i][j] == 2048)
{
MessageBox(NULL,"恭喜你完成2048!","Congratulations",MB_OK);
DestroyWindow(hwnd);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
HDC dc;
RECT rec;
PAINTSTRUCT ps;
HBRUSH hBrush;
//HPEN hpen;
int i, j,t1,t2,t3;
int res; //退出的返回值
RECT win;
srand((unsigned int)time(NULL));
SetRect(&win, 0, 0, 400, 400);
switch (umsg)
{
case WM_KEYDOWN:
switch (wparam)
{
case VK_LEFT:
loop2:
for (i = 3; i >0; i--)//用于将数合并
for (j = 3; j >= 0; j--)
{
if (a[i][j] != 0 && a[i - 1][j] == 0)//如果下面的数不为0而上面的数为0
{
a[i - 1][j] = a[i][j];//则把下面的数赋值给上面的那个数
a[i][j] = 0;
goto loop2;
}
}
for (i = 0; i < 3; i++)//这边用于判断按向上的键时,上下是否有一样数字的
for (j = 0; j < 4; j++)
{
if (a[i][j] == a[i + 1][j])//如果相邻的两行数字一样的
{
a[i][j] += a[i][j];//则把上面一行的数字变为2倍
a[i + 1][j] = 0;//下面的数字变为0
score += 5;
}
}
loop1:
for (i = 3; i >0; i--)//用于将数合并
for (j = 3; j >= 0; j--)
{
if (a[i][j] != 0 && a[i - 1][j] == 0)//如果下面的数不为0而上面的数为0
{
a[i - 1][j] = a[i][j];//则把下面的数赋值给上面的那个数
a[i][j] = 0;
goto loop1;
}
}
t1 = rand() % 4;//产生一个随机数用于保存数字出现在第t1列
t2 = rand() % 4;
t3 = rand() % 2;
while (a[t1][t2] != 0)//如果这一列都满了则重新生成t1
{
t1 = rand() % 4;
t2 = rand() % 4;
}
if (t3 % 2 == 0)
a[t1][t2] = 2;
else
a[t1][t2] = 4;
InvalidateRect(hwnd, &win, TRUE);
break;
case VK_RIGHT:
loop3:
for (i = 0; i <3; i++)
for (j = 0; j<4; j++)
{
if (a[i][j] != 0 && a[i + 1][j] == 0)
{
a[i + 1][j] = a[i][j];
a[i][j] = 0;
goto loop3;
}
}
for (i = 3; i >= 0; i--)//这边用于判断按向下的键时,上下是否有一样数字的
for (j = 3; j >= 0; j--)
{
if (a[i][j] == a[i - 1][j])//如果相邻的两行数字一样的
{
a[i][j] += a[i][j];//则把下面一行的数字变为2倍
a[i - 1][j] = 0;//上面的数字变为0
score += 5;
}
}
loop4:
for (i = 0; i <3; i++)
for (j = 0; j<4; j++)
{
if (a[i][j] != 0 && a[i + 1][j] == 0)
{
a[i + 1][j] = a[i][j];
a[i][j] = 0;
goto loop4;
}
}
t1 = rand() % 4;//产生一个随机数用于保存数字出现在第t1列
t2 = rand() % 4;
t3 = rand() % 2;
while (a[t1][t2] != 0)//如果这一列都满了则重新生成t1
{
t1 = rand() % 4;
t2 = rand() % 4;
}
if (t3 % 2 == 0)
a[t1][t2] = 2;
else
a[t1][t2] = 4;
InvalidateRect(hwnd, &win, TRUE);
break;
case VK_UP:
loop5:
for (j = 3; j >0; j--)//用于将数合并
for (i = 3; i >= 0; i--)
{
if (a[i][j] != 0 && a[i][j - 1] == 0)//如果右面的数不为0而左面的数为0
{
a[i][j - 1] = a[i][j];//则把右面的数赋值给左面的那个数
a[i][j] = 0;
goto loop5;
}
}
for (j = 0; j < 3; j++)//这边用于判断按向左的键时,左右是否有一样数字的
for (i = 0; i < 4; i++)
{
if (a[i][j] == a[i][j + 1])//如果相邻的两行数字一样的
{
a[i][j] += a[i][j];//则把左面一行的数字变为2倍
a[i][j + 1] = 0;//右面的数字变为0
score += 5;
}
}
loop6:
for (j = 3; j >0; j--)//用于将数合并
for (i = 3; i >= 0; i--)
{
if (a[i][j] != 0 && a[i][j - 1] == 0)//如果右面的数不为0而左面的数为0
{
a[i][j - 1] = a[i][j];//则把右面的数赋值给左面的那个数
a[i][j] = 0;
goto loop6;
}
}
t1 = rand() % 4;//产生一个随机数用于保存数字出现在第t1列
t2 = rand() % 4;
t3 = rand() % 4;
while (a[t1][t2] != 0)//如果这一列都满了则重新生成t1
{
t1 = rand() % 4;
t2 = rand() % 4;
}
if (t3 % 2 == 0)
a[t1][t2] = 2;
else
a[t1][t2] = 4;
InvalidateRect(hwnd, &win, TRUE);
break;
case VK_DOWN:
loop7:
for (j = 0; j <3; j++)//用于将数合并
for (i = 0; i<4; i++)
{
if (a[i][j] != 0 && a[i][j + 1] == 0)//如果左面的数不为0而又面的数为0
{
a[i][j + 1] = a[i][j];//则把左面的数赋值给上面的那个数
a[i][j] = 0;
goto loop7;
}
}
for (j = 3; j >0; j--)//这边用于判断按向右的键时,左右是否有一样数字的
for (i = 3; i >= 0; i--)
{
if (a[i][j] == a[i][j - 1])//如果相邻的两行数字一样的
{
a[i][j] += a[i][j];//则把右面一行的数字变为2倍
a[i][j - 1] = 0;//左面的数字变为0
score += 5;
}
}
loop8:
for (j = 0; j <3; j++)//用于将数合并
for (i = 0; i<4; i++)
{
if (a[i][j] != 0 && a[i][j + 1] == 0)//如果左面的数不为0而又面的数为0
{
a[i][j + 1] = a[i][j];//则把左面的数赋值给上面的那个数
a[i][j] = 0;
goto loop8;
}
}
t1 = rand() % 4;//产生一个随机数用于保存数字出现在第t1列
t2 = rand() % 4;
t3 = rand() % 2;
while (a[t1][t2] != 0)//如果这一列都满了则重新生成t1
{
t1 = rand() % 4;
t2 = rand() % 4;
}
if (t3 % 2 == 0)
a[t1][t2] = 2;
else
a[t1][t2] = 4;
InvalidateRect(hwnd, &win, TRUE);
break;
case VK_ESCAPE:
res = MessageBox(NULL,"游戏正在进行中确定要退出?","温馨提示",MB_YESNO);
if (res == IDYES)
DestroyWindow(hwnd);
}
case WM_SIZE:
cxClient = LOWORD(lparam);
cyClient = HIWORD(lparam);
break;
case WM_PAINT:
BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rec);
dc = GetDC(hwnd);
size_t text1,text2;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
switch (a[i][j])
{
case 0:
{
hBrush = CreateSolidBrush(RGB(204, 192, 180));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
// TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("0"), 1);
DeleteObject(hBrush);
break;
}
case 2:
{
hBrush = CreateSolidBrush(RGB(238, 228, 218));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("2"), 1);
DeleteObject(hBrush);
break;
}
case 4:
{
hBrush = CreateSolidBrush(RGB(255, 236, 139));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("4"), 1);
DeleteObject(hBrush);
break;
}
case 8:
{
hBrush = CreateSolidBrush(RGB(242, 177, 121));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("8"), 1);
DeleteObject(hBrush);
break;
}
case 16:
{
hBrush = CreateSolidBrush(RGB(236, 141, 84));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("16"), 2);
DeleteObject(hBrush);
break;
}
case 32:
{
hBrush = CreateSolidBrush(RGB(246, 124, 95));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("32"), 2);
DeleteObject(hBrush);
break;
}
case 64:
{
hBrush = CreateSolidBrush(RGB(234, 89, 55));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("64"), 2);
DeleteObject(hBrush);
break;
}
case 128:
{
hBrush = CreateSolidBrush(RGB(120, 216, 107));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("128"), 3);
DeleteObject(hBrush);
break;
}
case 256:
{
hBrush = CreateSolidBrush(RGB(237, 255, 97));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("256"), 3);
DeleteObject(hBrush);
break;
}
case 512:
{
hBrush = CreateSolidBrush(RGB(0, 200, 0));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("512"), 3);
DeleteObject(hBrush);
break;
}
case 1024:
{
hBrush = CreateSolidBrush(RGB(0, 0, 200));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("1024"), 4);
DeleteObject(hBrush);
break;
}
case 2048:
{
hBrush = CreateSolidBrush(RGB(255,0,0));
SelectObject(dc, hBrush);
Rectangle(dc, i * 100, j * 100, (i + 1) * 100, (j + 1) * 100);
SetBkMode(dc, TRANSPARENT);
TextOut(dc, i * 100 + 50, j * 100 + 50, TEXT("2048"), 4);
DeleteObject(hBrush);
break;
}
}
}
hBrush =CreateSolidBrush(RGB(255, 255, 0));
SelectObject(dc, hBrush);
RoundRect(dc, 250, 415, 390, 445, 10, 10);
RoundRect(dc, 10, 415, 200, 445, 10, 10);
DeleteObject(hBrush);
TCHAR buf1[50],buf2[40];
dc = GetDC(hwnd);
StringCchPrintf(buf2, 40, TEXT("分数 : %d "), score);
StringCchPrintf(buf1, 50, TEXT("上下左右键控制,ESC退出"));
StringCchLength(buf2, 40, &text1);
StringCchLength(buf1, 50, &text2);
SetTextColor(dc,RGB(0, 255, 255));
SetBkMode(dc,TRANSPARENT);
TextOut(dc, 270, 420, buf2, text1);
TextOut(dc,10, 420, buf1, text2);
//DeleteObject(hpen);
EndPaint(hwnd, &ps);
ReleaseDC(hwnd, dc);
break;
case WM_CLOSE:
res = MessageBox(NULL, "游戏正在进行中确定要退出?", "温馨提示", MB_YESNO);
if (res == IDYES)
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, umsg, wparam, lparam); //默认的窗口处理函数
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstace, PSTR szCmdLine, int iCmdShow)
{
for (int B = 0; B < 2; B++)
{
int A1 = rand() % 4;
int A2 = rand() % 4;
a[A1][A2] = 2;
}
TCHAR szName[] = "My Windows"; //用于保存窗口类名
HWND hWnd;
MSG msg;
WNDCLASS wnd;
wnd.style = NULL;
wnd.lpfnWndProc = WndProc; //回调函数
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;// 应用程序实例句柄
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wnd.lpszMenuName = NULL;
wnd.lpszClassName = szName; //指定窗口类名
if (!RegisterClass(&wnd))
{
MessageBox(NULL, TEXT("注册窗口失败!"), TEXT("警告"), MB_ICONWARNING);
return 0;
}
hWnd = CreateWindow(szName, TEXT("GDI绘图版2048小游戏"), WS_SYSMENU|WS_CAPTION, 500, 100, 413, 500, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while (GetMessage(&msg, 0, 0, 0))//获取到WM_QUIT返回值为0,其他为非0值
{
TranslateMessage(&msg);// 将虚拟键消息转换为字符消息
DispatchMessage(&msg);// 将消息传送到窗口函数
GameOver(hWnd);
Win(hWnd);
}
return 0;
}
2048小游戏
最新推荐文章于 2025-07-05 20:28:57 发布

3967

被折叠的 条评论
为什么被折叠?



