VC俄罗斯方块
用VC撸了一个俄罗斯方块, 实在是内流满面啊, 我屮艸芔茻, 纠结代码:
运行下面代码
// Blocks.cpp : 定义应用程序的入口点。 #include "stdafx.h" #include "Blocks.h" #include "stdio.h" #include "time.h" #include<stdlib.h> #define MAX_LOADSTRING 100 #define BOUND_SIZE 10 #define TETRIS_SIZE 30 #define GAME_X 10 #define GAME_Y 20 //游戏中方块的类型 int Tetris[][4][4] = { { { 0,0,0,0 }, { 1,1,1,1 }, { 0,0,0,0 }, { 0,0,0,0 } }, { { 1,1,0,0 }, { 1,1,0,0 }, { 0,0,0,0 }, { 0,0,0,0 } }, { { 1,1,0,0 }, { 0,1,1,0 }, { 0,0,0,0 }, { 0,0,0,0 } }, { { 0,1,1,0 }, { 1,1,0,0 }, { 0,0,0,0 }, { 0,0,0,0 } }, { { 1,0,0,0 }, { 1,1,1,0 }, { 0,0,0,0 }, { 0,0,0,0 } } }; //方块的个数 int TetrisCount = sizeof(Tetris) / sizeof(Tetris[0]); int currentTetris[4][4] = { { 0,0,0,0 }, { 1,1,1,1 }, { 0,0,0,0 }, { 0,0,0,0 } }; int tempTetris[4][4]; //游戏面板.保存临时数据 int game_board[GAME_X][GAME_Y]; //游戏初始化的变量, X和Y为当前的方块的几何轴, timer为定时器变量; int X = 3, Y = 0, timer = 0; //随机生成方块 VOID generateTetris(int TETData[4][4]); //返回1的话就是碰到,返回0就是没有碰到; int CheckTetris(int x, int y, int TETData[4][4], int gb[GAME_X][GAME_Y]); //合并背景方块和消方块 VOID RefreshTetris(int x, int y, int TETData[4][4], int gb[GAME_X][GAME_Y]); //旋转方块 VOID rotateTetris(int tet[4][4]); //绘制方块 VOID DrawTetris(HDC hdc, int x, int y, int tet[4][4]); //绘制背景 VOID DrawBackGround(HDC hdc); // 全局变量: HINSTANCE hInst; // 当前实例 WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。 // 初始化全局字符串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_BLOCKS, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_BLOCKS)); MSG msg; // 主消息循环: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函数: MyRegisterClass() // // 目的: 注册窗口类。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BLOCKS)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_BLOCKS); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&wcex); } // // 函数: InitInstance(HINSTANCE, int) // // 目的: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 将实例句柄存储在全局变量中 HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //绘制背景 VOID DrawBackGround(HDC hdc) { int x, y; HPEN hPen = (HPEN)GetStockObject(NULL_PEN); HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH); HPEN hPen1 = (HPEN)GetStockObject(NULL_PEN); HBRUSH hBrush1 = (HBRUSH)GetStockObject(BLACK_BRUSH); Rectangle(hdc, BOUND_SIZE, BOUND_SIZE, BOUND_SIZE+ TETRIS_SIZE*GAME_X, BOUND_SIZE+TETRIS_SIZE*GAME_Y); for (x = 0; x < GAME_X; x++) { for (y = 0; y < GAME_Y; y++) { if (game_board[x][y] == 1) { SelectObject(hdc, hBrush1); Rectangle(hdc, BOUND_SIZE + x*TETRIS_SIZE, BOUND_SIZE + y*TETRIS_SIZE, BOUND_SIZE + (x + 1)*TETRIS_SIZE, BOUND_SIZE + (y + 1)*TETRIS_SIZE); }else { SelectObject(hdc, hPen); SelectObject(hdc, hBrush); Rectangle(hdc, BOUND_SIZE + TETRIS_SIZE*x, BOUND_SIZE + TETRIS_SIZE*y, BOUND_SIZE + TETRIS_SIZE*x + TETRIS_SIZE, BOUND_SIZE + TETRIS_SIZE*y + TETRIS_SIZE); } } } } //绘制方块 VOID DrawTetris(HDC hdc, int x, int y, int tet[4][4]) { HPEN hPen = (HPEN)GetStockObject(BLACK_PEN); HBRUSH hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH); SelectObject(hdc, hPen); SelectObject(hdc, hBrush); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (tet[i][j]) { Rectangle(hdc, BOUND_SIZE + (x + j)*TETRIS_SIZE, BOUND_SIZE + (y + i)*TETRIS_SIZE, BOUND_SIZE + (x + j + 1 )*TETRIS_SIZE, BOUND_SIZE + (y + i + 1)*TETRIS_SIZE); } } } } //旋转方块 VOID rotateTetris(int tet[4][4]) { int x, y; int bNewTet[4][4]; for (x = 0; x < 4; x++) { for (y = 0; y < 4; y++) { bNewTet[x][y] = tet[3 - y][x]; } } //tet = bNewTet memcpy(tet, bNewTet, sizeof(bNewTet)); } //合并背景方块和消方块 VOID RefreshTetris(int x, int y, int TETData[4][4], int gb[GAME_X][GAME_Y]) { //合并TETData和gb; int i, j; for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { if (TETData[j][i] == 1) { gb[x + i][y + j] = 1; } } } int flag, newY; for (i = GAME_Y, newY = GAME_Y; i >= 0; i--) { flag = 1; for (j = 0; j < GAME_X; j++) { game_board[j][newY] = game_board[j][i]; if (game_board[j][i] == 0) { flag = 0; } } if (flag == 1) { //满格的话,用上一行替换这一行 }else { //如果没有满格的话 newY--; } } } //返回1的话就是碰到,返回0就是没有碰到; int CheckTetris(int x, int y, int TETData[4][4], int gb[GAME_X][GAME_Y]) { if (x < 0) { return 1; } int flag = 0, i = 0, j = 0; for (j=0; j < 4; j++) { for (i=0; i < 4; i++) { if (TETData[j][i] == 1) { if (x + i >= GAME_X) { return 1; } if (y + j >= GAME_Y) { return 1; } if (gb[x + i][y + j]) { return 1; } } } } return 0; } //随机生成方块 VOID generateTetris(int TETData[4][4]) { srand(time(NULL)); int getTetris = rand()%TetrisCount; currentTetris; memcpy(currentTetris, Tetris[getTetris], sizeof(currentTetris)); } // // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { memset(game_board, 0, sizeof(game_board)); RECT rect; int nWinX, nWinY, nClientX, nClientY, nScreenWidth, nScreenHeight, userWidth, userHeight; GetWindowRect(hWnd, &rect); //获取窗口大小 nWinX = rect.right - rect.left; nWinY = rect.bottom - rect.top; //获取客户区大小 GetClientRect(hWnd, &rect); nClientX = rect.right - rect.left; nClientY = rect.bottom - rect.top; //计算窗口大小 userWidth = 3 * BOUND_SIZE + GAME_X *TETRIS_SIZE + (nWinX - nClientX); userHeight = 2 * BOUND_SIZE + GAME_Y*TETRIS_SIZE + (nWinY - nClientY); //移动居中 nScreenWidth = GetSystemMetrics(SM_CXSCREEN); nScreenHeight = GetSystemMetrics(SM_CYSCREEN); //设置对象在桌面中的位置 MoveWindow(hWnd, (nScreenWidth - userWidth) / 2, (nScreenHeight - userHeight) / 2, userWidth, userHeight, TRUE); //启动定时器 SetTimer(hWnd, timer, 1000, NULL); } break; case WM_TIMER: { if (0==CheckTetris(X, Y + 1, currentTetris, game_board)) { Y++; } else { //合成方块到游戏面板中 RefreshTetris(X, Y , currentTetris, game_board); //生成新的方块 generateTetris(currentTetris); //X,Y重新赋值 Y = 0; X = 3; }; InvalidateRect(hWnd, NULL, true); } break; case WM_LBUTTONDOWN: { //测试代码 //rotateTetris(currentTetris) //刷新界面 //InvalidateRect(hWnd, NULL, true) } break; case WM_COMMAND: { int wmId = LOWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_KEYDOWN: { switch(wParam) { case VK_LEFT : { if (0 == CheckTetris(X-1, Y , currentTetris, game_board)) { X--; } } break; case VK_RIGHT: { if (0 == CheckTetris(X + 1, Y, currentTetris, game_board)) { X++; } } break; case VK_UP: { memcpy(tempTetris, currentTetris, sizeof(currentTetris)); rotateTetris(tempTetris); if (0 == CheckTetris(X, Y, tempTetris, game_board)) { rotateTetris(currentTetris); } } break; case VK_DOWN: { while (0 == CheckTetris(X, Y + 1, currentTetris, game_board)) { Y++; } } break; default: { } break; } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: 在此处添加使用 hdc 的任何绘图代码... DrawBackGround(hdc); DrawTetris(hdc, X,Y, currentTetris); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “关于”框的消息处理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
eof
天道酬勤
本文作者:方方和圆圆
本文链接:https://www.cnblogs.com/diligenceday/p/6079607.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
C 和C++
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2015-11-18 自己写一个JS单向数据流动库----one way binding
2014-11-18 jQuery1.4源码解读
2014-11-18 Handlebars的使用方法文档整理(Handlebars.js)
2013-11-18 JS建造者模式
2013-11-18 简单的装饰模式
2013-11-18 JS_工厂模式