俄罗斯方块修复BUG版






//*********************************************//
//**************  头文件  *********************//
//*********************************************//
#include <windows.h>
#include <time.h>
#include "stdafx.h"




//*********************************************//
//**************  宏定义  *********************//
//*********************************************//
#define WND_POS_X 10 //窗口左上角点的横坐标
#define WND_POS_Y 10 //窗口左上角点的纵坐标
#define WND_WIDTH 500 //窗口的宽度
#define WND_HEIGHT 600 //窗口的高度
#define RECT_UPPER_X 0 //背景矩形框的左上角点的横坐标
#define RECT_UPPER_Y 0 //背景矩形框的左上角点的纵坐标
#define RECT_LOWER_X 300 //背景矩形框的右下角点的横坐标
#define RECT_LOWER_Y 620 //背景矩形框的右下角点的纵坐标
#define SIDE_LEN 30 //游戏小方块的边长
#define G_ARR_ROW (RECT_LOWER_Y/SIDE_LEN) // 背景矩形框的行数 600/30=20行
#define G_ARR_RANK (RECT_LOWER_X/SIDE_LEN)// 背景矩形框的列数 300/30=10列
#define COMB_ROW 2 //随机方块的组合使用2行4列矩阵存储
#define COMB_RANK 4
#define CHANGE_SIZE 3 //3*3矩阵作为旋转矩阵
#define N_TIMER 1 //定时器的ID
#define T_TIMER 500 //定时器的时间,单位为毫秒
#define IDR_MENU1                       130
#define IDR_MENU3                       133
#define IDI_ICON2                       134
#define N_TIMER                          1


//*********************************************//
//**************  全局变量  *********************//
//*********************************************//
int g_arrBackGround[G_ARR_ROW][G_ARR_RANK] = { 0 };//背景矩阵
int g_arrRandomSquare[COMB_ROW][COMB_RANK] = { 0 };//随机块组合
int g_nIndex = 0;//随机块组合对应的序号
int G_ROW = 0;//实时记录3*3矩阵的行位置,即需要变形的矩阵位置
int G_RANK = 0;//实时记录3*3矩阵的列位置,即需要变形的矩阵位置
int gScore = 0;






  //*********************************************//
  //**************  函数声明 *********************//
  //*********************************************//
  //回调函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//消息响应函数
void OnCreate();//创建窗口时用作初始化随机数种子
void OnPaint(HDC hDC);//窗口变化时重绘函数
void OnReturn(HWND hWnd);//按键处理--回车键
void OnTimer(HWND hWnd);//定时器响应函数
void OnDown(HWND hWnd);//向下加速
void OnLeft(HWND hWnd);//左移响应函数
void OnRight(HWND hWnd);//右移响应函数
void OnUp(HWND hWnd);//上键变形




//在背景矩形上画方块
void PaintSquare(HDC mDC);//画值为1的方块
void PaintSquare2(HDC mDC);//画值为2的方块


  //产生随机块组合并显示
int CreateRandomSquare();//产生随机块组合
void CopySquareToBack();//随机块贴到背景中g_arrRandomSquare->g_arrBackGround


//方块操作
void SquareDown();//方块下落
void SquareLeft();//方块左移
void SquareRight();//方块右移
void SquareChange();//方块变形
void SquareChangeLong();//长条变形


int TestSquareDown();//判断方块是否可以下落  如果到底不能下落
int TestSquareDown2();//判断方块是否可以下落  如果下方有方块不能下落
int TestSquareLeft();//判断方块能否左移,如果到达左边边界,不能左移
int TestSquareLeft2();//判断方块能否左移,如果左边有方块,不能左移
int TestSquareRight();//判断方块能否右移,如果到达右边边界,不能右移
int TestSquareRight2();//判断方块能否右移,如果右边有方块,不能右移
int TestSquareChange();//判断方块能否变形
int TestSquareChangeLong();//判断长条能否变形


void Change1To2();//标识已经到底的方块,方块取值由1变为2
void DestroyLine();//消除行


  //显示分数
void ShowScore(HDC mDC);


//游戏结束
int GameOver();






 //*********************************************//
 //**************  主函数 *********************//
 //*********************************************//
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{


HWND hWnd;//窗口句柄
MSG mSg;//消息结构体
HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU3));


//创建窗口结构体
WNDCLASSEX wc;
wc.cbClsExtra = 0;//暂时不用
wc.cbSize = sizeof(wc);//结构体大小
wc.cbWndExtra = 0;//暂时不用
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;//背景颜色
wc.hCursor = NULL;//光标
wc.hIcon = NULL;//LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));状态栏图标
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);//(HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,0,0,LR_DEFAULTCOLOR);;//左上角图标
wc.hInstance = hInstance;//实例句柄
wc.lpfnWndProc = WndProc;//回调函数
wc.lpszClassName = "nanhang";//结构体名字
wc.lpszMenuName = "Mean";//菜单栏名字
wc.style = CS_HREDRAW | CS_VREDRAW;//窗口水平变化或是垂直变化时重绘窗口




  //注册窗口结构体
if (0 == RegisterClassEx(&wc))
{
int eNum = GetLastError();//获取注册窗口结构体失败的错误代码
return 0;//注册失败
}


//创建窗口
hWnd = CreateWindowEx(WS_EX_WINDOWEDGE, "nanhang",
"俄罗斯方块", WS_OVERLAPPEDWINDOW,
WND_POS_X, WND_POS_Y, WND_WIDTH, WND_HEIGHT,
NULL, hMenu, hInstance, NULL); 
if (NULL == hWnd)
{
int eNum = GetLastError();//获取创建窗口失败的错误代码
return 0;//创建窗口失败
}


//显示窗口
ShowWindow(hWnd, nCmdShow);//隐藏返回0  非隐藏返回非0


  //消息循环
