先说这种俄罗斯方块的游戏规则('w','a','s','d' -> 旋转,左边,快速下降,右边):
1、右边4x4方块群内左键自造积木,右键放下积木(只有等当前积木下落停靠后,右键放下新的积木才有效)。
2、右面的墙是粘性墙,会黏住最右边的积木而只能下降不能向左(这会形成分散型积木,从而出现真空静止的积木)。
3、靠上固定的积木就会一同固定(也就是说每块积木之间都有粘性)
(VC08下编译通过)
源文件这里下载: SelfTetrisV1.1.rar
1、右边4x4方块群内左键自造积木,右键放下积木(只有等当前积木下落停靠后,右键放下新的积木才有效)。
2、右面的墙是粘性墙,会黏住最右边的积木而只能下降不能向左(这会形成分散型积木,从而出现真空静止的积木)。
3、靠上固定的积木就会一同固定(也就是说每块积木之间都有粘性)
左手键盘wasd,右手(或者女朋友的手)操作鼠标左键来构造新积木,右键放下构造的积木。
(VC08下编译通过)
1
/**/
/* SelfTetris.h */
2
3
4 #include < windows.h >
5
6 class SelfTetris
7 {
8#define DELTA_LEFTTOP 20
9#define PV(v) (DELTA_LEFTTOP+(v)*D_LEN)
10#define BIN_FOR_BEGINE(i,j,topi,topj) for(i=0;i!=(topi);++i)for(j=0;j!=(topj);++j)
11public:
12 void Action();
13 int IsMove(int x,int y);/**//* 是否能向(x,y)向量移动 */
14 int IsDis(int y);/**//* 是否消除第y行 */
15 int GoCurdle(int x,int y,int isFall,int isX);/**//* 按(x,y)向量*/
16 void KeyDown(WPARAM wparam);
17 void Run(int x,int y,int isX);/**//* 一次移动 */
18 void RotateBlocks();
19 void CastBlocks();
20 void SetBlocks(int mx,int my);
21 int Rectangle(int i,int j,int isStill);/**//* 在游戏矩阵内画矩形,isStill为是否画静止类型的矩形 */
22 SelfTetris(int dtime_=100);
23public:
24 static const int W_NUM=18,H_NUM=35,D_LEN=15,H_HIDE=1;/**//* 游戏区域宽,高,单位长度象素,顶部是否隐藏*/
25 int canDrop,_x,_y,obj[4][4];/**//* _x,_y 为当前下落积木重心 ,obj为当前构造积木形状, canDrop为是否可下新积木*/
26 int scores;/**//* 分数,临时变量*/
27 int board[H_NUM][W_NUM];/**//* 俄罗斯方块游戏区域矩阵 */
28 int x,y,dtime,i,j;/**//* x,y,i,j为临时变量 dtime为游戏action周期*/
29 HDC hdc;
30} ;
31
2
3
4 #include < windows.h >
5
6 class SelfTetris
7 {
8#define DELTA_LEFTTOP 20
9#define PV(v) (DELTA_LEFTTOP+(v)*D_LEN)
10#define BIN_FOR_BEGINE(i,j,topi,topj) for(i=0;i!=(topi);++i)for(j=0;j!=(topj);++j)
11public:
12 void Action();
13 int IsMove(int x,int y);/**//* 是否能向(x,y)向量移动 */
14 int IsDis(int y);/**//* 是否消除第y行 */
15 int GoCurdle(int x,int y,int isFall,int isX);/**//* 按(x,y)向量*/
16 void KeyDown(WPARAM wparam);
17 void Run(int x,int y,int isX);/**//* 一次移动 */
18 void RotateBlocks();
19 void CastBlocks();
20 void SetBlocks(int mx,int my);
21 int Rectangle(int i,int j,int isStill);/**//* 在游戏矩阵内画矩形,isStill为是否画静止类型的矩形 */
22 SelfTetris(int dtime_=100);
23public:
24 static const int W_NUM=18,H_NUM=35,D_LEN=15,H_HIDE=1;/**//* 游戏区域宽,高,单位长度象素,顶部是否隐藏*/
25 int canDrop,_x,_y,obj[4][4];/**//* _x,_y 为当前下落积木重心 ,obj为当前构造积木形状, canDrop为是否可下新积木*/
26 int scores;/**//* 分数,临时变量*/
27 int board[H_NUM][W_NUM];/**//* 俄罗斯方块游戏区域矩阵 */
28 int x,y,dtime,i,j;/**//* x,y,i,j为临时变量 dtime为游戏action周期*/
29 HDC hdc;
30} ;
31
1
/**/
/* SelfTetris.cpp */
2
3 #include " SelfTetris.h "
4
5 int SelfTetris::Rectangle( int i, int j, int isStill)
6 {
7 isStill=isStill?GRAY_BRUSH:WHITE_BRUSH;
8 SelectObject (hdc, GetStockObject (isStill)) ;
9 ::Rectangle(hdc,PV(j),PV(i),PV(j+1),PV(i+1));
10 SelectObject (hdc, GetStockObject (GRAY_BRUSH)) ;
11 return 0;
12}
13 int SelfTetris::IsMove( int x, int y)
14 {
15 BIN_FOR_BEGINE(i,j,H_NUM,W_NUM)
16 if((board[i][j]==2)&&((i+y>=H_NUM||i+y<=-1)||(board[i+y][j+x]==1)))
17 return -1;
18 else if((board[i][j]==2)&&((j+x>=W_NUM||j+x<=-1)))
19 return 0;
20 return 1;
21}
22 int SelfTetris::IsDis( int y)
23 {
24 for(j=0;j!=W_NUM;j++)
25 if(board[y][j]!=1) return 0;
26 for(j=0;j!=W_NUM;j++) board[y][j]=0;
27 for(int i=y-1;i!=-1;--i)
28 for(int j=0;j!=W_NUM;++j)
29 if(board[i][j]==1)
30 {
31 board[i+1][j]=1;
32 i>=H_HIDE?Rectangle(i+1,j,1):1;
33 board[i][j]=0;
34 }
35 return 1;
36}
37 int SelfTetris::GoCurdle( int x, int y, int isFall, int isX)
38 {
39 int tag=0,a,b,d;
40 a=W_NUM-1,b=-1,d=-1;
41 if(x==-1) b=W_NUM-1,a=0,d=1;
42 for(i=H_NUM-1;i!=-1;--i)
43 for(j=a;j!=b;j+=d)
44 if(board[i][j]==2)
45 {
46 if(isFall==-1){
47 canDrop=1;
48 board[i][j]=1;
49 i>=H_HIDE&&isX==0?Rectangle(i,j,1):1;
50 }else if(isFall==1)
51 {
52 board[i+y][j+x]=2,board[i][j]=0;
53 i>=H_HIDE&&isX==0?Rectangle(i+y,j+x,0):1;
54 tag=1;
55 }
56 }else if(board[i][j]==1)
57 i>=H_HIDE&&isX==0?Rectangle(i,j,1):1;
58 if(tag==1) _x+=x,_y+=y;
59 if(isX==0)
60 BIN_FOR_BEGINE(i,j,4,4)
61 Rectangle(H_NUM/2+4+i,W_NUM+4+j,!(obj[i][j]==1));
62 return isFall;
63}
64 void SelfTetris::KeyDown(WPARAM wparam)
65 {
66 switch (wparam)
67 {
68 case 0x41:i=-1;break;
69 case 0x57: RotateBlocks();break;
70 case 0x53:i=2;break;
71 case 0x44:i=1;
72 }
73}
74 void SelfTetris::Run( int x, int y, int isX)
75 {
76 SelectObject (hdc, GetStockObject (BLACK_PEN)) ;
77 ::Rectangle(hdc,DELTA_LEFTTOP,DELTA_LEFTTOP+H_HIDE*D_LEN,DELTA_LEFTTOP+W_NUM*D_LEN,DELTA_LEFTTOP+H_NUM*D_LEN);
78 SelectObject (hdc, GetStockObject (GRAY_BRUSH)) ;
79 int mul=0;
80 GoCurdle(x,y,IsMove(x,y),isX);
81 for(i=0;i!=H_NUM;i++)
82 IsDis(i)?++mul>=2?scores+=10*mul:scores+=10:1;
83 static wchar_t str[40];
84 SelectObject (hdc, GetStockObject (BLACK_PEN));
85 wsprintf(str,L" Total Score : %d ",scores);
86 TextOut(hdc,320,200,str,wcslen(str));
87 wsprintf(str,L" Game Level : %d ",scores/10+1);
88 TextOut(hdc,320,250,str,wcslen(str));
89}
90
91 void SelfTetris::RotateBlocks()
92 {
93 int _board[H_NUM][W_NUM]={0};
94 BIN_FOR_BEGINE(x,y,H_NUM,W_NUM)
95 if(board[x][y]==2)
96 if((_x+_y-x)>=W_NUM||(_x+_y-x)<=-1||(_y-(_x-y))>=H_NUM||
97 (_y-(_x-y))<=-1||board[_y-(_x-y)][_x+(_y-x)]==1)
98 return;
99 BIN_FOR_BEGINE(x,y,H_NUM,W_NUM)
100 if(board[x][y]==2)
101 board[x][y]=0,_board[_y-(_x-y)][_x+(_y-x)]=2;
102 BIN_FOR_BEGINE(x,y,H_NUM,W_NUM)
103 if(_board[x][y]==2)
104 board[x][y]=_board[x][y];
105}
106 void SelfTetris::SetBlocks( int mx, int my)
107 {
108 BIN_FOR_BEGINE(x,y,4,4)
109 if(my>PV(H_NUM/2+4+x)&&
110 my<PV(H_NUM/2+4+x+1)&&
111 mx>PV(W_NUM+4+y)&&
112 mx<PV(W_NUM+4+y+1))
113 obj[x][y]=(obj[x][y]+1)%2;
114}
115 void SelfTetris::CastBlocks()
116 {
117 if(canDrop==0)
118 return;
119 BIN_FOR_BEGINE(x,y,4,4)
120 if(obj[x][y]==1)
121 board[0+x][W_NUM/2+y]=2;
122 canDrop=0;
123 _x=W_NUM/2+2;
124 _y=2;
125}
126 void SelfTetris::Action()
127 {
128 if(i==2) Run(0,1,1);
129 else if(i!=0) Run(i,0,1);
130 for(x=0;x!=scores/10+1;x++)
131 Run(0,1,0);
132 i=0;
133}
134 SelfTetris::SelfTetris( int dtime_)
135 {
136 canDrop=0;
137 memset(obj,0,sizeof(int)*16);
138 memset(board,0,sizeof(int)*H_NUM*W_NUM);
139 board[0][W_NUM/2-1]=board[0][W_NUM/2+2]=board[0][W_NUM/2+4]=board[0][W_NUM/2+3]=2;
140 _x=W_NUM/2+2;
141 _y=2;
142 i=j=0;
143 scores=0;
144 dtime=dtime_;
145}
2
3 #include " SelfTetris.h "
4
5 int SelfTetris::Rectangle( int i, int j, int isStill)
6 {
7 isStill=isStill?GRAY_BRUSH:WHITE_BRUSH;
8 SelectObject (hdc, GetStockObject (isStill)) ;
9 ::Rectangle(hdc,PV(j),PV(i),PV(j+1),PV(i+1));
10 SelectObject (hdc, GetStockObject (GRAY_BRUSH)) ;
11 return 0;
12}
13 int SelfTetris::IsMove( int x, int y)
14 {
15 BIN_FOR_BEGINE(i,j,H_NUM,W_NUM)
16 if((board[i][j]==2)&&((i+y>=H_NUM||i+y<=-1)||(board[i+y][j+x]==1)))
17 return -1;
18 else if((board[i][j]==2)&&((j+x>=W_NUM||j+x<=-1)))
19 return 0;
20 return 1;
21}
22 int SelfTetris::IsDis( int y)
23 {
24 for(j=0;j!=W_NUM;j++)
25 if(board[y][j]!=1) return 0;
26 for(j=0;j!=W_NUM;j++) board[y][j]=0;
27 for(int i=y-1;i!=-1;--i)
28 for(int j=0;j!=W_NUM;++j)
29 if(board[i][j]==1)
30 {
31 board[i+1][j]=1;
32 i>=H_HIDE?Rectangle(i+1,j,1):1;
33 board[i][j]=0;
34 }
35 return 1;
36}
37 int SelfTetris::GoCurdle( int x, int y, int isFall, int isX)
38 {
39 int tag=0,a,b,d;
40 a=W_NUM-1,b=-1,d=-1;
41 if(x==-1) b=W_NUM-1,a=0,d=1;
42 for(i=H_NUM-1;i!=-1;--i)
43 for(j=a;j!=b;j+=d)
44 if(board[i][j]==2)
45 {
46 if(isFall==-1){
47 canDrop=1;
48 board[i][j]=1;
49 i>=H_HIDE&&isX==0?Rectangle(i,j,1):1;
50 }else if(isFall==1)
51 {
52 board[i+y][j+x]=2,board[i][j]=0;
53 i>=H_HIDE&&isX==0?Rectangle(i+y,j+x,0):1;
54 tag=1;
55 }
56 }else if(board[i][j]==1)
57 i>=H_HIDE&&isX==0?Rectangle(i,j,1):1;
58 if(tag==1) _x+=x,_y+=y;
59 if(isX==0)
60 BIN_FOR_BEGINE(i,j,4,4)
61 Rectangle(H_NUM/2+4+i,W_NUM+4+j,!(obj[i][j]==1));
62 return isFall;
63}
64 void SelfTetris::KeyDown(WPARAM wparam)
65 {
66 switch (wparam)
67 {
68 case 0x41:i=-1;break;
69 case 0x57: RotateBlocks();break;
70 case 0x53:i=2;break;
71 case 0x44:i=1;
72 }
73}
74 void SelfTetris::Run( int x, int y, int isX)
75 {
76 SelectObject (hdc, GetStockObject (BLACK_PEN)) ;
77 ::Rectangle(hdc,DELTA_LEFTTOP,DELTA_LEFTTOP+H_HIDE*D_LEN,DELTA_LEFTTOP+W_NUM*D_LEN,DELTA_LEFTTOP+H_NUM*D_LEN);
78 SelectObject (hdc, GetStockObject (GRAY_BRUSH)) ;
79 int mul=0;
80 GoCurdle(x,y,IsMove(x,y),isX);
81 for(i=0;i!=H_NUM;i++)
82 IsDis(i)?++mul>=2?scores+=10*mul:scores+=10:1;
83 static wchar_t str[40];
84 SelectObject (hdc, GetStockObject (BLACK_PEN));
85 wsprintf(str,L" Total Score : %d ",scores);
86 TextOut(hdc,320,200,str,wcslen(str));
87 wsprintf(str,L" Game Level : %d ",scores/10+1);
88 TextOut(hdc,320,250,str,wcslen(str));
89}
90
91 void SelfTetris::RotateBlocks()
92 {
93 int _board[H_NUM][W_NUM]={0};
94 BIN_FOR_BEGINE(x,y,H_NUM,W_NUM)
95 if(board[x][y]==2)
96 if((_x+_y-x)>=W_NUM||(_x+_y-x)<=-1||(_y-(_x-y))>=H_NUM||
97 (_y-(_x-y))<=-1||board[_y-(_x-y)][_x+(_y-x)]==1)
98 return;
99 BIN_FOR_BEGINE(x,y,H_NUM,W_NUM)
100 if(board[x][y]==2)
101 board[x][y]=0,_board[_y-(_x-y)][_x+(_y-x)]=2;
102 BIN_FOR_BEGINE(x,y,H_NUM,W_NUM)
103 if(_board[x][y]==2)
104 board[x][y]=_board[x][y];
105}
106 void SelfTetris::SetBlocks( int mx, int my)
107 {
108 BIN_FOR_BEGINE(x,y,4,4)
109 if(my>PV(H_NUM/2+4+x)&&
110 my<PV(H_NUM/2+4+x+1)&&
111 mx>PV(W_NUM+4+y)&&
112 mx<PV(W_NUM+4+y+1))
113 obj[x][y]=(obj[x][y]+1)%2;
114}
115 void SelfTetris::CastBlocks()
116 {
117 if(canDrop==0)
118 return;
119 BIN_FOR_BEGINE(x,y,4,4)
120 if(obj[x][y]==1)
121 board[0+x][W_NUM/2+y]=2;
122 canDrop=0;
123 _x=W_NUM/2+2;
124 _y=2;
125}
126 void SelfTetris::Action()
127 {
128 if(i==2) Run(0,1,1);
129 else if(i!=0) Run(i,0,1);
130 for(x=0;x!=scores/10+1;x++)
131 Run(0,1,0);
132 i=0;
133}
134 SelfTetris::SelfTetris( int dtime_)
135 {
136 canDrop=0;
137 memset(obj,0,sizeof(int)*16);
138 memset(board,0,sizeof(int)*H_NUM*W_NUM);
139 board[0][W_NUM/2-1]=board[0][W_NUM/2+2]=board[0][W_NUM/2+4]=board[0][W_NUM/2+3]=2;
140 _x=W_NUM/2+2;
141 _y=2;
142 i=j=0;
143 scores=0;
144 dtime=dtime_;
145}
1
/**/
/* TetrisGame.cpp */
2
3 #include " SelfTetris.h "
4
5 SelfTetris aTetris( 100 );
6
7 LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
8 {
9 aTetris.hdc=GetDC(hwnd);
10 int mx = (int)LOWORD(lparam),my = (int)HIWORD(lparam);
11 switch(msg)
12 {
13 case WM_KEYDOWN:
14 aTetris.KeyDown(wparam);
15 break;
16 case WM_LBUTTONDOWN:
17 aTetris.SetBlocks(mx,my);
18 break;
19 case WM_RBUTTONUP:
20 aTetris.CastBlocks();
21 break;
22 case WM_CREATE:
23 SetTimer(hwnd,10,aTetris.dtime,0);
24 break;
25 case WM_TIMER:
26
27 aTetris.Action();
28 break;
29 case WM_PAINT:
30 break;
31 case WM_CLOSE :
32 MessageBoxW(0,L"非常感谢测试~",L"SelfTetrisv1.0",0);
33 break;
34 case WM_QUIT:
35 case WM_DESTROY:
36 PostQuitMessage(0);
37 break;
38 default:break;
39 }
40 ReleaseDC(hwnd,aTetris.hdc);
41 return DefWindowProc(hwnd, msg, wparam, lparam);
42}
43
44
45 int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE hprevinstance,LPSTR lpcmdline, int ncmdshow)
46 {
47 WNDCLASSEX winclass={sizeof(WNDCLASSEX),CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
48 WindowProc,0,0,hinstance,LoadIcon(NULL, IDI_APPLICATION),
49 LoadCursor(NULL, IDC_ARROW),(HBRUSH__*)GetStockObject(BLACK_BRUSH),0,
50 L"SelfTetris",0};
51 HWND hwnd;
52 MSG msg;
53 if (!RegisterClassEx(&winclass))
54 return 0;
55 if (!(hwnd = CreateWindowEx(NULL,L"SelfTetris",L"SelfTetrisV1.0",
56 WS_OVERLAPPEDWINDOW | WS_VISIBLE,0,0,455,600,NULL,NULL,hinstance,NULL)))
57 return 0;
58
59 while(GetMessage(&msg,NULL,0,0))
60 {
61 TranslateMessage(&msg);
62 DispatchMessage(&msg);
63 }
64 return msg.wParam;
65}
2
3 #include " SelfTetris.h "
4
5 SelfTetris aTetris( 100 );
6
7 LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
8 {
9 aTetris.hdc=GetDC(hwnd);
10 int mx = (int)LOWORD(lparam),my = (int)HIWORD(lparam);
11 switch(msg)
12 {
13 case WM_KEYDOWN:
14 aTetris.KeyDown(wparam);
15 break;
16 case WM_LBUTTONDOWN:
17 aTetris.SetBlocks(mx,my);
18 break;
19 case WM_RBUTTONUP:
20 aTetris.CastBlocks();
21 break;
22 case WM_CREATE:
23 SetTimer(hwnd,10,aTetris.dtime,0);
24 break;
25 case WM_TIMER:
26
27 aTetris.Action();
28 break;
29 case WM_PAINT:
30 break;
31 case WM_CLOSE :
32 MessageBoxW(0,L"非常感谢测试~",L"SelfTetrisv1.0",0);
33 break;
34 case WM_QUIT:
35 case WM_DESTROY:
36 PostQuitMessage(0);
37 break;
38 default:break;
39 }
40 ReleaseDC(hwnd,aTetris.hdc);
41 return DefWindowProc(hwnd, msg, wparam, lparam);
42}
43
44
45 int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE hprevinstance,LPSTR lpcmdline, int ncmdshow)
46 {
47 WNDCLASSEX winclass={sizeof(WNDCLASSEX),CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
48 WindowProc,0,0,hinstance,LoadIcon(NULL, IDI_APPLICATION),
49 LoadCursor(NULL, IDC_ARROW),(HBRUSH__*)GetStockObject(BLACK_BRUSH),0,
50 L"SelfTetris",0};
51 HWND hwnd;
52 MSG msg;
53 if (!RegisterClassEx(&winclass))
54 return 0;
55 if (!(hwnd = CreateWindowEx(NULL,L"SelfTetris",L"SelfTetrisV1.0",
56 WS_OVERLAPPEDWINDOW | WS_VISIBLE,0,0,455,600,NULL,NULL,hinstance,NULL)))
57 return 0;
58
59 while(GetMessage(&msg,NULL,0,0))
60 {
61 TranslateMessage(&msg);
62 DispatchMessage(&msg);
63 }
64 return msg.wParam;
65}
源文件这里下载: SelfTetrisV1.1.rar