eluosi.cpp
上传用户:zhengjing
上传日期:2022-08-08
资源大小:5708k
文件大小:8k
源码类别:

游戏

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "俄罗斯方块.h"
  3. #include"eluosi.h"
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. Celuosi::Celuosi()
  10. {
  11. BitCover.LoadBitmap(IDB_BITMAP1);
  12. BitBlock.LoadBitmap(IDB_BITMAP2);
  13.     for(int i=0;i<20;i++)
  14. for(int j=0;j<12;j++)
  15. {
  16. block[i][j]=0;
  17. }
  18.     startflags=0;
  19. score=0;
  20. }
  21. void Celuosi::DrawCover(CDC*pDC)
  22. {
  23. //贴上背景图片
  24. CDC dc;
  25. dc.CreateCompatibleDC(pDC);
  26. dc.SelectObject(BitCover);
  27. pDC->BitBlt(0,0,500,500,&dc,0,0,SRCCOPY);
  28. //设置画刷颜色
  29. CRect rect(100,40,340,440);
  30. CBrush BruBK;
  31. BruBK.CreateSolidBrush(RGB(69,125,125));
  32. dc.FillRect(&rect,&BruBK);
  33. BruBK.DeleteObject();
  34. /*
  35. //设置画笔的颜色
  36. CPen MyPen(PS_SOLID,1,RGB(0,0,0));
  37. HPEN hOldpen=(HPEN)dc.SelectObject(MyPen);
  38. for(int i=0;i<20;i++)
  39. {
  40. dc.MoveTo(100,40+20*i);
  41. dc.LineTo(340,40+20*i);
  42. }    
  43. for(i=0;i<13;i++)
  44. {
  45. dc.MoveTo(100+20*i,40);
  46. dc.LineTo(100+20*i,440);
  47. }
  48. dc.SelectObject(hOldpen);
  49. MyPen.DeleteObject();*/
  50. pDC->BitBlt(0,0,500,500,&dc,0,0,SRCCOPY);
  51.     //画分数
  52. DrawScore(pDC);
  53. //画下一块
  54. DrawNext(pDC);
  55.    
  56.     for(int i=0;i<20;i++)
  57. for(int j=0;j<12;j++)
  58. {
  59. if(block[i][j]==1)
  60. {
  61. dc.SelectObject(BitBlock);
  62. pDC->BitBlt(100+20*j,40+20*i,19,19,&dc,0,0,SRCCOPY);
  63. }
  64. }
  65. dc.DeleteDC();
  66. }
  67. void Celuosi::DrawScore(CDC*pDC)
  68. {
  69. int nOldDC=pDC->SaveDC();
  70. //设置字体
  71. CFont font;    
  72. if(0==font.CreatePointFont(150,"Comic Sans MS"))
  73. {
  74. AfxMessageBox("Can't Create Font");
  75. }
  76. pDC->SelectObject(&font);
  77.     //设置字体颜色及其背景颜色
  78. CString str;
  79. pDC->SetBkMode(TRANSPARENT);
  80. pDC->SetTextColor(RGB(39,244,10));
  81.     //输出分数
  82.   pDC->TextOut(350,60,"分数:");
  83.     pDC->TextOut(350,160,"难度:");
  84.     pDC->TextOut(350,260,"下一块:");
  85. str.Format("%d",score);
  86. if(score>=0)
  87. pDC->TextOut(400,90,str);
  88. //画难度
  89.     CMyApp*pApp=(CMyApp*)AfxGetApp();
  90.     str.Format("%d",pApp->speed);
  91. if(score>=0)
  92.   pDC->TextOut(400,190,str);
  93. pDC->RestoreDC(nOldDC);
  94. }
  95. void Celuosi::Start()
  96. {
  97.    m_PosLeft.x=4;
  98.    m_PosLeft.y=0;
  99.    for(int i=0;i<20;i++)
  100. for(int j=0;j<12;j++)
  101. {
  102. block[i][j]=0;
  103. }
  104.    for(i=0;i<4;i++)
  105.    for(int j=0;j<4;j++)
  106.    {
  107.    now[i][j]=0;
  108.    will[i][j]=0;
  109.    }
  110.   
  111.    GetBlock(); //赋值will
  112.    GetBlock(); //赋值now
  113.    startflags=true;
  114.    score=0;
  115. }
  116. void Celuosi::move(int dir)
  117. {
  118.    switch(dir)
  119.    {
  120.     case 1: //上键
  121. {
  122. change(); //变形
  123. break;
  124. }
  125.     case 2: //下键
  126. {
  127. Fall();   //下落
  128. break;
  129. }
  130. case 3: //左键
  131. {
  132. moveleft();  //左移
  133. break;
  134. case 4: //右键
  135. {
  136. moveright();  //右移
  137. break;
  138. }
  139.    }
  140. }
  141. void Celuosi::GetBlock()
  142. {
  143. for(int i=0;i<4;i++)
  144. for(int j=0;j<4;j++)
  145. {
  146. now[i][j]=will[i][j];
  147.     will[i][j]=0;
  148. }
  149. srand(::GetTickCount());
  150. int shap=rand()%7;
  151. switch(shap)
  152. {
  153. case 0:
  154. will[0][0]=1;
  155. will[0][1]=1;
  156. will[1][0]=1;
  157. will[1][1]=1;
  158. break;
  159. case 1:
  160.         will[0][0]=1;
  161. will[2][0]=1;
  162. will[1][0]=1;
  163. will[1][1]=1;
  164. break;
  165. case 2:
  166. will[0][0]=1;
  167. will[2][1]=1;
  168. will[1][0]=1;
  169. will[1][1]=1;
  170. break;
  171. case 3:
  172. will[2][0]=1;
  173. will[0][1]=1;
  174. will[1][0]=1;
  175. will[1][1]=1;
  176. break;
  177. case 4:
  178. will[0][0]=1;
  179. will[2][0]=1;
  180. will[1][0]=1;
  181. will[2][1]=1;
  182. break;
  183. case 5:
  184. will[0][1]=1;
  185. will[1][1]=1;
  186. will[2][0]=1;
  187. will[2][1]=1;
  188. break;
  189. case 6:
  190. will[0][0]=1;
  191. will[1][0]=1;
  192. will[2][0]=1;
  193. will[3][0]=1;
  194. break;
  195. }
  196. }
  197. void Celuosi::Fall()
  198. {
  199.    //清除前一步方块
  200.    int c=m_PosLeft.x;
  201.    int l=m_PosLeft.y;
  202.    for(int i=0;i<4;i++)
  203. for(int j=0;j<4;j++)
  204. {
  205. if(now[i][j]==1)
  206.        block[l+i][c+j]=0;
  207. }
  208.    for(i=0;i<4;i++)
  209.    for(int j=0;j<4;j++)
  210.    {
  211.    if(block[i][4+j]==1)
  212.    {
  213.    startflags=0;
  214.    for(int i=0;i<4;i++)
  215.    for(int j=0;j<4;j++)
  216.    {
  217.    if(now[i][j]==1)
  218.    block[i][4+j]=1;
  219.    }
  220.    score=0;
  221.    MessageBox(NULL,"游戏结束","fail",MB_OK);
  222.    return;
  223.    }
  224.    }
  225.    //判断边界
  226.    int col[4];
  227.    for(i=0;i<4;i++)
  228.    {
  229.       col[i]=0;
  230.    }
  231.    int n=0;
  232.    bool mark;
  233.    for(i=0;i<4;i++)
  234.    {
  235.    mark=false;
  236. for(int j=0;j<4;j++)
  237. {
  238. if(now[j][i]==1&&j>col[i])
  239.        col[i]=j;
  240. if(now[j][i]==1)
  241. mark=true;
  242. }
  243. if(mark)
  244.   n++;
  245.    }
  246.    for(i=0;i<n;i++)
  247.    {
  248.      if(block[l+col[i]+1][c+i]==1||(col[i]+l+1)>19)
  249. goto exit;  
  250.    }
  251.    //下落一格
  252.    m_PosLeft.y+=1;
  253.    l+=1;
  254.    for(i=0;i<4;i++)
  255. for(int j=0;j<4;j++)
  256. {
  257. if(now[i][j]==1)
  258.        block[l+i][c+j]=1;
  259. }
  260. return;
  261. exit:
  262. for(i=0;i<4;i++)
  263. for(int j=0;j<4;j++)
  264. {
  265. if(now[i][j]==1)
  266.        block[l+i][c+j]=1;
  267. }
  268. linedelete();
  269. GetBlock();
  270.     m_PosLeft.x=4;
  271.     m_PosLeft.y=0;
  272.     return;
  273. }
  274. void Celuosi::change()
  275. {
  276.    for(int i=0;i<4;i++)
  277. for(int j=0;j<4;j++)
  278. {
  279. if(now[i][j]==1)
  280. block[m_PosLeft.y+i][m_PosLeft.x+j]=0;
  281. }
  282.    int a[4][4],b[4][4];
  283.    //变换
  284.    for(i=0;i<4;i++)
  285.   for(int j=0;j<4;j++)
  286.   {
  287. a[i][j]=now[j][3-i];
  288. b[i][j]=now[i][j];
  289.   }
  290.    for(i=0;i<4;i++)
  291.   for(int j=0;j<4;j++)
  292. now[i][j]=0;
  293.    //找左上角
  294.    int k=4,l=4;
  295.    for(i=0;i<4;i++)
  296.   for(int j=0;j<4;j++)
  297.   {
  298. if(a[i][j]==1)
  299. {
  300.            if(k>i) k=i;
  301.    if(l>j) l=j;
  302. }
  303.   }
  304.    //得到变换后的形状
  305.    for(i=k;i<4;i++)
  306.   for(int j=l;j<4;j++)
  307.   {
  308. now[i-k][j-l]=a[i][j];
  309.   }
  310.    //判断是否超出范围
  311.   bool overflow=false;
  312.   for(i=0;i<4;i++)
  313. for(int j=0;j<4;j++)
  314. {
  315. if(now[i][j]==1)
  316. {
  317. if(m_PosLeft.x+j>11||m_PosLeft.x+j<0||m_PosLeft.y+i>19||m_PosLeft.y+i<0||block[m_PosLeft.y+i][m_PosLeft.x+j]==1)
  318.                overflow=true;
  319. }
  320.   if(overflow)
  321.   { 
  322.     for(i=0;i<4;i++)
  323.   for(int j=0;j<4;j++)
  324. now[i][j]=b[i][j];
  325.   }
  326.   for(i=0;i<4;i++)
  327. for(int j=0;j<4;j++)
  328. {
  329. if(now[i][j]==1)
  330.        block[m_PosLeft.y+i][m_PosLeft.x+j]=1;
  331. }
  332. }
  333. void Celuosi::moveleft()
  334. {
  335.    //清除前一次方块
  336.    for(int i=0;i<4;i++)
  337. for(int j=0;j<4;j++)
  338. {
  339. if(now[i][j]==1)
  340. block[m_PosLeft.y+i][m_PosLeft.x+j]=0;
  341. }
  342.    //左移
  343.    if(m_PosLeft.x<=0)
  344.    goto exit;
  345.    int a[4];
  346.    for(i=0;i<4;i++)
  347.    {
  348.       a[i]=4;
  349.    }
  350.    for(i=0;i<4;i++)
  351. for(int j=0;j<4;j++)
  352. {
  353.      if(now[i][j]==1&&j<a[i])
  354.       a[i]=j;
  355. }
  356.    for(i=0;i<4;i++)
  357.    {
  358.       if(block[m_PosLeft.y+i][m_PosLeft.x+a[i]-1]==1)
  359.   goto exit;
  360.    }
  361.    m_PosLeft.x-=1;
  362.    //移动
  363. exit:
  364.    for(i=0;i<4;i++)
  365. for(int j=0;j<4;j++)
  366. {
  367. if(now[i][j]==1)
  368. block[m_PosLeft.y+i][m_PosLeft.x+j]=1;
  369. }
  370. }
  371. void Celuosi::moveright()
  372. {
  373.    //清除上一次方块
  374.    for(int i=0;i<4;i++)
  375. for(int j=0;j<4;j++)
  376. {
  377. if(now[i][j]==1)
  378. block[m_PosLeft.y+i][m_PosLeft.x+j]=0;
  379. }
  380. //右移
  381.    int a[4];
  382.    for(i=0;i<4;i++)
  383.    {
  384.       a[i]=0;
  385.    }
  386.    for(i=0;i<4;i++)
  387. for(int j=0;j<4;j++)
  388. {
  389.      if(now[i][j]==1&&j>a[i])
  390.       a[i]=j;
  391. }
  392.    for(i=0;i<4;i++)
  393.    {
  394.   if(m_PosLeft.x+a[i]>10)
  395.     goto exit;
  396.       if(block[m_PosLeft.y+i][m_PosLeft.x+a[i]+1]==1)
  397.   goto exit;
  398.    }
  399.    m_PosLeft.x+=1;
  400. exit:
  401.    //移动
  402.    for(i=0;i<4;i++)
  403. for(int j=0;j<4;j++)
  404. {
  405. if(now[i][j]==1)
  406. block[m_PosLeft.y+i][m_PosLeft.x+j]=1;
  407. }
  408. }
  409. void Celuosi::linedelete()
  410. {
  411.     int m=0;         //本次共消去的行数
  412. bool flag=0;
  413.     for(int i=0;i<20;i++)
  414.     {
  415. //检查要不要消行
  416. flag=true;
  417. for(int j=0;j<12;j++)
  418. {
  419. if(block[i][j]==0)
  420. flag=false;
  421. }
  422. //如果要
  423. if(flag==true)
  424. {
  425. m++;
  426. for(int k=i;k>0;k--)
  427. {
  428. //上行给下行                         
  429. for(int l=0;l<12;l++)
  430. {
  431. block[k][l]=block[k-1][l];
  432. }
  433. }
  434. //第一行为零
  435. for(int l=0;l<12;l++)
  436. {
  437. block[0][l]=0;
  438. }
  439. }
  440. }
  441. switch(m)
  442. {
  443. case 1:
  444.         score+=100;
  445. break;
  446. case 2:
  447. score+=200;
  448. break;
  449. case 3:
  450. score+=400;
  451. break;
  452. case 4:
  453. score+=600;
  454. break;
  455. default:
  456. break;
  457. }
  458. }
  459. void Celuosi::DrawNext(CDC*pDC)
  460. {
  461. CDC dc;
  462. dc.CreateCompatibleDC(pDC);
  463.     for(int i=0;i<4;i++)
  464. for(int j=0;j<4;j++)
  465. {
  466. if(will[i][j]==1)
  467. {
  468.                dc.SelectObject(BitBlock);
  469.    pDC->BitBlt(390+20*j,290+20*i,19,19,&dc,0,0,SRCCOPY);
  470. }
  471. }
  472. }
  473. void Celuosi::end()
  474. {
  475.    for(int i=0;i<20;i++)
  476. for(int j=0;j<12;j++)
  477. {
  478. block[i][j]=0;
  479. }
  480.    for(i=0;i<4;i++)
  481.    for(int j=0;j<4;j++)
  482.    {
  483.    now[i][j]=0;
  484.    will[i][j]=0;
  485.    }
  486.  startflags=false;
  487. }