标签:
基本功能实现了,样子可能不是很美观
总共5个文件
1 //2016/9/1 2 //c++和windows 简单api函数 俄罗斯方块 3 #include"Interface.h" 4 #include"Tetris.h" 5 #include <windows.h> 6 #include<random> 7 #include<iostream> 8 9 #define TIMER_SEC 1 10 #define TIMER_UPDATE 2 11 12 13 14 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 15 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 16 PSTR szCmdLine, int iCmdShow) 17 { 18 19 20 static TCHAR szAppName[] = TEXT("俄罗斯方块"); 21 HWND hwnd; 22 MSG msg; 23 WNDCLASS wndclass; 24 wndclass.style = CS_HREDRAW | CS_VREDRAW; 25 wndclass.lpfnWndProc = WndProc; 26 wndclass.cbClsExtra = 0; 27 wndclass.cbWndExtra = 0; 28 wndclass.hInstance = hInstance; 29 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 30 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 31 wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); 32 wndclass.lpszMenuName = NULL; 33 wndclass.lpszClassName = szAppName; 34 if (!RegisterClass(&wndclass)) 35 { 36 MessageBox(NULL, TEXT("This program requires Windows NT!"), 37 szAppName, MB_ICONERROR); 38 return 0; 39 } 40 hwnd = CreateWindow(szAppName, // window class name 41 TEXT("俄罗斯方块"), // window caption 42 WS_OVERLAPPEDWINDOW, // window style 43 50, // initial x position 44 10, // initial y position 45 400, // initial x size 46 700, // initial y size 47 NULL, // parent window handle 48 NULL, // window menu handle 49 hInstance, // program instance handle 50 NULL); // creation parameters 51 ShowWindow(hwnd, iCmdShow); 52 UpdateWindow(hwnd); 53 while (GetMessage(&msg, NULL, 0, 0)) 54 { 55 TranslateMessage(&msg); 56 DispatchMessage(&msg); 57 } 58 return msg.wParam; 59 } 60 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 61 { 62 static int cxClient, cyClient; 63 static Interface face(hwnd, BLOCK_NON_EXISTENT); 64 static Tetris ter; 65 static int count_up; 66 static int count_down; 67 static int count_slow; 68 static std::default_random_engine e; 69 static std::default_random_engine e_2; 70 static std::uniform_int_distribution<unsigned> u(0,5); 71 static std::uniform_int_distribution<unsigned> u_2(0, 5); 72 73 PAINTSTRUCT ps; 74 //HDC hdc; 75 //RECT rect; 76 switch (message) 77 { 78 case WM_CREATE: 79 SetTimer(hwnd, TIMER_SEC, 500, NULL); 80 /* SetTimer(hwnd, TIMER_UPDATE, 50, NULL); */ 81 ter.build(u_2(e_2),u(e),face); 82 return 0; 83 case WM_SIZE: 84 cxClient = LOWORD(lParam); 85 cyClient = HIWORD(lParam); 86 face.changeSize(cxClient, cyClient); 87 return 0; 88 case WM_TIMER: 89 switch (wParam) 90 { 91 case TIMER_SEC: 92 if (ter.downFall(face))//每秒一次的处理 93 { 94 if (!face.checkState()) 95 { 96 KillTimer(hwnd, TIMER_SEC); 97 MessageBox(NULL, TEXT("GAME OVER!!"), TEXT("俄罗斯方块"), 0); 98 SetTimer(hwnd, TIMER_SEC, 500, NULL); 99 face.clear(); 100 } 101 ter.build(u_2(e_2), u(e), face); //建立新方块 先默认了正方形 102 SetTimer(hwnd, TIMER_SEC,500, NULL); 103 count_down = count_up = 0; 104 } 105 InvalidateRect(hwnd, NULL, true); 106 break; 107 /*case TIMER_UPDATE: 108 InvalidateRect(hwnd, NULL, true); 109 break;*/ 110 } 111 return 0; 112 case WM_KEYDOWN: 113 switch (wParam) 114 { 115 case VK_RIGHT: 116 ter.Right_Movement(face); 117 InvalidateRect(hwnd, NULL, true); 118 break; 119 case VK_LEFT: 120 ter.Left_Movement(face); 121 InvalidateRect(hwnd, NULL, true); 122 break; 123 case VK_UP: 124 if (count_slow > 1 || count_down == 0 ) 125 { 126 count_slow++; 127 ter.ChangeShape(face); 128 MessageBeep(4); 129 InvalidateRect(hwnd, NULL, true); 130 } 131 if (++count_up <= 1) 132 { 133 SetTimer(hwnd, TIMER_SEC, 500, NULL); 134 count_down = 0; 135 } 136 break; 137 case VK_DOWN: 138 if (++count_down <= 1) 139 { 140 SetTimer(hwnd, TIMER_SEC, 20 , NULL); 141 count_up = 0; 142 count_slow = 0; 143 } 144 break; 145 } 146 case WM_PAINT: 147 face.drawBlock(ps, BLACK_BRUSH, GRAY_BRUSH); 148 return 0; 149 case WM_DESTROY: 150 KillTimer(hwnd, TIMER_SEC); 151 /* KillTimer(hwnd, TIMER_UPDATE);*/ 152 PostQuitMessage(0); 153 return 0; 154 } 155 return DefWindowProc(hwnd, message, wParam, lParam); 156 }
1 #include"Interface.h" 2 3 static const size_t cx, cy; 4 5 Interface::Interface(HWND hd, int b_ /*= BLOCK_FASTENED*/):hwnd(hd) 6 { 7 for (auto &row : isBlock) 8 { 9 for (auto &col : row) 10 { 11 col = b_; 12 } 13 } 14 } 15 16 void Interface::drawBlock(PAINTSTRUCT &ps, int fnObject_1, int fnObject_2) 17 { 18 //HDC hdc = GetDC(hwnd); //用了这个占用cpu大 19 HDC hdc = BeginPaint(hwnd, &ps); 20 HBRUSH hBrush_1 = (HBRUSH)::GetStockObject(fnObject_1); //方块画刷 21 HBRUSH hBrush_2 = (HBRUSH)::GetStockObject(fnObject_2); //方块画刷 22 RECT rect; 23 unsigned Block_h = height / cy; 24 unsigned Block_w = width / cx; 25 for (size_t i = 0;i < cy ; ++i) 26 for (size_t j = 0;j < cx; ++j) 27 { 28 if (isBlock[i][j] == BLOCK_FASTENED|| 29 isBlock[i][j] == BLOCK_FALL) 30 { 31 //以后可以在这里定义内嵌厚度 32 rect.left = j * Block_w + 2; 33 rect.top = (cy - i - 1) * Block_h + 2; 34 rect.right = (j + 1) * Block_w - 2; 35 rect.bottom = (cy - i) * Block_h - 2; 36 FrameRect(hdc, &rect, hBrush_1); 37 FillRect(hdc, &rect, hBrush_2); 38 } 39 } 40 EndPaint(hwnd, &ps); 41 } 42 43 44 void Interface::changeSize(unsigned wh, unsigned ht) 45 { 46 width = wh; 47 height = ht; 48 } 49 50 51 bool Interface::checkState() 52 { 53 for (size_t i = 0; i < cx; i++) 54 { 55 if (isBlock[cy][i] != BLOCK_NON_EXISTENT) 56 return false; 57 } 58 bool isFull; 59 for (size_t i = 0; i < cy ;i++) 60 { 61 isFull = true; 62 for (size_t j = 0; j < cx; j++) 63 { 64 if (isBlock[i][j] != BLOCK_FASTENED) 65 { 66 isFull = false; 67 break; 68 } 69 } 70 if (isFull && i != cy - 1) 71 { 72 Sink(i); 73 i--; //i不可少 74 } 75 else if (isFull && i == cy - 1) 76 { 77 for (size_t i = 0; i < cx; i++) 78 { 79 isBlock[cy - 1][i] = BLOCK_NON_EXISTENT; 80 } 81 } 82 } 83 return true; 84 } 85 86 87 void Interface::Sink(unsigned line) 88 { 89 for (size_t i = line + 1; i < cy; ++i) 90 { 91 for (size_t j = 0; j < cx; j++) 92 { 93 isBlock[i - 1][j] = isBlock[i][j]; 94 } 95 } 96 } 97 98 void Interface::clear() 99 { 100 for (size_t i = 0; i < cy + c; i++) 101 { 102 for (size_t j = 0; j < cx; j++) 103 { 104 isBlock[i][j] = BLOCK_NON_EXISTENT; 105 } 106 } 107 }
1 #ifndef TETERFACE 2 #define TETERFACE 3 4 constexpr int BLOCK_FASTENED = 1; //方块状态 5 constexpr int BLOCK_FALL = 2; 6 constexpr int BLOCK_NON_EXISTENT = 0; 7 8 #include<Windows.h> 9 #include<random> 10 class Interface 11 { 12 friend class Tetris; 13 public: 14 Interface(HWND, int b_ = true); 15 void drawBlock(PAINTSTRUCT&,int fnObject_1 = BLACK_BRUSH, int fnObject_2 = GRAY_BRUSH); 16 void changeSize(unsigned, unsigned); 17 bool checkState(); 18 void clear(); 19 private: 20 static const size_t cx = 10, cy = 18,c = 4; //12 + 4行8列 21 void Sink(unsigned); 22 int isBlock[cy + c][cx] = {}; 23 HWND hwnd; //界面内容代号 24 unsigned int width = 0, height = 0; //设置界面的高度和宽度 25 }; 26 #endif
1 #ifndef TETRIS 2 #define TETRIS 3 4 #include"Interface.h" 5 #include<vector> 6 7 constexpr int SHAPE_0 = 0; 8 constexpr int SHAPE_1 = 1; 9 constexpr int SHAPE_2 = 2; 10 constexpr int SHAPE_3 = 3; 11 constexpr int SHAPE_4 = 4; 12 constexpr int SHAPE_5 = 5; 13 14 15 16 struct Block { 17 int y; //垂直坐标 18 int x; //水平坐标 19 int center = 0; 20 }; 21 22 23 24 class Tetris 25 { 26 public: 27 Tetris() = default; 28 void build(int,unsigned,Interface&); 29 bool downFall(Interface&); 30 void Left_Movement(Interface&); 31 void Right_Movement(Interface&); 32 void ChangeShape(Interface&); 33 private: 34 bool isSomethingBlow(Interface&); 35 bool isSomethingLeft(Interface&); 36 bool isSomethingRight(Interface&); 37 bool rotate(const Block&, Interface&); 38 unsigned InitalPositoin = 0; 39 std::vector<Block>Accommodation; 40 int type; //方块类别 41 int direction = 0; 42 int radius; 43 int help = 0; 44 }; 45 #endif
1 #include"Tetris.h" 2 #include<algorithm> 3 4 bool isbiger_1(const Block &a, const Block &b) 5 { 6 if (a.x < b.x) 7 { 8 return true; 9 } 10 else if (a.x == b.x && a.y < b.y) 11 { 12 return true; 13 } 14 else 15 { 16 return false; 17 } 18 } 19 20 bool isbiger_x_up(const Block &a, const Block &b) 21 { 22 return a.x < b.x; 23 } 24 bool isbiger_y_up(const Block &a, const Block &b) 25 { 26 return a.y < b.y; 27 } 28 29 bool isbiger_x_down(const Block &a, const Block &b) 30 { 31 return a.x > b.x; 32 } 33 bool isbiger_y_down(const Block &a, const Block &b) 34 { 35 return a.y > b.y; 36 } 37 38 39 void Tetris::build(int te,unsigned pos, Interface& face) 40 { 41 InitalPositoin = pos; //注意初始值是有范围限制的 42 type = te; 43 unsigned cy = face.cy; 44 direction = 0; 45 Block block_1, block_2, block_3; 46 Block block_4, block_5, block_6;; 47 help = 0; 48 49 switch (type) 50 { 51 case SHAPE_0: 52 block_1.y = cy, block_1.x = InitalPositoin; //左下 53 block_2.y = cy, block_2.x = InitalPositoin + 1;//右下 54 block_3.y = cy + 1, block_3.x = InitalPositoin;//左上 55 block_4.y = cy + 1, block_4.x = InitalPositoin + 1;//右上 56 radius = 2; 57 Accommodation.clear(); 58 Accommodation.push_back(block_1); 59 Accommodation.push_back(block_2); 60 Accommodation.push_back(block_3); 61 Accommodation.push_back(block_4); 62 sort(Accommodation.begin(), Accommodation.end(), 63 isbiger_1); 64 break; 65 case SHAPE_1: 66 block_1.y = cy, block_1.x = InitalPositoin; 67 block_2.y = cy, block_2.x = InitalPositoin + 1; 68 block_3.y = cy + 1, block_3.x = InitalPositoin + 1; 69 block_4.y = cy + 2, block_4.x = InitalPositoin + 1; 70 block_2.center = 1; 71 72 radius = 3; 73 Accommodation.clear(); 74 Accommodation.push_back(block_1); 75 Accommodation.push_back(block_2); 76 Accommodation.push_back(block_3); 77 Accommodation.push_back(block_4); 78 sort(Accommodation.begin(), Accommodation.end(), 79 isbiger_1); 80 break; 81 case SHAPE_2: 82 block_1.y = cy, block_1.x = InitalPositoin; 83 block_2.y = cy, block_2.x = InitalPositoin + 1; 84 block_3.y = cy + 1, block_3.x = InitalPositoin + 1; 85 block_4.y = cy + 1, block_4.x = InitalPositoin + 2; 86 radius = 3; 87 block_1.center = 1; 88 Accommodation.clear(); 89 Accommodation.push_back(block_1); 90 Accommodation.push_back(block_2); 91 Accommodation.push_back(block_3); 92 Accommodation.push_back(block_4); 93 sort(Accommodation.begin(), Accommodation.end(), 94 isbiger_1); 95 break; 96 case SHAPE_3: 97 block_1.y = cy, block_1.x = InitalPositoin; 98 block_2.y = cy + 1, block_2.x = InitalPositoin; 99 block_3.y = cy + 2, block_3.x = InitalPositoin; 100 block_4.y = cy + 3, block_4.x = InitalPositoin; 101 radius = 4; 102 block_1.center = 1; 103 block_4.center = 1; 104 Accommodation.clear(); 105 Accommodation.push_back(block_1); 106 Accommodation.push_back(block_2); 107 Accommodation.push_back(block_3); 108 Accommodation.push_back(block_4); 109 sort(Accommodation.begin(), Accommodation.end(), 110 isbiger_1); 111 break; 112 case SHAPE_4: 113 block_1.y = cy, block_1.x = InitalPositoin; 114 radius = 1; 115 Accommodation.clear(); 116 Accommodation.push_back(block_1); 117 /*sort(Accommodation.begin(), Accommodation.end(), 118 [](const Block& a, const Block& b) { return a.y < b.y; });*/ 119 break; 120 case SHAPE_5: 121 122 block_1.y = cy, block_1.x = InitalPositoin; 123 block_2.y = cy, block_2.x = InitalPositoin + 1; 124 block_3.y = cy + 1, block_3.x = InitalPositoin; 125 block_4.y = cy + 1, block_4.x = InitalPositoin + 1; 126 block_5.y = cy + 2, block_5.x = InitalPositoin; 127 block_6.y = cy + 2, block_6.x = InitalPositoin + 1; 128 radius = 3; 129 block_1.center = 1; 130 block_2.center = 1; 131 block_5.center = 1; 132 block_6.center = 1; 133 Accommodation.clear(); 134 Accommodation.push_back(block_1); 135 Accommodation.push_back(block_2); 136 Accommodation.push_back(block_3); 137 Accommodation.push_back(block_4); 138 Accommodation.push_back(block_5); 139 Accommodation.push_back(block_6); 140 sort(Accommodation.begin(), Accommodation.end(), 141 isbiger_1); 142 break; 143 default: 144 break; 145 } 146 } 147 148 bool Tetris::downFall(Interface &face) 149 { 150 if (isSomethingBlow(face)) 151 { 152 for (auto it : Accommodation) 153 { 154 face.isBlock[it.y][it.x] = BLOCK_FASTENED; 155 } 156 return true; 157 } 158 else 159 { 160 for (auto &it : Accommodation) 161 { 162 face.isBlock[it.y - 1][it.x] = BLOCK_FALL; 163 face.isBlock[it.y][it.x] = BLOCK_NON_EXISTENT; 164 it.y--; 165 } 166 return false; 167 } 168 } 169 170 171 bool Tetris::isSomethingBlow(Interface& face) 172 { 173 for (auto it : Accommodation) 174 { 175 if (face.isBlock[it.y - 1][it.x] == BLOCK_FASTENED 176 || it.y == 0) 177 { 178 return true; 179 } 180 } 181 return false; 182 } 183 184 185 186 187 bool Tetris::isSomethingLeft(Interface& face) 188 { 189 for (auto it : Accommodation) 190 { 191 if (face.isBlock[it.y][it.x - 1] == BLOCK_FASTENED 192 || it.x == 0) 193 { 194 return true; 195 } 196 } 197 return false; 198 } 199 200 bool Tetris::isSomethingRight(Interface& face) 201 { 202 for (auto it : Accommodation) 203 { 204 if (face.isBlock[it.y][it.x + 1] == BLOCK_FASTENED 205 || it.x == face.cx - 1) 206 { 207 return true; 208 } 209 } 210 return false; 211 } 212 213 214 void Tetris::Left_Movement(Interface& face) 215 { 216 if (isSomethingLeft(face)) 217 { 218 return; 219 } 220 else 221 { 222 sort(Accommodation.begin(), Accommodation.end(), 223 [](const Block& a, const Block& b) { return a.x < b.x; }); 224 for (auto &it : Accommodation) 225 { 226 face.isBlock[it.y][it.x - 1] = BLOCK_FALL; 227 face.isBlock[it.y][it.x] = BLOCK_NON_EXISTENT; 228 it.x--; 229 } 230 sort(Accommodation.begin(), Accommodation.end(), 231 isbiger_1); 232 } 233 } 234 235 void Tetris::Right_Movement(Interface& face) 236 { 237 if (isSomethingRight(face)) 238 { 239 return; 240 } 241 else 242 { 243 sort(Accommodation.begin(), Accommodation.end(), 244 [](const Block& a, const Block& b) { return a.x > b.x; }); 245 for (auto &it : Accommodation) 246 { 247 face.isBlock[it.y][it.x + 1] = BLOCK_FALL; 248 face.isBlock[it.y][it.x] = BLOCK_NON_EXISTENT; 249 it.x++; 250 } 251 sort(Accommodation.begin(), Accommodation.end(), 252 isbiger_1); 253 } 254 } 255 256 257 258 void Tetris::ChangeShape(Interface& face) 259 { 260 for (auto &it : Accommodation) 261 { 262 face.isBlock[it.y][it.x] = BLOCK_NON_EXISTENT; 263 } 264 sort(Accommodation.begin(), Accommodation.end(), 265 isbiger_1); 266 help++; 267 268 if (type == SHAPE_3&& help == 1) 269 { 270 sort(Accommodation.begin(), Accommodation.end(), 271 isbiger_y_up); 272 } 273 if (type == SHAPE_3&& help == 2 ) 274 { 275 sort(Accommodation.begin(), Accommodation.end(), 276 isbiger_x_up); 277 } 278 if (type == SHAPE_3&& help == 3) 279 { 280 sort(Accommodation.begin(), Accommodation.end(), 281 isbiger_y_down); 282 } 283 if (type == SHAPE_3&& help == 4) 284 { 285 sort(Accommodation.begin(), Accommodation.end(), 286 isbiger_x_down); 287 } 288 if (type == SHAPE_5&& help == 2) 289 { 290 sort(Accommodation.begin(), Accommodation.end(), 291 isbiger_x_up); 292 sort(Accommodation.begin(), Accommodation.end(), 293 isbiger_y_down); 294 } 295 if (type == SHAPE_5&& help == 3) 296 { 297 sort(Accommodation.begin(), Accommodation.end(), 298 isbiger_x_down); 299 sort(Accommodation.begin(), Accommodation.end(), 300 isbiger_y_down); 301 } 302 if (help == 4 && type == SHAPE_5) 303 { 304 sort(Accommodation.begin(), Accommodation.end(), 305 isbiger_x_down); 306 sort(Accommodation.begin(), Accommodation.end(), 307 isbiger_y_up); 308 } 309 help = help % 4; 310 Block center; 311 center = Accommodation.front(); 312 for (auto it : Accommodation) 313 { 314 if (it.center) 315 { 316 center = it; 317 break; 318 } 319 } 320 rotate(center, face); 321 for (auto &it : Accommodation) 322 { 323 face.isBlock[it.y][it.x] = BLOCK_FALL; 324 } 325 sort(Accommodation.begin(), Accommodation.end(), 326 isbiger_1); 327 328 } 329 330 331 bool Tetris::rotate(const Block ¢er, Interface &face) 332 { 333 for (auto it : Accommodation) 334 { 335 auto item = center.x + (it.y - center.y); 336 it.y = center.y - (it.x - center.x); 337 it.x = item; 338 if (face.isBlock[it.y][it.x] == BLOCK_FASTENED //有毒 339 ||it.x > face.cx - 1||it.x < 0 340 ||it.y > face.cy - 1||it.y < 0) 341 return false; 342 } 343 for (auto &it : Accommodation) 344 { 345 auto item = center.x + (it.y - center.y); 346 it.y = center.y - (it.x - center.x); 347 it.x = item; 348 } 349 return true; 350 }
标签:
原文地址:http://www.cnblogs.com/7-29/p/5933427.html