while (GetMessage(&mSg, NULL, 0, 0))//Quit消息返回0  其他消息返回非0
{
//翻译消息
TranslateMessage(&mSg);


//分发消息 调用回调函数
DispatchMessage(&mSg);
}


return 0;
}




//*********************************************//
//**************  回调函数 *********************//
//*********************************************//
LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hDC;


switch (uID)
{
case WM_CREATE://窗口创建时只产生一次这个消息    适合进行初始化
OnCreate();
break;
case WM_PAINT://窗口变化时重绘
hDC = BeginPaint(hWnd, &ps);
OnPaint(hDC);
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN://按键消息处理
switch (wParam)
{
case VK_RETURN://回车键
OnReturn(hWnd);
break;
case VK_LEFT://左键
OnLeft(hWnd);
break;
case VK_RIGHT://右键
OnRight(hWnd);
break;
case VK_UP://上键
OnUp(hWnd);
break;
case VK_DOWN://下键
OnDown(hWnd);
break;
}
break;
case WM_TIMER://定时器时间到,执行相应操作
OnTimer(hWnd);
break;
case WM_DESTROY://关闭窗口时会依次产生WM_CLOSE WM_DESTROY消息
KillTimer(hWnd, N_TIMER);//关闭定时器
PostQuitMessage(0);//产生退出消息,GetMessage读取Quit消息的返回值为0
break;
}
return DefWindowProc(hWnd, uID, wParam, lParam);//让系统自动处理一些默认消息
}


//***********************************************//
//**************  消息处理函数 ******************//
//*********************************************//
// WM_CREATE响应函数
void OnCreate()
{
//产生随机数种子
srand((unsigned int)time(NULL));
//产生随机块组合
CreateRandomSquare();
//在背景矩形上显示随机块组合
CopySquareToBack();
}


//WM_PAINT响应函数
void OnPaint(HDC hDC)
{
//创建兼容性DC(内存DC)--纸的编号
HDC mDC = CreateCompatibleDC(hDC);


//创建兼容性位图--纸本身
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, WND_WIDTH, WND_HEIGHT);


//将DC与位图关联
SelectObject(mDC, hBitmap);


//画方块
PaintSquare(mDC);
PaintSquare2(mDC);


//从内存DC到窗口DC传递
BitBlt(hDC, 0, 0, WND_WIDTH, WND_HEIGHT, mDC, 0, 0, SRCCOPY);


//释放位图
DeleteObject(hBitmap);


//释放DC
DeleteDC(mDC);
}


//WM_TIMER响应函数
void OnTimer(HWND hWnd)
{
//获取DC
HDC hDC = GetDC(hWnd);

//判断能否下落
//方块已经到底,不能下落
//方块下方已经有方块,不能下落
if ((1 == TestSquareDown()) && (1 == TestSquareDown2()))
{
// 方块下落
SquareDown();
DestroyLine();
GameOver();
//3*3矩阵的位置更新
G_ROW++;
}
else
{
//已经到底的方块取值由1变为2
Change1To2();
//产生新的随机块组合
CreateRandomSquare();
//显示新的随机块组合
CopySquareToBack();
}


// 在背景矩形上画方块,取值为1或2显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}


//WM_KEYDOWN-->VK_DOWN响应函数
void OnDown(HWND hWnd)
{
OnTimer(hWnd);//按下键,马上调用定时响应函数,不等定时时间到
}




//WM_KEYDOWN-->VK_RETURN响应函数
void OnReturn(HWND hWnd)
{
//启动定时器
SetTimer(hWnd, N_TIMER, T_TIMER, NULL);
}


//WM_KEYDOWN-->VK_LEFT响应函数
void OnLeft(HWND hWnd)
{
if ((1 == TestSquareLeft()) && (1 == TestSquareLeft2()))
{
//获取DC
HDC hDC = GetDC(hWnd);
//方块左移
SquareLeft();
//3*3矩阵的位置更新
G_RANK--;
//显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}
}


//WM_KEYDOWN-->VK_RIGHT响应函数
void OnRight(HWND hWnd)
{
if ((1 == TestSquareRight()) && (1 == TestSquareRight2()))
{
//获取DC
HDC hDC = GetDC(hWnd);
//方块右移
SquareRight();
//3*3矩阵的位置更新
G_RANK++;
//显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}
}




void OnUp(HWND hWnd)
{


HDC hDC;//定义DC句柄


//方形方块组合,不做变形,因为变形等同于左移右移下落
if (5 == g_nIndex)
{
return;
}
else
{


//获取DC
hDC = GetDC(hWnd);
//方块变形
switch (g_nIndex)
{
case 0:
case 1:
case 2:
case 3:
case 4:
if (1 == TestSquareChange())
{
SquareChange();
}
break;
case 6:
if (1 == TestSquareChangeLong())
{
SquareChangeLong();
}
break;
default:break;
}
//显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}
}




//*********************************************//
//***************  方块操作 *******************//
//********************************************//
// 方块下落
void SquareDown()
{
int i = 0;
int j = 0;
for (i = G_ARR_ROW - 2; i >= 0; i--)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i + 1][j] = g_arrBackGround[i][j];//下一行替代上一行
g_arrBackGround[i][j] = 0;//上一行清零
}
}
}
}


//方块左移
void SquareLeft()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i][j - 1] = g_arrBackGround[i][j];
g_arrBackGround[i][j] = 0;
}
}
}
}


//方块右移
void SquareRight()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = G_ARR_RANK - 2; j >= 0; j--)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i][j + 1] = g_arrBackGround[i][j];
g_arrBackGround[i][j] = 0;
}
}
}
}


