c语言写俄罗斯方块-简单易懂

来源:互联网 发布:社区门诊软件 编辑:程序博客网 时间:2024/06/06 08:24
主要是记录自己最近学习的东西,本文的代码是这个老师写的,部分是我自己的标注,原代码视频地址在这里

http://study.163.com/course/courseMain.htm?courseId=1002988037,有兴趣同学可以去学习,希望对和我一样的初学者有所帮助。



#include <windows.h>#include <time.h>#define DEF_TIMERID   1000#define DEF_TIMENUM   500LRESULT CALLBACK pp(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);//创建随机块int CreateRandomSqare();//方块下落int SqareDwon();//方块是否还能下落,到底int CanSqareDown1();//方块是否还能下落,落在其他块儿上int CanSqareDown2();//方块左移int SqareMoveLeft();//方块能否左移int CanSqareLeft1();//方块还能左移吗?int CanSqareLeft2();//方块能右移吗?int SqareMoveRight();//方块能右移吗?int CanSqareRight1();//方块能右移吗?int CanSqareRight2();//变形int ChangeShape();//把1变成2int Change1To2();//方块的初始位置int InitSqareLocate();//显示随机块int ShowRandomSqare(HDC hdc);//显示固定的块int ShowSqareElement2(HDC hdc);//背景int arrBackground[20][10] = {0};//随机块int arrSqare[2][4] = {0};//落块实时位置int g_nLineLocation = 0;int g_nListLocation = 0;//int aaa[2]//m_n//o_//去除一行//把2变0int Change2To0();//当前行以上向下挪一个。int MoveCurrentToNext(int nLineTemp);//game overint GameOver();//显示分数int ShowScore(HDC hdc);int g_Score = 0;int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdline, int nShowCmd){//初始化窗口类WNDCLASSEX wc;HWND hWnd;MSG msg;DWORD dwRes;wc.cbClsExtra = 0;wc.cbSize = sizeof(wc);wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)COLOR_WINDOW;wc.hCursor = NULL;wc.hIcon = NULL;wc.hIconSm = NULL;wc.hInstance = hInstance;wc.lpfnWndProc = pp;wc.lpszClassName = "hehe";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW | CS_VREDRAW;//注册窗口类RegisterClassEx(&wc);dwRes = GetLastError();//创建窗口hWnd = CreateWindow("hehe", "俄罗斯方块", WS_OVERLAPPEDWINDOW, 100, 50, 500, 600+45, NULL, NULL, hInstance, NULL);if (NULL == hWnd){//输出错提示。}//显示窗口ShowWindow(hWnd, nShowCmd);//消息循环while(GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return 0;}LRESULT CALLBACK pp(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){PAINTSTRUCT ps;HDC hdc;switch (uMsg){case WM_CREATE://消息处理CreateRandomSqare();    InitSqareLocate();return 0;case WM_TIMER:hdc = GetDC(hWnd);if ((1 == CanSqareDown1()) && (1 == CanSqareDown2())){SqareDwon();g_nLineLocation++;}else{//变2Change1To2();//去除满行;Change2To0();if (0 == GameOver()){return 0;}//产生下一个随机块CreateRandomSqare();InitSqareLocate();}ShowScore(hdc);Rectangle(hdc, 0, 0, 300, 600);ShowRandomSqare(hdc);ShowSqareElement2(hdc);ReleaseDC(hWnd, hdc);return 0;case WM_KEYDOWN:switch (wParam){case VK_RETURN:SetTimer(hWnd, DEF_TIMERID, DEF_TIMENUM, NULL);return 0;case VK_LEFT:if ((1 == CanSqareLeft1()) && (1 == CanSqareLeft2())){hdc = GetDC(hWnd);g_nListLocation--;SqareMoveLeft();Rectangle(hdc, 0, 0, 300, 600);ShowRandomSqare(hdc);ShowSqareElement2(hdc);}return 0;case VK_RIGHT:if ((1 == CanSqareRight1()) && (1 == CanSqareRight2())){hdc = GetDC(hWnd);SqareMoveRight();g_nListLocation++;Rectangle(hdc, 0, 0, 300, 600);ShowRandomSqare(hdc);ShowSqareElement2(hdc);}return 0;case VK_DOWN:if ((1 == CanSqareDown1()) && (1 == CanSqareDown2())){hdc = GetDC(hWnd);SqareDwon();g_nLineLocation++;Rectangle(hdc, 0, 0, 300, 600);ShowRandomSqare(hdc);ShowSqareElement2(hdc);}return 0;case VK_UP:if ((1 == CanSqareRight2()) && (1 == CanSqareDown2()) && (1 == CanSqareLeft2())){hdc = GetDC(hWnd);ChangeShape();Rectangle(hdc, 0, 0, 300, 600);ShowRandomSqare(hdc);ShowSqareElement2(hdc);}return 0;default:return 0;}return 0;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);//画Rectangle(hdc, 0, 0, 300, 600);ShowScore(hdc);ShowRandomSqare(hdc);ShowSqareElement2(hdc);EndPaint(hWnd, &ps);return 0;case WM_DESTROY:KillTimer(hWnd, DEF_TIMERID);PostQuitMessage(0);return 0;}return DefWindowProc(hWnd, uMsg, wParam, lParam);}//显示分数int ShowScore(HDC hdc){char strBuf[10];int nLength = 0;itoa(g_Score, strBuf, 10);nLength = strlen(strBuf);TextOut (hdc, 410, 60, strBuf, nLength) ;return 0;}//game overint GameOver(){int nList = 0;for (nList = 0; nList < 10; nList++){if (2 == arrBackground[1][nList]){MessageBox(NULL, "GameOver", "提示", MB_OK);return 0;}}return 1;}/*俄罗斯都玩过,某一行已经满了,那么就得消除这一行:1.消除一行;2.消除当前行的以上全部向下移动一行*///1.把2变0,就代表消除一行int Change2To0(){int nLine = 19;int nList = 0;int nListTemp = 0;int nCount = 0;for (nLine = 19; nLine >= 0; nLine--){for (nList = 0; nList < 10; nList++){if (2 == arrBackground[nLine][nList]){nCount+=2;  //nCount = nCount+2}}if (20 == nCount){for (nListTemp = 0; nListTemp < 10; nListTemp++){arrBackground[nLine][nListTemp] = 0;}//g_Score++;MoveCurrentToNext(nLine);nLine = 19;}nCount = 0;}return 1;}//2.消除当前满行之后,这一行上面所有的方块都得下移一行int MoveCurrentToNext(int nLineTemp){int nLine = 0;int nList = 0;for (nLine = nLineTemp; nLine >= 0; nLine--){for (nList = 0; nList < 10; nList++){arrBackground[nLine][nList] = arrBackground[nLine-1][nList];}}return 1;}/*按向上键,代表要把这个随机方块变一下形状,因为碰到一条线的形状的方块得把2*4数组改为4*4,原理比较简单:每按一下up键,数组转置一下*/int ChangeShape(){int nLine = 0;int nList = 0;int nTemp = 3;int arrTemp[4][4] = {0};//把块弄出来for (nLine = 0; nLine < 4; nLine++){for(nList = 0; nList < 4; nList++){arrTemp[nLine][nList] = arrBackground[g_nLineLocation + nLine][g_nListLocation + nList];}}//把块弄回去for (nLine = 0; nLine < 4; nLine++){for(nList = 0; nList < 4; nList++){arrBackground[g_nLineLocation + nLine][g_nListLocation + nList] = arrTemp[nTemp][nLine];nTemp--;}nTemp = 3;}return 1;}/*按右键,正在落下的随机方块向右移动条件:1.遇到右边边界不能再移动了;2.右边已经有其他方块了。前面两个条件都不满足,3.然后落下的方块才能向右移动。原理很简单,列数+1即可表示右移动   *///1.方块到了右边边界,能右移吗?int CanSqareRight1(){int nLine = 0;for (nLine = 0; nLine < 20; nLine++){if (1 == arrBackground[nLine][9]){return 0;}}return 1;}//2.正在下落得方块右边已经有其他方块了,还能右移吗?int CanSqareRight2(){int nList = 0;int nLine = 0;for (nLine = 19; nLine >= 0; nLine--){for (nList = 10; nList >= 0; nList--){if (1 == arrBackground[nLine][nList]){if (2 == arrBackground[nLine][nList+1]){return 0;}}}}return 1;}//3.前面都返回1,表示可以向右移动,方块右移int SqareMoveRight(){int nLine = 0,nList = 0;for (nLine = 0; nLine < 20; nLine++){for (nList = 9; nList >= 0; nList--){if (1 == arrBackground[nLine][nList]){arrBackground[nLine][nList+1] = arrBackground[nLine][nList];arrBackground[nLine][nList] = 0;}}}return 1;}/*按左键,正在落下的随机方块向左移动条件:1.遇到左边边界不能再移动了;2.左边已经有其他方块了。前面两个条件都不满足,3.然后落下的方块才能向左移动。原理很简单,列数-1即可表示左移动   *///1.方块到了右边边界,能左移吗?int CanSqareLeft1(){int nLine = 0;for (nLine = 0; nLine < 20; nLine++){if (1 == arrBackground[nLine][0]){return 0;}}return 1;}//2.正在下落得方块右边已经有其他方块了,还能左移吗?int CanSqareLeft2(){int nList = 0;int nLine = 0;for (nLine = 19; nLine >= 0; nLine--){for (nList = 0; nList < 10; nList++){if (1 == arrBackground[nLine][nList]){if (2 == arrBackground[nLine][nList-1]){return 0;}}}}return 1;}//3.前面都返回1,表示可以向右移动,方块右移int SqareMoveLeft(){int nLine = 0,nList = 0;for (nLine = 0; nLine < 20; nLine++){for (nList = 0; nList <10; nList++){if (1 == arrBackground[nLine][nList]){arrBackground[nLine][nList-1] = arrBackground[nLine][nList];arrBackground[nLine][nList] = 0;}}}return 1;}/*按enter键,随机方块开始下落,下落有条件:1.遇到底边边边界不能再移动了;2.下边已经有其他方块了。前面两个条件都不满足,3.然后落下的方块才能继续向下移动。原理很简单,行数+1   *///1.还没到最底行,还能下落?int CanSqareDown1(){int nList = 0;for (nList = 0; nList < 10; nList++){if (1 == arrBackground[19][nList]){return 0;}}return 1;}//2.正在下落得方块下面已经有方块了,是否还能下落int CanSqareDown2(){int nList = 0;int nLine = 0;for (nLine = 19; nLine >= 0; nLine--){for (nList = 0; nList < 10; nList++){if (1 == arrBackground[nLine][nList]){if (2 == arrBackground[nLine+1][nList]){return 0;}}}}return 1;}//3.前面下落条件都满足了,方块才能下落int SqareDwon(){int nLine = 0,nList = 0;for (nLine = 19; nLine >= 0; nLine--){for (nList = 0; nList <10; nList++){if (1 == arrBackground[nLine][nList]){arrBackground[nLine+1][nList] = arrBackground[nLine][nList];arrBackground[nLine][nList] = 0;}}}return 1;}/*以下是关于随机方块显示的几个函数:1.怎么产生随机方块;2.产生的第一个方块显示到窗口;3.之后产生了随机方块又怎么显示到窗口;4.已结摆好的底层方块又怎么显示 *///1.产生随机方块,数组指为1就代表方块int CreateRandomSqare(){int nFlag = 0;srand((unsigned int)time(NULL));nFlag = rand()%7;g_nLineLocation = 0;g_nListLocation = 3;switch (nFlag){case 0:arrSqare[0][0] = 1;arrSqare[0][1] = 1;arrSqare[0][2] = 1;arrSqare[0][3] = 1;arrSqare[1][0] = 0;arrSqare[1][1] = 0;arrSqare[1][2] = 0;arrSqare[1][3] = 0;break;case 1:arrSqare[0][0] = 1;arrSqare[0][1] = 1;arrSqare[0][2] = 0;arrSqare[0][3] = 0;arrSqare[1][0] = 0;arrSqare[1][1] = 1;arrSqare[1][2] = 1;arrSqare[1][3] = 0;break;case 2:arrSqare[0][0] = 0;arrSqare[0][1] = 0;arrSqare[0][2] = 1;arrSqare[0][3] = 1;arrSqare[1][0] = 0;arrSqare[1][1] = 1;arrSqare[1][2] = 1;arrSqare[1][3] = 0;break;case 3:arrSqare[0][0] = 0;arrSqare[0][1] = 1;arrSqare[0][2] = 0;arrSqare[0][3] = 0;arrSqare[1][0] = 0;arrSqare[1][1] = 1;arrSqare[1][2] = 1;arrSqare[1][3] = 1;break;case 4:arrSqare[0][0] = 0;arrSqare[0][1] = 0;arrSqare[0][2] = 1;arrSqare[0][3] = 0;arrSqare[1][0] = 1;arrSqare[1][1] = 1;arrSqare[1][2] = 1;arrSqare[1][3] = 0;break;case 5:arrSqare[0][0] = 0;arrSqare[0][1] = 1;arrSqare[0][2] = 1;arrSqare[0][3] = 0;arrSqare[1][0] = 0;arrSqare[1][1] = 1;arrSqare[1][2] = 1;arrSqare[1][3] = 0;break;case 6:arrSqare[0][0] = 0;arrSqare[0][1] = 1;arrSqare[0][2] = 0;arrSqare[0][3] = 0;arrSqare[1][0] = 1;arrSqare[1][1] = 1;arrSqare[1][2] = 1;arrSqare[1][3] = 0;break;default:return 0;}return 1;}//2.把每次循环产生的第一个随机块放到背景上,没有这个爹原始方块函数就没有后面儿子方块int InitSqareLocate(){//把随机块放到背景上int nLine = 0;int nList = 0;for (nLine = 0; nLine < 2; nLine++){for (nList = 0; nList < 4; nList++){arrBackground[nLine][nList+3] = arrSqare[nLine][nList];}}return 1;}//3.显示正在下落的方块,大家可以试试,没了这个函数正在下落的方块将会看不到int ShowRandomSqare(HDC hdc){int nLine = 0;int nList = 0;//InitSqareLocate();//显示for (nLine = 0; nLine < 20; nLine++){for (nList = 0; nList < 10; nList++){if (1 == arrBackground[nLine][nList]){Rectangle(hdc, nList*30, nLine*30, nList*30+30, nLine*30+30);}}}return 1;}//4.显示已经落好的方块,大家可以试试,没了这个函数落到底的方块将会看不到,当然得先把数组的指1变成2,把正在下落的方块和已经摆好的区分开//把1变成2int Change1To2(){int nLine = 0,nList = 0;for (nLine = 19; nLine >= 0; nLine--){for (nList = 0; nList <10; nList++){if (1 == arrBackground[nLine][nList]){arrBackground[nLine][nList] = 2;}}}return 1;}int ShowSqareElement2(HDC hdc){int nLine = 0;int nList = 0;//InitSqareLocate();HGDIOBJ oldBrush;HGDIOBJ newBrush = CreateSolidBrush(RGB(67, 132, 19));oldBrush = SelectObject(hdc, newBrush);//显示for (nLine = 0; nLine < 20; nLine++){for (nList = 0; nList < 10; nList++){if (2 == arrBackground[nLine][nList]){Rectangle(hdc, nList*30, nLine*30, nList*30+30, nLine*30+30);}}}newBrush = SelectObject(hdc, oldBrush);DeleteObject(newBrush);return 1;}