码迷,mamicode.com
首页 > 编程语言 > 详细

俄罗斯方块c++

时间:2016-10-06 10:30:34      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

基本功能实现了,样子可能不是很美观

总共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 &center, 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 }










 

俄罗斯方块c++

标签:

原文地址:http://www.cnblogs.com/7-29/p/5933427.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!