//矩形旋转
void SquareChange()
{
int i = 0;
int j = 0;
int temp = 0;
int arrSquareChange[CHANGE_SIZE][CHANGE_SIZE] = { 0 };//矩阵旋转过程中的中间矩阵,存储原先背景中的3*3矩阵


 //取出现有的3*3矩阵的图形
for (i = 0; i<CHANGE_SIZE; i++)
{
for (j = 0; j<CHANGE_SIZE; j++)
{
arrSquareChange[i][j] = g_arrBackGround[G_ROW + i][G_RANK + j];
}
}


//将旋转后的图形复制给背景中的3*3矩阵
for (i = 0; i<CHANGE_SIZE; i++)
{
temp = CHANGE_SIZE - 1;
for (j = 0; j<CHANGE_SIZE; j++)
{
g_arrBackGround[G_ROW + i][G_RANK + j] = arrSquareChange[temp--][i];
}
}


}




//长条变形
void SquareChangeLong()
{
//横条
if (1 == g_arrBackGround[G_ROW][G_RANK - 1])
{
g_arrBackGround[G_ROW][G_RANK - 1] = 0;
g_arrBackGround[G_ROW][G_RANK + 1] = 0;
g_arrBackGround[G_ROW][G_RANK + 2] = 0;
if (2 == g_arrBackGround[G_ROW + 1][G_RANK])
{
g_arrBackGround[G_ROW - 1][G_RANK] = 1;
g_arrBackGround[G_ROW - 2][G_RANK] = 1;
g_arrBackGround[G_ROW - 3][G_RANK] = 1;
}
else if (2 == g_arrBackGround[G_ROW + 2][G_RANK])
{
g_arrBackGround[G_ROW - 1][G_RANK] = 1;
g_arrBackGround[G_ROW - 2][G_RANK] = 1;
g_arrBackGround[G_ROW + 1][G_RANK] = 1;
}
else
{
g_arrBackGround[G_ROW - 1][G_RANK] = 1;
g_arrBackGround[G_ROW + 1][G_RANK] = 1;
g_arrBackGround[G_ROW + 2][G_RANK] = 1;
}
}
//竖条
else
{
g_arrBackGround[G_ROW - 1][G_RANK] = 0;
g_arrBackGround[G_ROW + 1][G_RANK] = 0;
g_arrBackGround[G_ROW + 2][G_RANK] = 0;


if ((2 == g_arrBackGround[G_ROW][G_RANK - 1]) || (0 == G_RANK))
{
g_arrBackGround[G_ROW][G_RANK + 1] = 1;
g_arrBackGround[G_ROW][G_RANK + 2] = 1;
g_arrBackGround[G_ROW][G_RANK + 3] = 1;
G_RANK = G_RANK + 1;


}
else if ((2 == g_arrBackGround[G_ROW][G_RANK + 1]) || (9 == G_RANK))
{
g_arrBackGround[G_ROW][G_RANK - 1] = 1;
g_arrBackGround[G_ROW][G_RANK - 2] = 1;
g_arrBackGround[G_ROW][G_RANK - 3] = 1;
G_RANK = G_RANK - 2;
}
else if ((2 == g_arrBackGround[G_ROW][G_RANK + 2]) || ((8 == G_RANK)))
{
g_arrBackGround[G_ROW][G_RANK + 1] = 1;
g_arrBackGround[G_ROW][G_RANK - 1] = 1;
g_arrBackGround[G_ROW][G_RANK - 2] = 1;
G_RANK = G_RANK - 1;
}
else
{
g_arrBackGround[G_ROW][G_RANK - 1] = 1;
g_arrBackGround[G_ROW][G_RANK + 1] = 1;
g_arrBackGround[G_ROW][G_RANK + 2] = 1;
}
}
}




//判断方块能否下落,已经到达下方边界不再下落
int TestSquareDown()
{
int j = 0;
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[G_ARR_ROW - 1][j])
{
return 0;
}
}


return 1;
}


//判断方块能否下落,下方有方块不能下落
int TestSquareDown2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW - 1; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
if (2 == g_arrBackGround[i + 1][j])
{
return 0;
}
}
}
}
return 1;
}


//判断方块能否左移,如果到达左边边界,不能左移
int TestSquareLeft()
{
int i = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
if (1 == g_arrBackGround[i][0])
{
return 0;
}
}
return 1;
}


//判断方块能否左移,如果左边有方块,不能左移
int TestSquareLeft2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
if (2 == g_arrBackGround[i][j - 1])
{
return 0;
}
}
}
}


return 1;
}


//判断方块能否右移,如果到达右边边界,不能右移
int TestSquareRight()
{
int i = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
if (1 == g_arrBackGround[i][G_ARR_RANK - 1])
{
return 0;
}
}
return 1;
}


//判断方块能否右移,如果右边有方块,不能右移
int TestSquareRight2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = G_ARR_RANK - 2; j >= 0; j--)
{
if (1 == g_arrBackGround[i][j])
{
if (2 == g_arrBackGround[i][j + 1])
{
return 0;
}
}
}
}


return 1;
}


//判断是否可以变形 3*3数组中有元素为2就不再变形
int TestSquareChange()
{
int i = 0;
int j = 0;
if (g_nIndex <4)
{
for(i=0;i<20;i++)
if (g_arrBackGround[i][0] == 1)
return 0;
}
for (i = 0; i<CHANGE_SIZE; i++)
{
for (j = 0; j<CHANGE_SIZE; j++)
{
if (2 == g_arrBackGround[G_ROW + i][G_RANK + j])
{
return 0;
}
}
}


//此时3*3矩阵的左上角的起始点已经在背景矩阵的外边
if (G_ROW < 0)
{
G_ROW = 0;
}
//此时3*3矩阵的右边已经在背景矩阵的外边
else if (G_RANK + CHANGE_SIZE - 1>G_ARR_RANK - 1)
{
G_RANK = (G_ARR_RANK - 1) - (CHANGE_SIZE - 1);
}


return 1;
}




