C++编写的俄罗斯方块代码
2018-07-20 来源:open-open
#ifndef DATA_H_ #define DATA_H_ /* * index:7行10列数组 每行对应一种方块类别。 * 每行的前四列为x坐标,中间四列为y坐标 * 第九列为方块类别代码,最后一列为该类型方块有几种变形 * 用一个5*5的矩阵表示 7种类别方块 共19种变形 */ #include<windows.h> static const int KINDS=7;//方块种类数量 static const int COLS=10;//数据列数 //每种方块的代号 static const int TYPE1=1; static const int TYPE2=2; static const int TYPE3=3; static const int TYPE4=4; static const int TYPE5=5; static const int TYPE6=6; static const int TYPE7=7; //变形的种类 static const int RTYPE1=1; static const int RTYPE2=2; static const int RTYPE3=4; static int rTypeNext; static int rTypeDown; //初始化方块坐标及对应的类别和变形种类 static const int index[KINDS][COLS]={ {0,1,0,1,0,0,-1,-1,TYPE1,RTYPE1}, {-1,0,1,2,0,0,0,0,TYPE2,RTYPE2}, {0,0,1,1,1,0,0,-1,TYPE3,RTYPE2}, {0,0,1,1,-1,0,0,1,TYPE4,RTYPE2}, {-1,0,0,1,0,0,1,0,TYPE5,RTYPE3}, {-1,0,1,1,0,0,0,-1,TYPE6,RTYPE3}, {-1,0,1,1,0,0,0,1,TYPE7,RTYPE3} }; //定时器ID static const int TIMER=1; // //初始游戏级别对应的时间间隔 static int CURRENTLEVEL=600; static int level=1; //每种图形所包含的小方块数 static const int CTN=4; //方块形状定义 typedef struct { int x; int y; }sCord; sCord sDown[CTN],sNext[CTN]; //下一个方块的坐标 static RECT rectNext[CTN]; //正在下落方块的坐标 static RECT rectDown[CTN]; //显示区域的大小 static const int cxSize=25; static const int cySize=35; //方块偏离(0,0)得位置 static int offsetx; static int offsety; static int offsetxNext; static int offsetyNext; //自定义消息 static const int MS_DOWN=10001; //暂停 static bool go=true; //开始 static bool startGame=false; //结束 static bool gameOver=false; //得分 static int score; RECT rt={326,81,425,455}; //每个方格包含的像素 static const int pelsSize=13; //显示区域大小的定义 static const POINT area[]={0,455,326,455,326,0}; //显示区域的表示方法 最后一列最后一行分别对应该行该列所具有的方块总数 0表示没有方块1表示有 static int fillArea[cySize+1][cxSize+1]; HBRUSH hBrush1=CreateSolidBrush(RGB(0,0,0));//方块颜色 //HBRUSH hBrush1=CreateSolidBrush(RGB(240,250,100));//黄色 HBRUSH hBrush2=CreateSolidBrush(RGB(255,255,255)); HPEN hPen1=CreatePen(PS_SOLID,0,RGB(230,230,230));//背景格颜色 #endif /* DATA_H_ */ #include"Data.h" #include<iostream> #include<cstdlib> using namespace std; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); /* * 逆时针方向旋转方格 返回能否旋转 * @param lpsCord 要旋转的方块坐标指针 * @param rType 旋转类型 * @param rNumber 旋转次数 * @param 是否第一次旋转 */ bool rotate(sCord *lpsCord,int rType,int rNumber,bool firstRotate); void getRandom();//初始化方格形状 void getNext(sCord *targ,const sCord* sur);//取出下一个方块 void draw();//绘出方格 void start();//开始游戏 bool downAble();//能否下落 bool leftAble();//能否左移 bool rightAble();//能否右移 bool disRows(HWND hwnd);//判断能否消行 //int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, // // PSTR szCmdLine, int iCmdShow) //void paintRect(HDC hdc,RECT&,HBRUSH hBrush); int main() { HINSTANCE hInstance=NULL; static TCHAR szAppName[]=TEXT("ELS"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style=CS_HREDRAW|CS_VREDRAW;//|~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX) ; wndclass.lpfnWndProc=WndProc; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hInstance=hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground= (HBRUSH)GetStockObject (WHITE_BRUSH);// CreateSolidBrush(RGB(195,195,237)); wndclass.lpszMenuName= NULL; wndclass.lpszClassName= szAppName; if(!RegisterClass(&wndclass)) { MessageBox(NULL,TEXT("REGISTER ERROR"),szAppName,MB_ICONERROR); return 0; } hwnd=CreateWindow(szAppName,TEXT("俄罗斯方块"),WS_DLGFRAME|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,//(WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX)&~WS_BORDER,//WS_SIZEBOX WS_OVERLAPPEDWINDOW&~WS_MAXIMIZEBOX,WS_CAPTION|//&~WS_MAXIMIZEBOX禁用最大化选项 300,100,429,480, NULL,NULL,hInstance,NULL); ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void getRandom() { int k=rand()%KINDS+1; for(int i=0;i<KINDS;i++) { if(index[i][COLS-2]==k) { rTypeNext=index[i][COLS-1];//获得旋转类型 for(int j=0;j<CTN;j++) { sNext[j].x=index[i][j]; sNext[j].y=index[i][j+4]; } break; } } rotate(sNext,rTypeNext,rand()%rTypeNext+1,true); int min_y=0; for (int t = 0; t < CTN; t++) min_y = min_y > sNext[t].y ? sNext[t].y : min_y; offsetxNext=(int)(cxSize/2)*pelsSize+(int)(pelsSize/2);//x方向的中间显示 offsetyNext=(-min_y)*pelsSize+(int)(pelsSize/2);//保证置顶显示 } bool rotate(sCord *lpsCord,int rType,int rNumber,bool firstRotate) { int tempx; int tempy; int temp; int tx=(offsetx-(int)(pelsSize/2))/pelsSize; int ty=(offsety-(int)(pelsSize/2))/pelsSize; bool ra=true; switch(rType) { case RTYPE1: ra=false; break; case RTYPE2: { if(rNumber%2!=0) { for (int j = 0; j < CTN; j++) { tempx=-lpsCord->y+tx; tempy=lpsCord->x+ty; lpsCord++; if(!firstRotate&&(fillArea[tempx][tempy]>0||tempx>24||tempx<0||tempy<0||tempy>34)) { ra=false; } } lpsCord-=4; } if(ra) { if (rNumber % 2 != 0) for (int k = 0; k < CTN; k++) { temp = -lpsCord->x; lpsCord->x = lpsCord->y; lpsCord->y = temp; lpsCord++; } } } break; case RTYPE3: for(int k=0;k<rNumber;k++) { for(int l=0;l<CTN;l++) { tempx=lpsCord->y+tx; tempy=(-lpsCord->x)+ty; lpsCord++; if(!firstRotate&&(fillArea[tempx][tempy]>0||tempx>24||tempx<0||tempy<0||tempy>34)) { ra = false; } } lpsCord-=4; } if(ra) for (int i = 0; i < rNumber; i++) { for (int j = 0; j < CTN; j++) { temp = -lpsCord->x; lpsCord->x = lpsCord->y; lpsCord->y = temp; lpsCord++; } lpsCord=lpsCord-4; } break; } return ra; } void getNext(sCord *targ,const sCord* sur) { rTypeDown=rTypeNext; offsetx=offsetxNext; offsety=offsetyNext; for(int i=0;i<CTN;i++) { targ->x=sur->x; targ->y=sur->y; sur++; targ++; } getRandom(); } void draw(HWND hwnd,const sCord* shape,RECT *rect,HBRUSH hBrush,int offsetx,int offsety) { HDC hdc=GetDC(hwnd); SelectObject(hdc,hBrush); SelectObject(hdc,hPen1); // SelectObject(hdc,hPen2); // for(int i=0;i<CTN;i++) // { //// cout<<"draw:x="<<shape->x<<"y="<<shape->y<<endl; // SetRect(rect,pelsSize*shape->x-(int)(pelsSize/2)+offsetx,pelsSize*shape->y-(int)(pelsSize/2)+offsety, // pelsSize*shape->x+(int)(pelsSize/2)+offsetx,pelsSize*shape->y+(int)(pelsSize/2)+offsety); // FillRect(hdc,rect,hBrush); // shape++; // rect++; // } for(int i=0;i<CTN;i++) { Rectangle(hdc,pelsSize*shape->x-(int)(pelsSize/2)+offsetx,pelsSize*shape->y-(int)(pelsSize/2)+offsety, pelsSize*shape->x+(int)(pelsSize/2)+offsetx+2,pelsSize*shape->y+(int)(pelsSize/2)+offsety+2); shape++; // rect++; } ReleaseDC(hwnd,hdc); } void start() { if(!startGame) { for (int i = 0; i < cySize + 1; i++) for (int j = 0; j < cxSize + 1; j++) fillArea[i][j] = 0; startGame=true; go=true; score=0; } } bool downAble() { bool da=true; int x=(offsetx-(int)(pelsSize/2))/pelsSize; int y=(offsety-(int)(pelsSize/2))/pelsSize; int xtemp; int ytemp; for(int i=0;i<CTN;i++) { xtemp=sDown[i].x+x; ytemp=sDown[i].y+y+1; if(fillArea[ytemp][xtemp]>0||ytemp>34) { da=false; break; } } if (!da) { for (int k = 0; k < CTN; k++) { xtemp = sDown[k].x + x; ytemp = sDown[k].y + y; fillArea[ytemp][xtemp] = 1; fillArea[ytemp][cxSize]++; fillArea[cySize][xtemp]++; } } return da; } bool leftAble() { bool la = true; int x = (offsetx - (int) (pelsSize / 2)) / pelsSize; int y = (offsety - (int) (pelsSize / 2)) / pelsSize; int xtemp; int ytemp; for (int i = 0; i < CTN; i++) { xtemp = sDown[i].x + x-1; ytemp = sDown[i].y + y; if (fillArea[ytemp][xtemp] > 0 || xtemp <0) { la = false; break; } } return la; } bool rightAble() { bool ra = true; int x = (offsetx - (int) (pelsSize / 2)) / pelsSize; int y = (offsety - (int) (pelsSize / 2)) / pelsSize ; int xtemp; int ytemp; for (int i = 0; i < CTN; i++) { xtemp = sDown[i].x + x+1; ytemp = sDown[i].y + y; if (fillArea[ytemp][xtemp] > 0 || xtemp > 24) { ra = false; break; } } return ra; } bool disRows(HWND hwnd) { HDC hdc=GetDC(hwnd); bool da=false; int row[CTN];//可以消除的行 for (int ii = 0; ii < CTN; ii++) row[ii] = 0; int number = 0;//可连续消的行数 static int levelScore; SelectObject(hdc,hPen1); for (int i = 0; i < cySize; i++) { if (fillArea[i][cxSize] == cxSize) row[number++] = i; } if (number > 0)//可以消行 { da=true; levelScore+=(number + 1) * number / 2; score += (number + 1) * number / 2; cout<<"levelScore:"<<levelScore<<endl; if(levelScore>19)//增加游戏级别 { levelScore=0; CURRENTLEVEL=(int)CURRENTLEVEL*2/3; SetTimer(hwnd,TIMER,CURRENTLEVEL,NULL); cout<<"currentlevel:"<<CURRENTLEVEL<<endl; for(int i=0;i<15;i++) { if((int)CURRENTLEVEL*3*(i+1)/2>=600) { level=i+2; cout<<"level"<<i+2<<endl; break; } } } InvalidateRect(hwnd,&rt,true); for (int k = 0; k < number; k++) { for(int i=row[k];i>0;i--) { for(int j=0;j<cxSize+1;j++) { fillArea[i][j]=fillArea[i-1][j]; } } } InvalidateRect(hwnd,NULL,true); } ReleaseDC(hwnd,hdc); return da; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT r; static bool down=false; bool isSend=false; switch(message) { case WM_CREATE: { SetTimer(hwnd,TIMER,CURRENTLEVEL,NULL); cout<<"level1"<<endl; return 0; } case WM_SIZE: // cout<<LOWORD(lParam)<<endl // <<HIWORD(lParam)<<endl; return 0; // case WM_GETMINMAXINFO: // return 0; case WM_TIMER: { if(startGame&&go) { if (down) { if(!downAble())//不能再下落条件 { cout<<"can not down"<<endl; down=false; disRows(hwnd); if(!isSend) { SendMessage(hwnd,MS_DOWN,0,0); isSend=true; } } else { draw(hwnd, sDown, rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH), offsetx, offsety); offsety += pelsSize; draw(hwnd, sDown, rectDown,hBrush1, offsetx, offsety); } } } return 0; } case MS_DOWN: { draw(hwnd,sNext,rectNext,(HBRUSH)GetStockObject(WHITE_BRUSH),369,44); getNext(sDown,sNext); draw(hwnd,sNext,rectNext,hBrush1,369,44); draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety); //判断游戏是否结束 offsety-=pelsSize; if(downAble()) { offsety+=pelsSize; isSend=false; down=true; } else { cout<<"game over!"<<endl; startGame=false; gameOver=true; InvalidateRect(hwnd,&rt,true); } } case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &r); SelectObject(hdc,hPen1); SelectObject(hdc,hBrush1); for(int i=1;i<cxSize+8;i++) { MoveToEx(hdc,i*pelsSize,0,NULL); LineTo(hdc,i*pelsSize,476); } for(int j=1;j<cySize;j++) { MoveToEx(hdc,0,j*pelsSize,NULL); LineTo(hdc,425,j*pelsSize); } SaveDC(hdc); for(int t=0;t<cySize;t++) for(int k=0;k<cxSize;k++) { if(fillArea[t][k]>0) { Rectangle(hdc,k*pelsSize,t*pelsSize,(k+1)*pelsSize+1,(t+1)*pelsSize+1); } } if(startGame) { draw(hwnd,sNext,rectNext,hBrush1,369,44); draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety); } FillRect(hdc,&rt,hBrush2); char ss[20]; char ll[20]; wsprintf(ss,"score:%d",score); wsprintf(ll,"level:%d",level); TextOut(hdc,330,300,ll,lstrlen(ll)); TextOut(hdc,330,320,ss,lstrlen(ss)); if(gameOver) { char g[]="Game Over!!"; TextOut(hdc,330,200,g,lstrlen(g)); } SelectObject(hdc, GetStockObject(BLACK_PEN)); Polyline(hdc, area, 3);//绘制一个矩形 MoveToEx(hdc, 325, 80, NULL); LineTo(hdc, 425, 80); EndPaint(hwnd, &ps); return 0; } case WM_KEYDOWN: switch(wParam) { case VK_UP: { if(go&&startGame) { down=false; draw(hwnd,sDown,rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH),offsetx,offsety); rotate(sDown,rTypeDown,1,false); draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety); } } return 0; case VK_DOWN: { if(go&&startGame) { down=false; draw(hwnd,sDown,rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH),offsetx,offsety); int k=(offsety-(int)(pelsSize)/2)/pelsSize; while(k<cySize) { if(downAble()) { offsety+=pelsSize; } else break; } draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety); disRows(hwnd); SendMessage(hwnd,MS_DOWN,0,0); } return 0; } case VK_LEFT: { if(leftAble()&&go&&startGame) { down=false; draw(hwnd,sDown,rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH),offsetx,offsety); offsetx-=pelsSize; draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety); } return 0; } case VK_RIGHT: { if(rightAble()&&go&&startGame) { down=false; draw(hwnd, sDown, rectDown, (HBRUSH) GetStockObject(WHITE_BRUSH), offsetx, offsety); offsetx+=pelsSize; draw(hwnd, sDown, rectDown, hBrush1, offsetx, offsety); } return 0; } case VK_SPACE: { go=!go; return 0; } case VK_RETURN: { if(!startGame&&!gameOver) { cout<<"startGame"<<endl; gameOver=false; start(); getRandom(); SendMessage(hwnd,MS_DOWN,0,0); } if(!startGame&&gameOver) { cout<<"RestartGame!"<<endl; gameOver=false; start(); level=1; InvalidateRect(hwnd,NULL,true); getRandom(); SendMessage(hwnd,MS_DOWN,0,0); } return 0; } } return 0; case WM_KEYUP: switch(wParam) { case VK_UP: if(go) down=true; return 0; case VK_LEFT: if(go) down=true; return 0; case VK_RIGHT: if(go) down=true; return 0; } return 0; case WM_DESTROY: DeleteObject(hBrush1); DeleteObject(hBrush2); DeleteObject(hPen1); KillTimer(hwnd,TIMER); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); }
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。
下一篇:IOS 8 使用系统自带导航
最新资讯
热门推荐