| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
wdey
10年前发布

C++编写的俄罗斯方块代码

#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);  }