//判断长条是否可以变形
int TestSquareChangeLong()
{
int i = 0;
int j = 0;
for (i = 1; i<4; i++)
{
if ((2 == g_arrBackGround[G_ROW][G_RANK + i]) || (G_RANK + i>9))
{
break;
}
}


for (j = 1; j<4; j++)
{
if ((2 == g_arrBackGround[G_ROW][G_RANK - j]) || (G_RANK - j<0))
{
break;
}
}


if (i - 1 + j - 1<3)
{
return 0;
}




return 1;
}




//标识已经到底的方块,取值由1变为2
void Change1To2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i][j] = 2;
}
}
}
}




//*********************************************//
//******  在背景矩形上画方块函数 **************//
//*********************************************//
// 背景数组g_arrBackGround元素取值为1画方块,为0则不画方块
void PaintSquare(HDC mDC)
{
int i = 0;
int j = 0;
HBRUSH holdBrush;
HBRUSH hnewBrush;
ShowScore(mDC);
//画矩形框
Rectangle(mDC, RECT_UPPER_X, RECT_UPPER_Y, RECT_LOWER_X, RECT_LOWER_Y);


//创建画刷
hnewBrush = CreateSolidBrush(RGB(251,216 ,96));
//关联画刷
holdBrush = (HBRUSH)SelectObject(mDC, hnewBrush);




//遍历二维数组
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
Rectangle(mDC, j*SIDE_LEN, i*SIDE_LEN, j*SIDE_LEN + SIDE_LEN, i*SIDE_LEN + SIDE_LEN);
}
}
}


//返回旧的画刷
hnewBrush = (HBRUSH)SelectObject(mDC, holdBrush);
//释放新的画刷
DeleteObject(hnewBrush);
}


// 背景数组g_arrBackGround元素取值为2画方块,为0则不画方块
// 没有和PaintSquare合并,便于绘制不同画刷颜色
void PaintSquare2(HDC mDC)
{
int i = 0;
int j = 0;


HBRUSH holdBrush;
HBRUSH hnewBrush;


//创建画刷
hnewBrush = CreateSolidBrush(RGB(250, 128, 10));
//关联画刷
holdBrush = (HBRUSH)SelectObject(mDC, hnewBrush);


//遍历二维数组
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (2 == g_arrBackGround[i][j])
{
Rectangle(mDC, j*SIDE_LEN, i*SIDE_LEN, j*SIDE_LEN + SIDE_LEN, i*SIDE_LEN + SIDE_LEN);
}
}
}


//返回旧的画刷
hnewBrush = (HBRUSH)SelectObject(mDC, holdBrush);
//释放新的画刷
     DeleteObject(hnewBrush);


}


//*********************************************//
//******  产生随机块组合并显示 ***************//
//********************************************//
//产生随机块的组合之一
int CreateRandomSquare()
{
int nIndex = rand() % 7;//7种组合
g_nIndex = nIndex;


switch (nIndex)
{
case 0:
g_arrRandomSquare[0][0] = 1; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 0; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 0; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 1:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 0; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 2:
g_arrRandomSquare[0][0] = 1; g_arrRandomSquare[0][1] = 0; g_arrRandomSquare[0][2] = 0; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 3:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 0; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 4:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 0; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 5:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 0; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 6:
g_arrRandomSquare[0][0] = 1; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 1;
g_arrRandomSquare[1][0] = 0; g_arrRandomSquare[1][1] = 0; g_arrRandomSquare[1][2] = 0; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 4;
break;
default:break;
}


return nIndex;
}


//在背景矩形上显示随机块
void CopySquareToBack()
{
int i = 0;
int j = 0;
for (i = 0; i<COMB_ROW; i++)
{
for (j = 0; j<COMB_RANK; j++)
{
g_arrBackGround[i][j + 3] = g_arrRandomSquare[i][j];//起始出现位置在中间 数字3可以根据图的大小调整
}
}


}
//*********************************************//
//*************  游戏计分并显示 ***************//
//********************************************//
//消除行
void DestroyLine()
{
int i, j;
int sum = 0;
int temp;
for (i = 20 - 1; i >= 0; i--)
{
for (j = 0; j < 10; j++)
{
sum += g_arrBackGround[i][j];
}
if (20 == sum)
{
for (temp = i; temp >0; temp--)
{
for (j = 0; j < 10; j++)
{
g_arrBackGround[temp][j] = g_arrBackGround[temp-1][j];


}
}

i = 20;
gScore+=20;
if (g_nIndex == 6)
{
G_ROW++;
}

}
sum = 0;
}


}




//显示分数
void ShowScore(HDC mDC)
{
char strScore[10] = { 0 };
//Rectangle(mDC, 0, 0, 500, 640);
Rectangle(mDC, 300, 0, 300, 600);
_itoa_s(gScore, strScore, 10);//转化为十进制
TextOut(mDC,300+60,100,"分数",strlen("分数"));
TextOut(mDC, 300 + 60, 140, strScore, strlen(strScore));


}




//*********************************************//
//*************** 游戏结束 *******************//
//********************************************//
int GameOver()
{
int i = 0;
for (i = 0; i < 10; i++)
{
if (2 == g_arrBackGround[1][i])
{
MessageBox(NULL,"GameOver","提示",MB_YESNO);
return 0;
}
}


return 1;
}





//*********************************************//
//**************  头文件  *********************//
//*********************************************//
#include <windows.h>
#include <time.h>
#include "stdafx.h"




