TetrisView.cpp
上传用户:apollo_111
上传日期:2022-08-09
资源大小:2146k
文件大小:24k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // TetrisView.cpp : implementation of the CTetrisView class
  2. //
  3. #include "stdafx.h"
  4. #include "Tetris.h"
  5. #include "time.h"
  6. #include "TetrisDoc.h"
  7. #include "TetrisView.h"
  8. #include <mmsystem.h>
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CTetrisView
  16. IMPLEMENT_DYNCREATE(CTetrisView, CView)
  17. BEGIN_MESSAGE_MAP(CTetrisView, CView)
  18. //{{AFX_MSG_MAP(CTetrisView)
  19. ON_WM_CREATE()
  20. ON_WM_DESTROY()
  21. ON_WM_SIZE()
  22. ON_WM_KEYDOWN()
  23. ON_WM_KEYUP()
  24. ON_WM_TIMER()
  25. ON_COMMAND(ID_GAME_NEW, OnGameNew)
  26. //}}AFX_MSG_MAP
  27. // Standard printing commands
  28. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  29. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  30. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  31. END_MESSAGE_MAP()
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CTetrisView construction/destruction
  34. CTetrisView::CTetrisView()
  35. {
  36. // TODO: add construction code here
  37. gameintro  = true;
  38. gamerun    = false;
  39. gamewin    = false;
  40. gamefinish = false;
  41. onetime    = true;
  42. test       = false;
  43. running    = true;
  44. xpos = 155;
  45. ypos = 295;
  46. level = 1;
  47. speed = 1000;
  48. keys[VK_RETURN]=false;
  49. keys[VK_LEFT]=false;
  50. keys[VK_RIGHT]=false;
  51. keys[VK_UP]=false;
  52. keys[VK_DOWN]=false;
  53. keys[VK_SPACE]=false;
  54. int i,j;
  55. for(i=0;i<=10;i++)
  56. for(j=0;j<=20;j++)
  57. map[i][j]=0;
  58. for(i=0;i<=4;i++)
  59. for(j=0;j<=5;j++)
  60. nextblockmap[i][j]=0;
  61. }
  62. CTetrisView::~CTetrisView()
  63. {
  64. }
  65. BOOL CTetrisView::PreCreateWindow(CREATESTRUCT& cs)
  66. {
  67. // TODO: Modify the Window class or styles here by modifying
  68. //  the CREATESTRUCT cs
  69. ////////////////////////////////////////////////////////////////
  70. //设置窗口类型
  71. cs.style |=WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  72. ////////////////////////////////////////////////////////////////
  73. return CView::PreCreateWindow(cs);
  74. }
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CTetrisView drawing
  77. void CTetrisView::OnDraw(CDC* pDC)
  78. {
  79. CTetrisDoc* pDoc = GetDocument();
  80. ASSERT_VALID(pDoc);
  81. // TODO: add draw code for native data here
  82. //////////////////////////////////////////////////////////////////
  83. RenderScene(); //渲染场景
  84. //////////////////////////////////////////////////////////////////
  85. }
  86. /////////////////////////////////////////////////////////////////////////////
  87. // CTetrisView printing
  88. BOOL CTetrisView::OnPreparePrinting(CPrintInfo* pInfo)
  89. {
  90. // default preparation
  91. return DoPreparePrinting(pInfo);
  92. }
  93. void CTetrisView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  94. {
  95. // TODO: add extra initialization before printing
  96. }
  97. void CTetrisView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  98. {
  99. // TODO: add cleanup after printing
  100. }
  101. /////////////////////////////////////////////////////////////////////////////
  102. // CTetrisView diagnostics
  103. #ifdef _DEBUG
  104. void CTetrisView::AssertValid() const
  105. {
  106. CView::AssertValid();
  107. }
  108. void CTetrisView::Dump(CDumpContext& dc) const
  109. {
  110. CView::Dump(dc);
  111. }
  112. CTetrisDoc* CTetrisView::GetDocument() // non-debug version is inline
  113. {
  114. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTetrisDoc)));
  115. return (CTetrisDoc*)m_pDocument;
  116. }
  117. #endif //_DEBUG
  118. /////////////////////////////////////////////////////////////////////////////
  119. // CTetrisView message handlers
  120. int CTetrisView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  121. {
  122. if (CView::OnCreate(lpCreateStruct) == -1)
  123. return -1;
  124. // TODO: Add your specialized creation code here
  125. //////////////////////////////////////////////////////////////////
  126. //初始化OpenGL和设置定时器
  127. m_pDC = new CClientDC(this);
  128. SetTimer(1, 10, NULL);
  129. InitializeOpenGL(m_pDC);
  130. //////////////////////////////////////////////////////////////////
  131. return 0;
  132. }
  133. void CTetrisView::OnDestroy() 
  134. {
  135. CView::OnDestroy();
  136. // TODO: Add your message handler code here
  137. /////////////////////////////////////////////////////////////////
  138. //删除调色板和渲染上下文、定时器
  139. ::wglMakeCurrent(0,0);
  140. ::wglDeleteContext( m_hRC);
  141. if (m_hPalette)
  142.     DeleteObject(m_hPalette);
  143. if ( m_pDC )
  144. {
  145. delete m_pDC;
  146. }
  147. KillTimer(1);
  148. /////////////////////////////////////////////////////////////////
  149. m_font.KillFont();
  150. }
  151. void CTetrisView::OnSize(UINT nType, int cx, int cy) 
  152. {
  153. CView::OnSize(nType, cx, cy);
  154. // TODO: Add your message handler code here
  155. if (cy==0) // Prevent A Divide By Zero By
  156. {
  157. cy=1; // Making Height Equal One
  158. }
  159. glViewport(0,0,cx,cy); // Reset The Current Viewport
  160. glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
  161. glLoadIdentity(); // Reset The Projection Matrix
  162. glOrtho(0.0f,640.0f,480.0f,0.0f,-1.0f,1.0f); // Create Ortho 640x480 View (0,0 At Top Left)
  163. glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
  164. glLoadIdentity(); // Reset The Modelview Matrix
  165. }
  166. void CTetrisView::OnTimer(UINT nIDEvent) 
  167. {
  168. // TODO: Add your message handler code here and/or call default
  169. /////////////////////////////////////////////////////////////////
  170. //添加定时器响应函数和场景更新函数
  171. Invalidate(FALSE);
  172. /////////////////////////////////////////////////////////////////
  173. CView::OnTimer(nIDEvent);
  174. }
  175. /////////////////////////////////////////////////////////////////////
  176. //                   设置逻辑调色板
  177. //////////////////////////////////////////////////////////////////////
  178. void CTetrisView::SetLogicalPalette(void)
  179. {
  180.     struct
  181.     {
  182.         WORD Version;
  183.         WORD NumberOfEntries;
  184.         PALETTEENTRY aEntries[256];
  185.     } logicalPalette = { 0x300, 256 };
  186. BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};
  187. BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};
  188. BYTE blues[] = {0, 85, 170, 255};
  189.     for (int colorNum=0; colorNum<256; ++colorNum)
  190.     {
  191.         logicalPalette.aEntries[colorNum].peRed =
  192.             reds[colorNum & 0x07];
  193.         logicalPalette.aEntries[colorNum].peGreen =
  194.             greens[(colorNum >> 0x03) & 0x07];
  195.         logicalPalette.aEntries[colorNum].peBlue =
  196.             blues[(colorNum >> 0x06) & 0x03];
  197.         logicalPalette.aEntries[colorNum].peFlags = 0;
  198.     }
  199.     m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);
  200. }
  201. //////////////////////////////////////////////////////////
  202. // 初始化openGL场景
  203. //////////////////////////////////////////////////////////
  204. BOOL CTetrisView::InitializeOpenGL(CDC* pDC)
  205. {
  206. m_pDC = pDC;
  207. SetupPixelFormat();
  208. //生成绘制描述表
  209. m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());
  210. //置当前绘制描述表
  211. ::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
  212. CreateTexture(texture, "Data/GameRun.bmp",0);     
  213. CreateTexture(texture, "Data/Block.bmp",1);
  214. CreateTexture(texture, "Data/GameIntro.bmp",2);
  215. CreateTexture(texture, "Data/GameOver.bmp",3);
  216. CreateTexture(texture, "Data/GameWin.bmp",4);
  217. CreateTexture(texture, "Data/LevelSelect.bmp",5);
  218. CreateTexture(texture, "Data/Mask.bmp",6);
  219. glEnable(GL_TEXTURE_2D);
  220. glShadeModel(GL_SMOOTH);
  221. glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
  222. glClearDepth(1.0f);
  223. glEnable(GL_DEPTH_TEST);
  224. glDepthFunc(GL_LEQUAL);
  225. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  226. HDC hDC = wglGetCurrentDC();
  227. m_font.BuildFont(hDC);
  228. srand(timeGetTime() );
  229. return TRUE;
  230. }
  231. //////////////////////////////////////////////////////////
  232. // 设置像素格式
  233. //////////////////////////////////////////////////////////
  234. BOOL CTetrisView::SetupPixelFormat()
  235. {
  236. PIXELFORMATDESCRIPTOR pfd = { 
  237.     sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小 
  238.     1,                                // 版本号 
  239.     PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图 
  240.     PFD_SUPPORT_OPENGL |              // 支持 OpenGL 
  241.     PFD_DOUBLEBUFFER,                 // 双缓存模式 
  242.     PFD_TYPE_RGBA,                    // RGBA 颜色模式 
  243.     24,                               // 24 位颜色深度 
  244.     0, 0, 0, 0, 0, 0,                 // 忽略颜色位 
  245.     0,                                // 没有非透明度缓存 
  246.     0,                                // 忽略移位位 
  247.     0,                                // 无累加缓存 
  248.     0, 0, 0, 0,                       // 忽略累加位 
  249.     32,                               // 32 位深度缓存     
  250.     0,                                // 无模板缓存 
  251.     0,                                // 无辅助缓存 
  252.     PFD_MAIN_PLANE,                   // 主层 
  253.     0,                                // 保留 
  254.     0, 0, 0                           // 忽略层,可见性和损毁掩模 
  255. }; 
  256. int pixelformat;
  257. pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//选择像素格式
  258. ::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd); //设置像素格式
  259. if(pfd.dwFlags & PFD_NEED_PALETTE)
  260. SetLogicalPalette(); //设置逻辑调色板
  261. return TRUE;
  262. }
  263. //////////////////////////////////////////////////////////
  264. // 场景绘制与渲染
  265. //////////////////////////////////////////////////////////
  266. BOOL CTetrisView::RenderScene() 
  267. {
  268. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
  269. glLoadIdentity(); // Reset The Current Modelview Matrix
  270. if(gameintro)
  271. {
  272. DrawGameIntro();
  273. }
  274. if(gamerun)
  275. {
  276. DrawGameRun();
  277. }
  278. if(gamefinish)
  279. {
  280. DrawGameRun();
  281. DrawGameFinish();
  282. }
  283. if(gamewin)
  284. {
  285. DrawGameRun();
  286. DrawGameWin();
  287. }
  288. ::SwapBuffers(m_pDC->GetSafeHdc()); //交互缓冲区
  289. return TRUE;
  290. }
  291. void CTetrisView::DrawGameIntro()
  292. {
  293. //  游戏封面的绘制
  294. glBindTexture(GL_TEXTURE_2D,  texture[2]);
  295. glBegin(GL_QUADS);
  296. glTexCoord2i(0,1); glVertex2i(0,0);
  297. glTexCoord2i(0,0); glVertex2i(0,480);
  298. glTexCoord2i(1,0); glVertex2i(640,480);
  299. glTexCoord2i(1,1); glVertex2i(640,0);
  300. glEnd();
  301. //  被选择难度等级数的绘制
  302. glBlendFunc(GL_DST_COLOR,GL_ZERO);
  303. glEnable(GL_BLEND);
  304. glBindTexture(GL_TEXTURE_2D,  texture[6]);
  305. glBegin(GL_QUADS);
  306. glTexCoord2i(0,1); glVertex2i(xpos,ypos);
  307. glTexCoord2i(0,0); glVertex2i(xpos,ypos+64);
  308. glTexCoord2i(1,0); glVertex2i(xpos+64,ypos+64);
  309. glTexCoord2i(1,1); glVertex2i(xpos+64,ypos);
  310. glEnd();
  311. glBlendFunc(GL_ONE,GL_ONE);
  312. glBindTexture(GL_TEXTURE_2D,  texture[5]);
  313. glBegin(GL_QUADS);
  314. glTexCoord2i(0,1); glVertex2i(xpos,ypos);
  315. glTexCoord2i(0,0); glVertex2i(xpos,ypos+64);
  316. glTexCoord2i(1,0); glVertex2i(xpos+64,ypos+64);
  317. glTexCoord2i(1,1); glVertex2i(xpos+64,ypos);
  318. glEnd();
  319. glDisable(GL_BLEND);
  320. if (keys[VK_LEFT])
  321. {
  322. keys[VK_LEFT] = false;
  323. if(level--==1)
  324. level=10;
  325. if (xpos <= 155 && ypos == 295)
  326. {
  327. xpos = 419;
  328. ypos = 295+66;
  329. }else if (xpos <= 155 && ypos == 295+66)
  330. {
  331. xpos = 419;
  332. ypos = 295;
  333. }else
  334. xpos-=66;
  335. }
  336. if (keys[VK_RIGHT])
  337. {
  338. keys[VK_RIGHT] = false;
  339. if(level++==10)
  340. level=1;
  341. if (xpos >= 419 && ypos == 295)
  342. {
  343. xpos = 155;
  344. ypos = 295+66;
  345. }else if (xpos >= 419 && ypos == 295+66)
  346. {
  347. xpos = 155;
  348. ypos = 295;
  349. }else
  350. xpos+=66;
  351. }
  352. if (keys[VK_RETURN])
  353. {
  354. speed=int(speed/(level+1));
  355. SetTimer(1, speed, NULL);
  356. gamefinish = false;
  357. gamewin    = false;
  358. gameintro  = false;
  359. gamerun    = true;
  360. }
  361. }
  362.  
  363. int CTetrisView::DrawGameRun(GLvoid)
  364. {
  365. if (onetime)
  366. {
  367. InitGame();
  368. onetime = false;
  369. }
  370. else if (running)
  371. {
  372. if (!MoveDown())
  373. {
  374. CheckWin();
  375. }
  376. }
  377. // 绘制背景
  378. glBindTexture(GL_TEXTURE_2D,  texture[0]);
  379. glBegin(GL_QUADS);
  380. glTexCoord2i(0,1); glVertex2i(0,0);
  381. glTexCoord2i(0,0); glVertex2i(0,480);
  382. glTexCoord2i(1,0); glVertex2i(640,480);
  383. glTexCoord2i(1,1); glVertex2i(640,0);
  384. glEnd();
  385. //绘制主窗口的方块图
  386. for (int x = 0;x <= 9;x++)
  387. {
  388. for (int y = 0;y <= 19;y++)
  389. {
  390. int xp = x* 25+50;
  391. int yp = y* 20+40;
  392. if (map[x][y] == 2 || map [x][y] == 1)
  393. {
  394. glBindTexture(GL_TEXTURE_2D, texture[1]);
  395. glBegin(GL_QUADS);
  396. glTexCoord2i(0,1); glVertex2i(xp,yp);
  397. glTexCoord2i(1,1); glVertex2i(xp + 25,yp);   
  398. glTexCoord2i(1,0); glVertex2i(xp + 25,yp + 20);      
  399. glTexCoord2i(0,0); glVertex2i(xp,yp + 20);           
  400. glEnd();
  401. }
  402. }
  403. }
  404.     // 绘制下一个将要下落的随机小方块
  405. for (int i = 0; i < 4; i++)
  406. {
  407. for (int j = 0; j < 5; j++)
  408. {
  409. int ip = i* 25+410;
  410. int jp = j* 20+320;
  411. if (nextblockmap[i][j] != 0 && type != 0)
  412. {
  413. glBindTexture(GL_TEXTURE_2D, texture[1]);
  414. glBegin(GL_QUADS);
  415. glTexCoord2i(0,1); glVertex2i(ip,jp);
  416. glTexCoord2i(1,1); glVertex2i(ip + 25,jp);   
  417. glTexCoord2i(1,0); glVertex2i(ip + 25,jp + 20);      
  418. glTexCoord2i(0,0); glVertex2i(ip,jp + 20);           
  419. glEnd();
  420. }
  421. if (nextblockmap[i][j] != 0 && type == 0)
  422. {
  423. glBindTexture(GL_TEXTURE_2D, texture[1]);
  424. glBegin(GL_QUADS);
  425. glTexCoord2i(0,1); glVertex2i(ip+12,jp);
  426. glTexCoord2i(1,1); glVertex2i(ip+12 + 25,jp);   
  427. glTexCoord2i(1,0); glVertex2i(ip+12 + 25,jp + 20);      
  428. glTexCoord2i(0,0); glVertex2i(ip+12,jp + 20);           
  429. glEnd();
  430. }
  431. }
  432. }    
  433. // 绘制文本
  434. glDisable(GL_TEXTURE_2D);
  435.     glColor3d(128,128,128);
  436. glRasterPos2d(370, 65);
  437. m_font.glPrint("L E V E L");
  438. glRasterPos2d(485, 65);
  439. m_font.glPrint("%d",level-1);
  440. glRasterPos2d(370,68+73+13);
  441. m_font.glPrint("L I N E S");
  442. glRasterPos2d(485,68+73+13);
  443. m_font.glPrint("%d",lines);
  444. glRasterPos2d(370, 239);
  445. m_font.glPrint("S C O R E");
  446. glRasterPos2d(485, 239);
  447. m_font.glPrint("%d",score);
  448. glRasterPos2d(433,320);
  449. m_font.glPrint("N E X T");
  450. glEnable(GL_TEXTURE_2D);
  451. if (keys[VK_LEFT])
  452. {
  453. keys[VK_LEFT] = false;
  454. MoveLeft();
  455. }
  456. if (keys[VK_RIGHT])
  457. {
  458. keys[VK_RIGHT] = false;
  459. MoveRight();
  460. }
  461. if (keys[VK_UP])
  462. {
  463. keys[VK_UP] = false;
  464. Rotate();
  465. }
  466. if (keys[VK_DOWN])
  467. {
  468. keys[VK_DOWN] = false;
  469. MoveDown();
  470. }
  471. if (keys[VK_SPACE])
  472. {
  473. keys[VK_SPACE] = false;
  474. do{} while (MoveDown());
  475. }
  476. return true;
  477. }
  478. void CTetrisView::DrawGameWin()
  479. {
  480. glBindTexture(GL_TEXTURE_2D,  texture[4]);
  481. glBegin(GL_QUADS);
  482. glTexCoord2i(0,1); glVertex2i(640/2-150,480/2-75);
  483. glTexCoord2i(0,0); glVertex2i(640/2-150,480/2+150-75);
  484. glTexCoord2i(1,0); glVertex2i(640/2+300-150,480/2+150-75);
  485. glTexCoord2i(1,1); glVertex2i(640/2+300-150,480/2-75);
  486. glEnd();
  487. }
  488. void CTetrisView::DrawGameFinish()
  489. {
  490. glBindTexture(GL_TEXTURE_2D,  texture[3]);
  491. glBegin(GL_QUADS);
  492. glTexCoord2i(0,1); glVertex2i(640/2-150,480/2-75);
  493. glTexCoord2i(0,0); glVertex2i(640/2-150,480/2+150-75);
  494. glTexCoord2i(1,0); glVertex2i(640/2+300-150,480/2+150-75);
  495. glTexCoord2i(1,1); glVertex2i(640/2+300-150,480/2-75);
  496. glEnd();
  497. }
  498. void CTetrisView::InitGame()
  499. {
  500. score = 0;
  501. state = 0;
  502. lines = 0;
  503. block = nextblock;
  504. state = 0;
  505. NewBlock();
  506. CheckWin();
  507. }
  508. void CTetrisView::NewBlock()
  509. {
  510. int i;
  511. type = rand()%7;
  512. switch(type)
  513. {
  514. case 0:
  515. for ( i = 0;i <= 3;i++)
  516. {
  517. block[0].x[i] = 4;
  518. block[1].x[i] = 5;
  519. block[2].x[i] = 4;
  520. block[3].x[i] = 5;
  521. block[0].y[i] = 0;
  522. block[1].y[i] = 0;
  523. block[2].y[i] = 1;
  524. block[3].y[i] = 1;
  525. }
  526. break;
  527. case 1:
  528. for ( i = 0;i <= 3;i++)
  529. {
  530. block[i].y[0] = i;
  531. block[i].y[2] = i;
  532. block[i].x[0] = 5;
  533. block[i].x[2] = 5;
  534. block[i].x[1] = i + 4;
  535. block[i].x[3] = i + 4;
  536. block[i].y[1] = 0;
  537. block[i].y[3] = 0;
  538. }
  539. break;
  540. case 2:
  541. for ( i = 0;i <= 2;i += 2)
  542. {
  543. block[0].x[i] = 4;
  544. block[1].x[i] = 5;
  545. block[2].x[i] = 5;
  546. block[3].x[i] = 6;
  547. block[0].y[i] = 0;
  548. block[1].y[i] = 0;
  549. block[2].y[i] = 1;
  550. block[3].y[i] = 1;
  551. block[0].x[i+1] = 5;
  552. block[1].x[i+1] = 5;
  553. block[2].x[i+1] = 4;
  554. block[3].x[i+1] = 4;
  555. block[0].y[i+1] = 0;
  556. block[1].y[i+1] = 1;
  557. block[2].y[i+1] = 1;
  558. block[3].y[i+1] = 2;
  559. }
  560. break;
  561. case 3:
  562. for ( i = 0;i <= 2;i +=2)
  563. {
  564. block[0].x[i] = 6;
  565. block[1].x[i] = 5;
  566. block[2].x[i] = 5;
  567. block[3].x[i] = 4;
  568. block[0].y[i] = 0;
  569. block[1].y[i] = 0;
  570. block[2].y[i] = 1;
  571. block[3].y[i] = 1;
  572. block[0].x[i+1] = 5;
  573. block[1].x[i+1] = 5;
  574. block[2].x[i+1] = 4;
  575. block[3].x[i+1] = 4;
  576. block[0].y[i+1] = 2;
  577. block[1].y[i+1] = 1;
  578. block[2].y[i+1] = 1;
  579. block[3].y[i+1] = 0;
  580. }
  581. break;
  582. case 4:
  583. block[0].x[0] = 4; // 状态 0
  584. block[1].x[0] = 4;
  585. block[2].x[0] = 5;
  586. block[3].x[0] = 6;
  587. block[0].y[0] = 1;
  588. block[1].y[0] = 0;
  589. block[2].y[0] = 0;
  590. block[3].y[0] = 0;
  591. block[0].x[1] = 5; // 状态 1
  592. block[1].x[1] = 6;
  593. block[2].x[1] = 6;
  594. block[3].x[1] = 6;
  595. block[0].y[1] = 0;
  596. block[1].y[1] = 0;
  597. block[2].y[1] = 1;
  598. block[3].y[1] = 2;
  599. block[0].x[2] = 4; // 状态 2
  600. block[1].x[2] = 5;
  601. block[2].x[2] = 6;
  602. block[3].x[2] = 6;
  603. block[0].y[2] = 1;
  604. block[1].y[2] = 1;
  605. block[2].y[2] = 1;
  606. block[3].y[2] = 0;
  607. block[0].x[3] = 5; // 状态 3
  608. block[1].x[3] = 5;
  609. block[2].x[3] = 5;
  610. block[3].x[3] = 6;
  611. block[0].y[3] = 0;
  612. block[1].y[3] = 1;
  613. block[2].y[3] = 2;
  614. block[3].y[3] = 2;
  615. break;
  616. case 5:
  617. block[0].x[0] = 4; // 状态 0
  618. block[1].x[0] = 5;
  619. block[2].x[0] = 6;
  620. block[3].x[0] = 6;
  621. block[0].y[0] = 0;
  622. block[1].y[0] = 0;
  623. block[2].y[0] = 0;
  624. block[3].y[0] = 1;
  625. block[0].x[1] = 6; // 状态 1
  626. block[1].x[1] = 6;
  627. block[2].x[1] = 6;
  628. block[3].x[1] = 5;
  629. block[0].y[1] = 0;
  630. block[1].y[1] = 1;
  631. block[2].y[1] = 2;
  632. block[3].y[1] = 2;
  633. block[0].x[2] = 4; // 状态 2
  634. block[1].x[2] = 4;
  635. block[2].x[2] = 5;
  636. block[3].x[2] = 6;
  637. block[0].y[2] = 0;
  638. block[1].y[2] = 1;
  639. block[2].y[2] = 1;
  640. block[3].y[2] = 1;
  641. block[0].x[3] = 6; // 状态 3
  642. block[1].x[3] = 5;
  643. block[2].x[3] = 5;
  644. block[3].x[3] = 5;
  645. block[0].y[3] = 0;
  646. block[1].y[3] = 0;
  647. block[2].y[3] = 1;
  648. block[3].y[3] = 2;
  649. break;
  650. case 6:
  651. block[0].x[3] = 5;  // 状态 0
  652. block[1].x[3] = 5;
  653. block[2].x[3] = 5;
  654. block[3].x[3] = 4;
  655. block[0].y[3] = 0;
  656. block[1].y[3] = 1;
  657. block[2].y[3] = 2;
  658. block[3].y[3] = 1;
  659. block[0].x[2] = 4; // 状态 1
  660. block[1].x[2] = 5;
  661. block[2].x[2] = 6;
  662. block[3].x[2] = 5;
  663. block[0].y[2] = 1;
  664. block[1].y[2] = 2;
  665. block[2].y[2] = 1;
  666. block[3].y[2] = 1;
  667. block[0].x[0] = 4;  // 状态 2
  668. block[1].x[0] = 5;
  669. block[2].x[0] = 6;
  670. block[3].x[0] = 5;
  671. block[0].y[0] = 1;
  672. block[1].y[0] = 1;
  673. block[2].y[0] = 1;
  674. block[3].y[0] = 0;
  675. block[0].x[1] = 5;  // 状态 3
  676. block[1].x[1] = 5;
  677. block[2].x[1] = 5;
  678. block[3].x[1] = 6;
  679. block[0].y[1] = 0;
  680. block[1].y[1] = 1;
  681. block[2].y[1] = 2;
  682. block[3].y[1] = 1;
  683. break;
  684. }
  685. }
  686. void CTetrisView::CreateTexture(UINT textureArray[], LPSTR strFileName, int textureID)
  687. {
  688. AUX_RGBImageRec *pBitmap = NULL;
  689. //  如果文件不存在,在返回
  690. if(!strFileName)
  691. return;
  692. //  读入位图文件中的数据
  693. pBitmap = auxDIBImageLoad(strFileName);
  694. if(pBitmap == NULL)
  695. exit(0);
  696. //  生成纹理
  697. glGenTextures(1, &textureArray[textureID]);
  698. //  捆绑纹理
  699. glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);
  700. //  设置纹理参数
  701. gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap->sizeX, pBitmap->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pBitmap->data);
  702. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  703. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  704. //  释放资源
  705. if (pBitmap)
  706. {
  707. if (pBitmap->data)
  708. {
  709. free(pBitmap->data);
  710. }
  711. free(pBitmap);
  712. }
  713. }
  714. bool CTetrisView::CheckWin()
  715. {
  716. linemultiplier = 0;
  717. linesformed = 0;
  718. for (int i = 0;i <=3;i++)
  719. map[block[i].x[state]][block[i].y[state]] = 1;
  720. for ( i = 0;i<20;i++)
  721. {
  722. lineformed = TRUE;
  723. for(int j=0;j<10;j++)
  724. {
  725. if (map[j][i] == 0)
  726. lineformed = FALSE;
  727. }
  728. if (lineformed)
  729. {
  730.     
  731. linesformed++;
  732. for (int k=i-1;k>=0;k--)
  733. {
  734. for (int l=0;l<10;l++)
  735. {
  736. map[l][k + 1] = map[l][k];
  737. }
  738. }
  739. }
  740. }
  741. switch (linesformed)
  742. {
  743. case 1:
  744. linemultiplier = 10; 
  745. break;
  746. case 2:
  747. linemultiplier = 25; 
  748. break;
  749. case 3:
  750. linemultiplier = 75; 
  751. break;
  752. case 4:
  753. linemultiplier = 300; 
  754. break;
  755. }
  756. //  游戏分数递增
  757. lines += linesformed;
  758. score += (level + 1) * 4 * linemultiplier;
  759. for (i=0;i<4;i++) 
  760. currentblock[i] = nextblock[i];
  761. block = nextblock;
  762. state = 0;
  763. NewBlock();
  764. for (int y=0;y<4;y++)
  765. {
  766. for (int x=0;x<5;x++)
  767. {
  768. nextblockmap[y][x] = 0;
  769. }
  770. }
  771. for (i = 0;i <=3;i++)
  772. nextblockmap[block[i].x[state]-3][block[i].y[state]+1] = 1;
  773. block = currentblock;
  774. for (i = 0;i <=3;i++)
  775. if (map[block[i].x[state]][block[i].y[state]] == 1 && !onetime)
  776. {
  777. gamerun    = false;
  778. gameintro  = false;
  779. gamewin    = false;
  780. gamefinish = true;
  781. running    = false;
  782. }
  783. }
  784. for (i = 0;i <=3;i++)
  785. map[block[i].x[state]][block[i].y[state]] = 2;
  786. if (lines >= (level) * 10)
  787. {
  788. //  难度等级递增
  789. level++;
  790. speed=int(speed/(level+1));
  791. SetTimer(1, speed, NULL);
  792. //  如果游戏难度等级大于10,则游戏成功
  793. if (level >10)
  794. {
  795. gamerun    = false;
  796. gameintro  = false;
  797. gamefinish = false;
  798. gamewin    = true;
  799. running    = false;
  800. }
  801. return true;
  802. }
  803. return false;
  804. }
  805. bool CTetrisView::MoveDown()
  806. {
  807. for (int i = 0;i <=3;i++)
  808. {
  809. // 如果小方块到达底部
  810. if ((map[block[i].x[state]][block[i].y[state]+1] == 1) || 
  811. (block[i].y[state] >= 19)) return false;
  812. for (i = 0;i <=3;i++)
  813. {
  814. // 删除块
  815. map[block[i].x[state]][block[i].y[state]] = 0;
  816. // 向下移动
  817. for (int j = 0;j <= 3;j++)
  818. {
  819. block[i].y[j] = block[i].y[j]++;
  820. }
  821. }
  822. for (i = 0;i <=3;i++)
  823. map[block[i].x[state]][block[i].y[state]] = 2;
  824. return true;
  825. }
  826. bool CTetrisView::MoveLeft()
  827. {
  828. for (int i = 0;i <=3;i++)
  829. {
  830. if (map[block[i].x[state]-1][block[i].y[state]] == 1 ||
  831. block[i].x[state] <= 0)
  832. return false;
  833. for (i = 0;i <=3;i++)
  834. {
  835. map[block[i].x[state]][block[i].y[state]] = 0;
  836. for (int j = 0;j <= 3;j++)
  837. {
  838. block[i].x[j] = block[i].x[j]--;
  839. }
  840. }
  841. for (i = 0;i <=3;i++)
  842. map[block[i].x[state]][block[i].y[state]] = 2;
  843. return true;
  844. }
  845. bool CTetrisView::MoveRight()
  846. {
  847. for (int i = 0;i <=3;i++)
  848. {
  849. if (map[block[i].x[state]+1][block[i].y[state]] == 1 ||
  850. block[i].x[state] >= 9)
  851. return false;
  852. for (i = 0;i <=3;i++)
  853. {
  854. map[block[i].x[state]][block[i].y[state]] = 0;
  855. for (int j = 0;j <= 3;j++)
  856. {
  857. block[i].x[j] = block[i].x[j]++;
  858. }
  859. }
  860. for (i = 0;i <=3;i++)
  861. map[block[i].x[state]][block[i].y[state]] = 2;
  862. return true;
  863. }
  864. bool CTetrisView::Rotate()
  865. {
  866. newstate = state+1;
  867. if (newstate==4)
  868. newstate=0;
  869. for (int i = 0;i <=3;i++)
  870. {
  871. if (map[block[i].x[newstate]][block[i].y[newstate]] == 1 ||
  872. block[i].x[newstate] >= 10 || block[i].x[newstate] <= -1 ||
  873. block[i].y[newstate] >= 19 || block[i].y[newstate] <= 0)
  874. {
  875. return FALSE;
  876. }
  877. }
  878. for (i = 0;i <=3;i++)
  879. {
  880. map[block[i].x[state]][block[i].y[state]] = 0;
  881. }
  882. for (i = 0;i <=3;i++)
  883. map[block[i].x[newstate]][block[i].y[newstate]] = 2;
  884. state = newstate;
  885. return true;
  886. }
  887. void CTetrisView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  888. {
  889. // TODO: Add your message handler code here and/or call default
  890. keys[nChar]=true;
  891. if(nChar==VK_ESCAPE) exit(0);
  892. CView::OnKeyDown(nChar, nRepCnt, nFlags);
  893. }
  894. void CTetrisView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  895. {
  896. // TODO: Add your message handler code here and/or call default
  897. keys[nChar]=false;
  898. CView::OnKeyUp(nChar, nRepCnt, nFlags);
  899. }
  900. void CTetrisView::OnGameNew() 
  901. {
  902. // TODO: Add your command handler code here
  903. int i,j;
  904. for(i=0;i<=10;i++)
  905. for(j=0;j<=20;j++)
  906. map[i][j]=0;
  907. for(i=0;i<=4;i++)
  908. for(j=0;j<=5;j++)
  909. nextblockmap[i][j]=0;
  910. gameintro  = true;
  911. gamerun    = false;
  912. gamewin    = false;
  913. gamefinish = false;
  914. onetime    = true;
  915. test       = false;
  916. running    = true;
  917. }