//*********************************************//
//**************  宏定义  *********************//
//*********************************************//
#define WND_POS_X 10 //窗口左上角点的横坐标
#define WND_POS_Y 10 //窗口左上角点的纵坐标
#define WND_WIDTH 500 //窗口的宽度
#define WND_HEIGHT 600 //窗口的高度
#define RECT_UPPER_X 0 //背景矩形框的左上角点的横坐标
#define RECT_UPPER_Y 0 //背景矩形框的左上角点的纵坐标
#define RECT_LOWER_X 300 //背景矩形框的右下角点的横坐标
#define RECT_LOWER_Y 620 //背景矩形框的右下角点的纵坐标
#define SIDE_LEN 30 //游戏小方块的边长
#define G_ARR_ROW (RECT_LOWER_Y/SIDE_LEN) // 背景矩形框的行数 600/30=20行
#define G_ARR_RANK (RECT_LOWER_X/SIDE_LEN)// 背景矩形框的列数 300/30=10列
#define COMB_ROW 2 //随机方块的组合使用2行4列矩阵存储
#define COMB_RANK 4
#define CHANGE_SIZE 3 //3*3矩阵作为旋转矩阵
#define N_TIMER 1 //定时器的ID
#define T_TIMER 500 //定时器的时间,单位为毫秒
#define IDR_MENU1                       130
#define IDR_MENU3                       133
#define IDI_ICON2                       134
#define N_TIMER                          1


//*********************************************//
//**************  全局变量  *********************//
//*********************************************//
int g_arrBackGround[G_ARR_ROW][G_ARR_RANK] = { 0 };//背景矩阵
int g_arrRandomSquare[COMB_ROW][COMB_RANK] = { 0 };//随机块组合
int g_nIndex = 0;//随机块组合对应的序号
int G_ROW = 0;//实时记录3*3矩阵的行位置,即需要变形的矩阵位置
int G_RANK = 0;//实时记录3*3矩阵的列位置,即需要变形的矩阵位置
int gScore = 0;






  //*********************************************//
  //**************  函数声明 *********************//
  //*********************************************//
  //回调函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//消息响应函数
void OnCreate();//创建窗口时用作初始化随机数种子
void OnPaint(HDC hDC);//窗口变化时重绘函数
void OnReturn(HWND hWnd);//按键处理--回车键
void OnTimer(HWND hWnd);//定时器响应函数
void OnDown(HWND hWnd);//向下加速
void OnLeft(HWND hWnd);//左移响应函数
void OnRight(HWND hWnd);//右移响应函数
void OnUp(HWND hWnd);//上键变形




//在背景矩形上画方块
void PaintSquare(HDC mDC);//画值为1的方块
void PaintSquare2(HDC mDC);//画值为2的方块


  //产生随机块组合并显示
int CreateRandomSquare();//产生随机块组合
void CopySquareToBack();//随机块贴到背景中g_arrRandomSquare->g_arrBackGround


//方块操作
void SquareDown();//方块下落
void SquareLeft();//方块左移
void SquareRight();//方块右移
void SquareChange();//方块变形
void SquareChangeLong();//长条变形


int TestSquareDown();//判断方块是否可以下落  如果到底不能下落
int TestSquareDown2();//判断方块是否可以下落  如果下方有方块不能下落
int TestSquareLeft();//判断方块能否左移,如果到达左边边界,不能左移
int TestSquareLeft2();//判断方块能否左移,如果左边有方块,不能左移
int TestSquareRight();//判断方块能否右移,如果到达右边边界,不能右移
int TestSquareRight2();//判断方块能否右移,如果右边有方块,不能右移
int TestSquareChange();//判断方块能否变形
int TestSquareChangeLong();//判断长条能否变形


void Change1To2();//标识已经到底的方块,方块取值由1变为2
void DestroyLine();//消除行


  //显示分数
void ShowScore(HDC mDC);


//游戏结束
int GameOver();






 //*********************************************//
 //**************  主函数 *********************//
 //*********************************************//
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{


HWND hWnd;//窗口句柄
MSG mSg;//消息结构体
HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU3));


//创建窗口结构体
WNDCLASSEX wc;
wc.cbClsExtra = 0;//暂时不用
wc.cbSize = sizeof(wc);//结构体大小
wc.cbWndExtra = 0;//暂时不用
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;//背景颜色
wc.hCursor = NULL;//光标
wc.hIcon = NULL;//LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));状态栏图标
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);//(HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,0,0,LR_DEFAULTCOLOR);;//左上角图标
wc.hInstance = hInstance;//实例句柄
wc.lpfnWndProc = WndProc;//回调函数
wc.lpszClassName = "nanhang";//结构体名字
wc.lpszMenuName = "Mean";//菜单栏名字
wc.style = CS_HREDRAW | CS_VREDRAW;//窗口水平变化或是垂直变化时重绘窗口




  //注册窗口结构体
if (0 == RegisterClassEx(&wc))
{
int eNum = GetLastError();//获取注册窗口结构体失败的错误代码
return 0;//注册失败
}


//创建窗口
hWnd = CreateWindowEx(WS_EX_WINDOWEDGE, "nanhang",
"俄罗斯方块", WS_OVERLAPPEDWINDOW,
WND_POS_X, WND_POS_Y, WND_WIDTH, WND_HEIGHT,
NULL, hMenu, hInstance, NULL); 
if (NULL == hWnd)
{
int eNum = GetLastError();//获取创建窗口失败的错误代码
return 0;//创建窗口失败
}


//显示窗口
ShowWindow(hWnd, nCmdShow);//隐藏返回0  非隐藏返回非0


  //消息循环
while (GetMessage(&mSg, NULL, 0, 0))//Quit消息返回0  其他消息返回非0
{
//翻译消息
TranslateMessage(&mSg);


//分发消息 调用回调函数
DispatchMessage(&mSg);
}


return 0;
}




//*********************************************//
//**************  回调函数 *********************//
//*********************************************//
LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hDC;


switch (uID)
{
case WM_CREATE://窗口创建时只产生一次这个消息    适合进行初始化
OnCreate();
break;
case WM_PAINT://窗口变化时重绘
hDC = BeginPaint(hWnd, &ps);
OnPaint(hDC);
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN://按键消息处理
switch (wParam)
{
case VK_RETURN://回车键
OnReturn(hWnd);
break;
case VK_LEFT://左键
OnLeft(hWnd);
break;
case VK_RIGHT://右键
OnRight(hWnd);
break;
case VK_UP://上键
OnUp(hWnd);
break;
case VK_DOWN://下键
OnDown(hWnd);
break;
}
break;
case WM_TIMER://定时器时间到,执行相应操作
OnTimer(hWnd);
break;
case WM_DESTROY://关闭窗口时会依次产生WM_CLOSE WM_DESTROY消息
KillTimer(hWnd, N_TIMER);//关闭定时器
PostQuitMessage(0);//产生退出消息,GetMessage读取Quit消息的返回值为0
break;
}
return DefWindowProc(hWnd, uID, wParam, lParam);//让系统自动处理一些默认消息
}


//***********************************************//
//**************  消息处理函数 ******************//
//*********************************************//
// WM_CREATE响应函数
void OnCreate()
{
//产生随机数种子
srand((unsigned int)time(NULL));
//产生随机块组合
CreateRandomSquare();
//在背景矩形上显示随机块组合
CopySquareToBack();
}


//WM_PAINT响应函数
void OnPaint(HDC hDC)
{
//创建兼容性DC(内存DC)--纸的编号
HDC mDC = CreateCompatibleDC(hDC);


//创建兼容性位图--纸本身
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, WND_WIDTH, WND_HEIGHT);


//将DC与位图关联
SelectObject(mDC, hBitmap);


//画方块
PaintSquare(mDC);
PaintSquare2(mDC);


//从内存DC到窗口DC传递
BitBlt(hDC, 0, 0, WND_WIDTH, WND_HEIGHT, mDC, 0, 0, SRCCOPY);


//释放位图
DeleteObject(hBitmap);


//释放DC
DeleteDC(mDC);
}


//WM_TIMER响应函数
void OnTimer(HWND hWnd)
{
//获取DC
HDC hDC = GetDC(hWnd);

//判断能否下落
//方块已经到底,不能下落
//方块下方已经有方块,不能下落
if ((1 == TestSquareDown()) && (1 == TestSquareDown2()))
{
// 方块下落
SquareDown();
DestroyLine();
GameOver();
//3*3矩阵的位置更新
G_ROW++;
}
else
{
//已经到底的方块取值由1变为2
Change1To2();
//产生新的随机块组合
CreateRandomSquare();
//显示新的随机块组合
CopySquareToBack();
}


// 在背景矩形上画方块,取值为1或2显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}


//WM_KEYDOWN-->VK_DOWN响应函数
void OnDown(HWND hWnd)
{
OnTimer(hWnd);//按下键,马上调用定时响应函数,不等定时时间到
}




//WM_KEYDOWN-->VK_RETURN响应函数
void OnReturn(HWND hWnd)
{
//启动定时器
SetTimer(hWnd, N_TIMER, T_TIMER, NULL);
}


//WM_KEYDOWN-->VK_LEFT响应函数
void OnLeft(HWND hWnd)
{
if ((1 == TestSquareLeft()) && (1 == TestSquareLeft2()))
{
//获取DC
HDC hDC = GetDC(hWnd);
//方块左移
SquareLeft();
//3*3矩阵的位置更新
G_RANK--;
//显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}
}


//WM_KEYDOWN-->VK_RIGHT响应函数
void OnRight(HWND hWnd)
{
if ((1 == TestSquareRight()) && (1 == TestSquareRight2()))
{
//获取DC
HDC hDC = GetDC(hWnd);
//方块右移
SquareRight();
//3*3矩阵的位置更新
G_RANK++;
//显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}
}




void OnUp(HWND hWnd)
{


HDC hDC;//定义DC句柄


//方形方块组合,不做变形,因为变形等同于左移右移下落
if (5 == g_nIndex)
{
return;
}
else
{


//获取DC
hDC = GetDC(hWnd);
//方块变形
switch (g_nIndex)
{
case 0:
case 1:
case 2:
case 3:
case 4:
if (1 == TestSquareChange())
{
SquareChange();
}
break;
case 6:
if (1 == TestSquareChangeLong())
{
SquareChangeLong();
}
break;
default:break;
}
//显示方块
OnPaint(hDC);
//释放DC
ReleaseDC(hWnd, hDC);
}
}




//*********************************************//
//***************  方块操作 *******************//
//********************************************//
// 方块下落
void SquareDown()
{
int i = 0;
int j = 0;
for (i = G_ARR_ROW - 2; i >= 0; i--)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i + 1][j] = g_arrBackGround[i][j];//下一行替代上一行
g_arrBackGround[i][j] = 0;//上一行清零
}
}
}
}


//方块左移
void SquareLeft()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i][j - 1] = g_arrBackGround[i][j];
g_arrBackGround[i][j] = 0;
}
}
}
}


//方块右移
void SquareRight()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = G_ARR_RANK - 2; j >= 0; j--)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i][j + 1] = g_arrBackGround[i][j];
g_arrBackGround[i][j] = 0;
}
}
}
}


//矩形旋转
void SquareChange()
{
int i = 0;
int j = 0;
int temp = 0;
int arrSquareChange[CHANGE_SIZE][CHANGE_SIZE] = { 0 };//矩阵旋转过程中的中间矩阵,存储原先背景中的3*3矩阵


 //取出现有的3*3矩阵的图形
for (i = 0; i<CHANGE_SIZE; i++)
{
for (j = 0; j<CHANGE_SIZE; j++)
{
arrSquareChange[i][j] = g_arrBackGround[G_ROW + i][G_RANK + j];
}
}


//将旋转后的图形复制给背景中的3*3矩阵
for (i = 0; i<CHANGE_SIZE; i++)
{
temp = CHANGE_SIZE - 1;
for (j = 0; j<CHANGE_SIZE; j++)
{
g_arrBackGround[G_ROW + i][G_RANK + j] = arrSquareChange[temp--][i];
}
}


}




//长条变形
void SquareChangeLong()
{
//横条
if (1 == g_arrBackGround[G_ROW][G_RANK - 1])
{
g_arrBackGround[G_ROW][G_RANK - 1] = 0;
g_arrBackGround[G_ROW][G_RANK + 1] = 0;
g_arrBackGround[G_ROW][G_RANK + 2] = 0;
if (2 == g_arrBackGround[G_ROW + 1][G_RANK])
{
g_arrBackGround[G_ROW - 1][G_RANK] = 1;
g_arrBackGround[G_ROW - 2][G_RANK] = 1;
g_arrBackGround[G_ROW - 3][G_RANK] = 1;
}
else if (2 == g_arrBackGround[G_ROW + 2][G_RANK])
{
g_arrBackGround[G_ROW - 1][G_RANK] = 1;
g_arrBackGround[G_ROW - 2][G_RANK] = 1;
g_arrBackGround[G_ROW + 1][G_RANK] = 1;
}
else
{
g_arrBackGround[G_ROW - 1][G_RANK] = 1;
g_arrBackGround[G_ROW + 1][G_RANK] = 1;
g_arrBackGround[G_ROW + 2][G_RANK] = 1;
}
}
//竖条
else
{
g_arrBackGround[G_ROW - 1][G_RANK] = 0;
g_arrBackGround[G_ROW + 1][G_RANK] = 0;
g_arrBackGround[G_ROW + 2][G_RANK] = 0;


if ((2 == g_arrBackGround[G_ROW][G_RANK - 1]) || (0 == G_RANK))
{
g_arrBackGround[G_ROW][G_RANK + 1] = 1;
g_arrBackGround[G_ROW][G_RANK + 2] = 1;
g_arrBackGround[G_ROW][G_RANK + 3] = 1;
G_RANK = G_RANK + 1;


}
else if ((2 == g_arrBackGround[G_ROW][G_RANK + 1]) || (9 == G_RANK))
{
g_arrBackGround[G_ROW][G_RANK - 1] = 1;
g_arrBackGround[G_ROW][G_RANK - 2] = 1;
g_arrBackGround[G_ROW][G_RANK - 3] = 1;
G_RANK = G_RANK - 2;
}
else if ((2 == g_arrBackGround[G_ROW][G_RANK + 2]) || ((8 == G_RANK)))
{
g_arrBackGround[G_ROW][G_RANK + 1] = 1;
g_arrBackGround[G_ROW][G_RANK - 1] = 1;
g_arrBackGround[G_ROW][G_RANK - 2] = 1;
G_RANK = G_RANK - 1;
}
else
{
g_arrBackGround[G_ROW][G_RANK - 1] = 1;
g_arrBackGround[G_ROW][G_RANK + 1] = 1;
g_arrBackGround[G_ROW][G_RANK + 2] = 1;
}
}
}




//判断方块能否下落,已经到达下方边界不再下落
int TestSquareDown()
{
int j = 0;
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[G_ARR_ROW - 1][j])
{
return 0;
}
}


return 1;
}


//判断方块能否下落,下方有方块不能下落
int TestSquareDown2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW - 1; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
if (2 == g_arrBackGround[i + 1][j])
{
return 0;
}
}
}
}
return 1;
}


//判断方块能否左移,如果到达左边边界,不能左移
int TestSquareLeft()
{
int i = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
if (1 == g_arrBackGround[i][0])
{
return 0;
}
}
return 1;
}


//判断方块能否左移,如果左边有方块,不能左移
int TestSquareLeft2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
if (2 == g_arrBackGround[i][j - 1])
{
return 0;
}
}
}
}


return 1;
}


//判断方块能否右移,如果到达右边边界,不能右移
int TestSquareRight()
{
int i = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
if (1 == g_arrBackGround[i][G_ARR_RANK - 1])
{
return 0;
}
}
return 1;
}


//判断方块能否右移,如果右边有方块,不能右移
int TestSquareRight2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = G_ARR_RANK - 2; j >= 0; j--)
{
if (1 == g_arrBackGround[i][j])
{
if (2 == g_arrBackGround[i][j + 1])
{
return 0;
}
}
}
}


return 1;
}


//判断是否可以变形 3*3数组中有元素为2就不再变形
int TestSquareChange()
{
int i = 0;
int j = 0;
if (g_nIndex <4)
{
for(i=0;i<20;i++)
if (g_arrBackGround[i][0] == 1)
return 0;
}
for (i = 0; i<CHANGE_SIZE; i++)
{
for (j = 0; j<CHANGE_SIZE; j++)
{
if (2 == g_arrBackGround[G_ROW + i][G_RANK + j])
{
return 0;
}
}
}


//此时3*3矩阵的左上角的起始点已经在背景矩阵的外边
if (G_ROW < 0)
{
G_ROW = 0;
}
//此时3*3矩阵的右边已经在背景矩阵的外边
else if (G_RANK + CHANGE_SIZE - 1>G_ARR_RANK - 1)
{
G_RANK = (G_ARR_RANK - 1) - (CHANGE_SIZE - 1);
}


return 1;
}




//判断长条是否可以变形
int TestSquareChangeLong()
{
int i = 0;
int j = 0;
for (i = 1; i<4; i++)
{
if ((2 == g_arrBackGround[G_ROW][G_RANK + i]) || (G_RANK + i>9))
{
break;
}
}


for (j = 1; j<4; j++)
{
if ((2 == g_arrBackGround[G_ROW][G_RANK - j]) || (G_RANK - j<0))
{
break;
}
}


if (i - 1 + j - 1<3)
{
return 0;
}




return 1;
}




//标识已经到底的方块,取值由1变为2
void Change1To2()
{
int i = 0;
int j = 0;
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
g_arrBackGround[i][j] = 2;
}
}
}
}




//*********************************************//
//******  在背景矩形上画方块函数 **************//
//*********************************************//
// 背景数组g_arrBackGround元素取值为1画方块,为0则不画方块
void PaintSquare(HDC mDC)
{
int i = 0;
int j = 0;
HBRUSH holdBrush;
HBRUSH hnewBrush;
ShowScore(mDC);
//画矩形框
Rectangle(mDC, RECT_UPPER_X, RECT_UPPER_Y, RECT_LOWER_X, RECT_LOWER_Y);


//创建画刷
hnewBrush = CreateSolidBrush(RGB(251,216 ,96));
//关联画刷
holdBrush = (HBRUSH)SelectObject(mDC, hnewBrush);




//遍历二维数组
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (1 == g_arrBackGround[i][j])
{
Rectangle(mDC, j*SIDE_LEN, i*SIDE_LEN, j*SIDE_LEN + SIDE_LEN, i*SIDE_LEN + SIDE_LEN);
}
}
}


//返回旧的画刷
hnewBrush = (HBRUSH)SelectObject(mDC, holdBrush);
//释放新的画刷
DeleteObject(hnewBrush);
}


// 背景数组g_arrBackGround元素取值为2画方块,为0则不画方块
// 没有和PaintSquare合并,便于绘制不同画刷颜色
void PaintSquare2(HDC mDC)
{
int i = 0;
int j = 0;


HBRUSH holdBrush;
HBRUSH hnewBrush;


//创建画刷
hnewBrush = CreateSolidBrush(RGB(250, 128, 10));
//关联画刷
holdBrush = (HBRUSH)SelectObject(mDC, hnewBrush);


//遍历二维数组
for (i = 0; i<G_ARR_ROW; i++)
{
for (j = 0; j<G_ARR_RANK; j++)
{
if (2 == g_arrBackGround[i][j])
{
Rectangle(mDC, j*SIDE_LEN, i*SIDE_LEN, j*SIDE_LEN + SIDE_LEN, i*SIDE_LEN + SIDE_LEN);
}
}
}


//返回旧的画刷
hnewBrush = (HBRUSH)SelectObject(mDC, holdBrush);
//释放新的画刷
     DeleteObject(hnewBrush);


}


//*********************************************//
//******  产生随机块组合并显示 ***************//
//********************************************//
//产生随机块的组合之一
int CreateRandomSquare()
{
int nIndex = rand() % 7;//7种组合
g_nIndex = nIndex;


switch (nIndex)
{
case 0:
g_arrRandomSquare[0][0] = 1; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 0; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 0; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 1:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 0; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 2:
g_arrRandomSquare[0][0] = 1; g_arrRandomSquare[0][1] = 0; g_arrRandomSquare[0][2] = 0; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 3:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 0; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 4:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 0; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 1; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 5:
g_arrRandomSquare[0][0] = 0; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 0;
g_arrRandomSquare[1][0] = 0; g_arrRandomSquare[1][1] = 1; g_arrRandomSquare[1][2] = 1; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 3;
break;
case 6:
g_arrRandomSquare[0][0] = 1; g_arrRandomSquare[0][1] = 1; g_arrRandomSquare[0][2] = 1; g_arrRandomSquare[0][3] = 1;
g_arrRandomSquare[1][0] = 0; g_arrRandomSquare[1][1] = 0; g_arrRandomSquare[1][2] = 0; g_arrRandomSquare[1][3] = 0;
G_ROW = 0;
G_RANK = 4;
break;
default:break;
}


return nIndex;
}


//在背景矩形上显示随机块
void CopySquareToBack()
{
int i = 0;
int j = 0;
for (i = 0; i<COMB_ROW; i++)
{
for (j = 0; j<COMB_RANK; j++)
{
g_arrBackGround[i][j + 3] = g_arrRandomSquare[i][j];//起始出现位置在中间 数字3可以根据图的大小调整
}
}


}
//*********************************************//
//*************  游戏计分并显示 ***************//
//********************************************//
//消除行
void DestroyLine()
{
int i, j;
int sum = 0;
int temp;
for (i = 20 - 1; i >= 0; i--)
{
for (j = 0; j < 10; j++)
{
sum += g_arrBackGround[i][j];
}
if (20 == sum)
{
for (temp = i; temp >0; temp--)
{
for (j = 0; j < 10; j++)
{
g_arrBackGround[temp][j] = g_arrBackGround[temp-1][j];


}
}

i = 20;
gScore+=20;
if (g_nIndex == 6)
{
G_ROW++;
}

}
sum = 0;
}


}




//显示分数
void ShowScore(HDC mDC)
{
char strScore[10] = { 0 };
//Rectangle(mDC, 0, 0, 500, 640);
Rectangle(mDC, 300, 0, 300, 600);
_itoa_s(gScore, strScore, 10);//转化为十进制
TextOut(mDC,300+60,100,"分数",strlen("分数"));
TextOut(mDC, 300 + 60, 140, strScore, strlen(strScore));


}




//*********************************************//
//*************** 游戏结束 *******************//
//********************************************//
int GameOver()
{
int i = 0;
for (i = 0; i < 10; i++)
{
if (2 == g_arrBackGround[1][i])
{
MessageBox(NULL,"GameOver","提示",MB_YESNO);
return 0;
}
}


return 1;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wym_king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值