Game.cpp
上传用户:may_xy
上传日期:2007-08-09
资源大小:1519k
文件大小:14k
源码类别:

游戏

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "斗地主.h"
  3. #include "MainFrm.h"
  4. #include "My_DirectInput.h"
  5. #include "my_directdraw.h"
  6. #include "Playing_Cards.h"
  7. #include "Game.h"
  8. #include "Draw_Item_Engine.h"
  9. #include "Draw_Cards_Engine.h"
  10. //#include "Single_Game.h"
  11. //主窗口句柄;
  12. HWND hWnd;
  13. //主窗口类指针;设为全局变量便于各个类访问其方法;
  14. CMainFrame* pCMainFrame;
  15. //DirectDraw设备对象指针;
  16. CMyDirectInput* pInput;
  17. CMyDirectDraw* pDraw;
  18. LPDIRECTDRAWSURFACE7  lpddsprimary; // dd primary surface
  19. LPDIRECTDRAWSURFACE7  lpddsback; // dd back surface
  20. LPDIRECTDRAWSURFACE7  lpddsbg_Game; //离屏表面;
  21. //游戏主体框架类指针;
  22. CGame* pGame;
  23. //54张扑克;
  24. CCard g_cAllCards[54];
  25. //存储玩家信息的类;
  26. CPlayerInfo* pCenterPlayer;
  27. CPlayerInfo* pLeftPlayer;
  28. CPlayerInfo* pRightPlayer;
  29. CPlayingCards* pLeftCards;      //左边玩家的牌对象;
  30. CPlayingCards* pCenterCards;   //主机玩家的牌对象;
  31. CPlayingCards* pRightCards;   //右边玩家的牌对象;
  32. //关于其他精灵的绘制引擎;
  33. CDrawItemEngine* pDrawItem;
  34. //关于扑克绘制的引擎;
  35. CDrawCardsEngine* pDrawCards;
  36. //游戏牌面坐标系统;
  37. CCardsMap* pCardsMap;
  38. //网络设备;
  39. CLink* pServerLink1;  //连接客户1;
  40. CLink* pServerLink2;  //连接客户2;
  41. CLink* pClientLink;   //客户端1;
  42. //位置坐标;
  43. int Screen_Width = 1024; int Screen_Height = 768;  //屏幕长,宽;
  44. int Cards_Width = 82; int Cards_Height = 114;  //扑克长宽;
  45. //int Face_Width = 70; int Face_Height = 70; //头像的长宽;
  46. int Center_x0 = 350;     int Center_y0 = 620; //中间玩家未出的牌;
  47. int Center_x1 = 230;     int Center_y1 = 470; //中间玩家已经出过的牌;
  48. int Center_x2 = 330;     int Center_y2 = 340; //中间玩家刚出的牌;
  49. int Left_x0 = 35;     int Left_y0 = 140; //左边玩家未出的牌;
  50. int Left_x1 = 140;     int Left_y1 = 30; //左边玩家已经出过的牌;
  51. int Left_x2 = 240;     int Left_y2 = 65; //左边玩家刚出的牌;
  52. int Right_x0 = 905;     int Right_y0 = 140;  //右边玩家未出的牌;
  53. int Right_x1 = 800;     int Right_y1 = 30;  //右边玩家已经出过的牌;
  54. int Right_x2 = 700;     int Right_y2 = 65;  //右边玩家刚出的牌;
  55. //三张显示的地主牌;
  56. int Lord_Card1_x = 379; int Lord_Card1_y =  30;
  57. int Lord_Card2_x = 471; int Lord_Card2_y =  30;
  58. int Lord_Card3_x = 563; int Lord_Card3_y =  30;
  59.               
  60. int Card_x = 471;     int Card_y = 190; //发牌的起始位置;
  61. //左,右玩家未出牌和中间玩家已出牌的间距:
  62. int Card_Distance0 = 18;
  63. //左,右玩家已出牌的间距;
  64. int Card_Distance1 = 23;
  65. //中间玩家未出牌和刚出的牌的间距;
  66. int Card_Distance2 = 25;
  67. //中间扑克选择后突出的高度;
  68. int Card_Up = 20;
  69. CPlayerInfo::CPlayerInfo()
  70. {
  71. m_nPlayerType = -1;
  72. m_nFaceID     = -1;
  73. m_nScore      = 50;
  74. m_nWin        = 0;
  75. m_nLose       = 0;
  76. }
  77. //游戏屏幕刷新函数;
  78. int RedrawGame(BOOL bSprimary)
  79. {
  80. pDraw->DrawSurface(lpddsbg_Game,0,0, Screen_Width,Screen_Height,lpddsback,0); 
  81. //重画整个牌面布局;
  82. pDrawCards->Redraw();
  83. pDrawItem->Redraw();
  84. if(bSprimary == 1)
  85. while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
  86. return 1;
  87. }
  88. CGame::CGame():m_cCardsRect(Center_x0,
  89.     Center_y0,
  90.     0,          //这个值会变,不定;
  91.     Center_y0 + Cards_Height),
  92.   m_cCardsUpRect(Center_x0,
  93.  Center_y0 - Card_Up,
  94.  0, //这个值会变,不定;
  95.  Center_y0 + Cards_Height - Card_Up),
  96.   m_cOK_RECT(660,550,660+80,550+30),
  97.   m_cYES_RECT(335,540,335+80,540+30),
  98.   m_cNO_RECT(425,540,425+80,540+30),
  99.   m_cEXIT_RECT(900,695,900+100,695+30)
  100. {
  101. m_nCurrentLord = -1;  
  102. m_nDefaultLord = -1;
  103. m_nLordLock    = -1; 
  104. m_bButton    = 1;
  105. m_bOperate     = FALSE;
  106. m_nRoundCounter = 0;
  107. m_nGameCounter  = 0;
  108. m_nBombCounter  = 0;
  109. }
  110. CGame::~CGame()
  111. {
  112. }
  113. void CGame::Init()
  114. {
  115. //Dx设备的初始化;
  116. //产生DirctDraw对象;
  117. pDraw = new CMyDirectDraw;
  118. pDraw->Init();
  119. //初始化鼠标输入设备;
  120. pInput = new CMyDirectInput;   
  121. pInput->MouseInit();
  122. pLeftCards  = new CPlayingCards;      //左边玩家的牌对象;
  123. pCenterCards    = new CPlayingCards;  //主机玩家的牌对象;
  124. pRightCards = new CPlayingCards;   //右边玩家的牌对象;
  125. pCardsMap = new CCardsMap;           
  126. pDrawItem = new CDrawItemEngine;
  127. pDrawItem->Init();
  128. pDrawCards = new CDrawCardsEngine;  
  129. pDrawCards->Init();
  130. }
  131. //新一局,洗牌;
  132. void CGame::NewGame()
  133. {
  134. m_nGameCounter++;
  135. m_nCurrentLord = -1;  
  136. m_nDefaultLord = -1;
  137. m_nLordLock    = -1; 
  138. m_bButton  = 1;
  139. m_bOperate   = FALSE;
  140. m_nRoundCounter = 0;  
  141. m_nBombCounter = 0;
  142. pDrawCards->m_bVisual = FALSE;
  143. pLeftCards->New();
  144. pCenterCards->New();
  145. pRightCards->New();
  146. //让新的地主牌不可见,让发的牌可见;
  147. pCardsMap->m_nLordCards = 1;
  148. pCardsMap->m_cDistributeCard.m_bVisual = 1;
  149. for(int i=0;i<3;i++)
  150. {
  151. pCardsMap->m_cLordCards[i].m_bVisual = 0;  //0为不可见;
  152. }
  153. }
  154. //洗牌;
  155. void CGame::ShuffleCards()
  156. {
  157. //将牌放入;
  158. for(int i=3,j=0;j<=12;i++,j++)
  159. {
  160. //黑桃
  161. g_cAllCards[j*4+0].m_nColor = 0;
  162. g_cAllCards[j*4+0].m_nValue = i;
  163. //红桃
  164. g_cAllCards[j*4+1].m_nColor = 1;
  165. g_cAllCards[j*4+1].m_nValue = i;
  166. //梅花
  167. g_cAllCards[j*4+2].m_nColor = 2;
  168. g_cAllCards[j*4+2].m_nValue = i;
  169. //方块
  170. g_cAllCards[j*4+3].m_nColor = 3;
  171. g_cAllCards[j*4+3].m_nValue = i;
  172. }
  173. g_cAllCards[52].m_nColor = 1;   //正百搭;
  174. g_cAllCards[52].m_nValue = 16;
  175. g_cAllCards[53].m_nColor = 0; //副百搭;
  176. g_cAllCards[53].m_nValue = 16;
  177. //高效洗牌;
  178. int nRandPos;   
  179. CCard cTempCard;
  180. for(int k=0;k<54;k++)
  181. {
  182. //产生一个随机位置;
  183. nRandPos = rand()%54;  
  184. //把当前牌与这个随机位置的牌交换;
  185. cTempCard = g_cAllCards[k];
  186. g_cAllCards[k] = g_cAllCards[nRandPos];
  187. g_cAllCards[nRandPos] = cTempCard;
  188. }
  189. }
  190. //当轮到本机玩家出牌时的屏幕刷新函数;
  191. int CGame::RefreshMyTurn()
  192. {
  193. // ::Redraw_Game();
  194. if( m_nLordLock != 1 )
  195. {
  196. if( m_bButton )   //延时锁;
  197. {
  198. //当鼠标点击到按钮并且提起牌数不为0时才执行出牌操作
  199. if( pInput->IsLButtonDown(m_cOK_RECT) )  
  200. {
  201. ::KillTimer(hWnd,20);
  202. PlaySound(MAKEINTRESOURCE(IDR_DING),AfxGetResourceHandle(),
  203. SND_ASYNC|SND_RESOURCE|SND_NODEFAULT );  //
  204. int i = CenterDoing();
  205. if( i == 0 )
  206. {
  207. ::SetTimer(hWnd,20,50,NULL);  //恢复计时器;
  208. }
  209. else if( i == 1 )
  210. {
  211. //左边玩家(电脑)思考,并决定要出的牌;
  212. if( RightDoing() == 0 )
  213. {
  214. return 0;
  215. }
  216. //右边玩家(电脑)思考,并决定要出的牌;
  217. if( LeftDoing() == 0 )
  218. {
  219. return 0;
  220. }
  221. ::SetTimer(hWnd,20,50,NULL);
  222. }
  223. else if( i == 2 )
  224. {
  225. return 0;
  226. }
  227. }
  228. //
  229. }
  230. }
  231. else
  232. {
  233. ::KillTimer(hWnd,20);
  234. CenterDoing();
  235. if( RightDoing() == 0 )
  236. {
  237. return 0;
  238. }
  239. Sleep(1000);  //延时;
  240. //右边玩家(电脑)思考,并决定要出的牌;
  241. if( LeftDoing() == 0 )
  242. {
  243. return 0;
  244. }
  245. Sleep(1000);  //延时;
  246. ::SetTimer(hWnd,20,50,NULL);
  247. }
  248. return 1;
  249. }
  250. //刷新菜单控制整个游戏生命周期的全局线程函数;
  251. DWORD WINAPI CGame::RefreshMenu(LPVOID pParam)
  252. {
  253. int pos;
  254. CPoint point;
  255. while(1)
  256. {
  257. //如果正在游戏当中;
  258. if( pGame->m_bOperate  )
  259. {
  260. pGame->m_cCardsRect.right    = Center_x0 + Card_Distance1 * (pCenterCards->m_nCardsCounter - 1) + Cards_Width;
  261. pGame->m_cCardsUpRect.right = Center_x0 + Card_Distance1 * (pCenterCards->m_nCardsCounter - 1) + Cards_Width;
  262. if( pInput->IsLButtonDown(pGame->m_cCardsRect) )
  263. {
  264. ::GetCursorPos(&point);
  265. pos = (point.x - Center_x0)/Card_Distance1 + 1;  //左键点击的牌;
  266. if(pos >= pCenterCards->m_nCardsCounter)
  267. {
  268. if(pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY != Center_y0 - Card_Up)
  269. {
  270. PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
  271. SND_ASYNC|SND_RESOURCE|SND_NODEFAULT );  //
  272. pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY -= Card_Up;
  273. pCardsMap->m_nUpCounter++; //选择提起的牌数加一;
  274. ::RedrawGame();
  275. // return 1;
  276. }//end if(pCardsMap->Center0[pCenterCards->Cards_Counter - 1].m_nY == Center_y0 - Card_Up)
  277. }
  278. else
  279. {
  280. if(pCardsMap->Center0[pos - 1].m_nY != Center_y0 - Card_Up)
  281. {
  282. PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
  283. SND_ASYNC|SND_RESOURCE|SND_NODEFAULT );  //
  284. pCardsMap->Center0[pos - 1].m_nY -= Card_Up;
  285. pCardsMap->m_nUpCounter++; //选择提起的牌数加一;
  286. ::RedrawGame();
  287. // return 1;
  288. }
  289. }// end if(pos >= pCenterCards->Cards_Counter)
  290. }
  291. else if( pInput->IsRButtonDown(pGame->m_cCardsUpRect) )
  292. {
  293. ::GetCursorPos(&point);
  294. pos = (point.x - Center_x0)/Card_Distance1 + 1;  //右键点击的牌;
  295. if(pos >= pCenterCards->m_nCardsCounter)
  296. {
  297. if(pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY == Center_y0 - Card_Up)
  298. {
  299. PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
  300. SND_ASYNC|SND_RESOURCE|SND_NODEFAULT );  //
  301. pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY += Card_Up;
  302. pCardsMap->m_nUpCounter--; //选择提起的牌数减一;
  303. ::RedrawGame();
  304. }
  305. }
  306.     else
  307. {
  308. if(pCardsMap->Center0[pos - 1].m_nY == Center_y0 - Card_Up)
  309. {
  310. PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
  311. SND_ASYNC|SND_RESOURCE|SND_NODEFAULT );  //
  312. pCardsMap->Center0[pos - 1].m_nY += Card_Up;
  313. pCardsMap->m_nUpCounter--; //选择提起的牌数减一;
  314. ::RedrawGame();
  315. }
  316. }// end if(pos >= pCenterCards->Cards_Counter)
  317. }//end if 点击在未出牌区;
  318. } //end if;
  319. //刷新菜单;
  320. if( pInput->IsLButtonDown(pGame->m_cEXIT_RECT) )  
  321. {
  322. ::PostMessage(hWnd,WM_CLOSE,NULL,NULL); 
  323. ::ExitProcess(NULL);
  324. //强制结束游戏;
  325. }
  326. Sleep(20);
  327. }//end while;
  328. return 1;
  329. }
  330. void CGame::AccountScore(int player)
  331. {
  332. //地主胜;
  333. int score = 0;
  334. if( m_nBombCounter == 0 )
  335. {
  336. score = 1;
  337. }
  338. else
  339. {
  340. score = 2;
  341. m_nBombCounter--;
  342. while( m_nBombCounter )
  343. {
  344. score *= 2;
  345. m_nBombCounter--;
  346. }
  347. // char table_info[10];
  348. //左边玩家得分信息;
  349. // sprintf(table_info,"%d",score);
  350. // pDraw->Draw_Text_GDI(table_info,300,300,RGB(255,0,0),500,"华文新魏",lpddsprimary);
  351. // Sleep(2000);
  352. }
  353. if( player == m_nCurrentLord )
  354. {
  355. switch( m_nCurrentLord )
  356. {
  357. case 0:
  358. pLeftPlayer->m_nScore += score*2;
  359. pLeftPlayer->m_nWin++;
  360. pCenterPlayer->m_nScore -= score;
  361. pCenterPlayer->m_nLose++;
  362. pRightPlayer->m_nScore  -= score;
  363. pRightPlayer->m_nLose++;
  364. pDrawItem->GameScore(m_nCurrentLord,score*2,-score,-score);
  365. break;
  366. case 1:
  367. pCenterPlayer->m_nScore += score*2;
  368. pCenterPlayer->m_nWin++;
  369. pLeftPlayer->m_nScore -= score;
  370. pLeftPlayer->m_nLose++;
  371. pRightPlayer->m_nScore  -= score;
  372. pRightPlayer->m_nLose++;
  373. pDrawItem->GameScore(m_nCurrentLord,-score,score*2,-score);
  374. break;
  375. case 2:
  376. pRightPlayer->m_nScore += score*2;
  377. pRightPlayer->m_nWin++;
  378. pLeftPlayer->m_nScore -= score;
  379. pLeftPlayer->m_nLose++;
  380. pCenterPlayer->m_nScore  -= score;
  381. pCenterPlayer->m_nLose++;
  382. pDrawItem->GameScore(m_nCurrentLord,-score,-score,score*2);
  383. break;
  384. }
  385. }
  386. else
  387. {
  388. switch( m_nCurrentLord )
  389. {
  390. case 0:
  391. pLeftPlayer->m_nScore -= score*2;
  392. pLeftPlayer->m_nLose++;
  393. pCenterPlayer->m_nScore += score;
  394. pCenterPlayer->m_nWin++;
  395. pRightPlayer->m_nScore  += score;
  396. pRightPlayer->m_nWin++;
  397. pDrawItem->GameScore(m_nCurrentLord,-score*2,score,score);
  398. break;
  399. case 1:
  400. pCenterPlayer->m_nScore -= score*2;
  401. pCenterPlayer->m_nLose++;
  402. pLeftPlayer->m_nScore += score;
  403. pLeftPlayer->m_nWin++;
  404. pRightPlayer->m_nScore  += score;
  405. pRightPlayer->m_nWin++;
  406. pDrawItem->GameScore(m_nCurrentLord,score,-score*2,score);
  407. break;
  408. case 2:
  409. pRightPlayer->m_nScore -= score*2;
  410. pRightPlayer->m_nLose++;
  411. pLeftPlayer->m_nScore += score;
  412. pLeftPlayer->m_nWin++;
  413. pCenterPlayer->m_nScore  += score;
  414. pCenterPlayer->m_nWin++;
  415. pDrawItem->GameScore(m_nCurrentLord,score,score,-score*2);
  416. break;
  417. }
  418. }
  419. }
  420. //比较当前牌是否为合法;
  421. int CGame::CompareCards()
  422. {
  423. //大小判断;
  424. if( pLeftCards->m_cDiscardingType.m_nTypeNum != 0 )
  425. {
  426. if( pCenterCards->m_cDiscardingType.m_nTypeNum != 
  427. pLeftCards->m_cDiscardingType.m_nTypeNum )
  428. {
  429. if( pCenterCards->m_cDiscardingType.m_nTypeNum == 4 ) //炸弹;
  430. {
  431. return 1; //合法;
  432. }
  433. else
  434. {
  435. return 0;  //不合法;
  436. }
  437. }
  438. else
  439. {
  440. //补丁:
  441. if( pLeftCards->m_cDiscardingType.m_nTypeValue == 16 && 
  442. pLeftCards->m_cDiscardingType.m_nTypeNum == 1 )
  443. {
  444. if( pCenterCards->m_cDiscardingType.m_nTypeValue == 16 && //大王,可以出;
  445. pCenterCards->m_cChoosingCards[0].m_nColor == 1 )  
  446. {
  447. return 1;
  448. }
  449. else   //要不起;
  450. {
  451. return 0;
  452. }
  453. }
  454. //如果牌型相同;
  455. if( pCenterCards->m_cDiscardingType.m_nTypeValue > 
  456. pLeftCards->m_cDiscardingType.m_nTypeValue )
  457. {
  458. return 1;  //合法;
  459. }
  460. else
  461. {
  462. return 0; //不合法;
  463. }
  464. }
  465. }
  466. //如果左边玩家没出牌,则比较右边玩家;
  467. else if( pRightCards->m_cDiscardingType.m_nTypeNum != 0 )
  468. {
  469. if( pCenterCards->m_cDiscardingType.m_nTypeNum != 
  470. pRightCards->m_cDiscardingType.m_nTypeNum )
  471. {
  472. if( pCenterCards->m_cDiscardingType.m_nTypeNum == 4 ) //炸弹;
  473. {
  474. return 1; //合法;
  475. }
  476. else
  477. {
  478. return 0;  //不合法;
  479. }
  480. }
  481. else
  482. {
  483. //补丁:
  484. if( pRightCards->m_cDiscardingType.m_nTypeValue == 16 && 
  485. pRightCards->m_cDiscardingType.m_nTypeNum == 1 )
  486. {
  487. if( pCenterCards->m_cDiscardingType.m_nTypeValue == 16 && //大王,可以出;
  488. pCenterCards->m_cChoosingCards[0].m_nColor == 1 )  
  489. {
  490. return 1;
  491. }
  492. else   //要不起;
  493. {
  494. return 0;
  495. }
  496. }
  497. //如果牌型相同;
  498. if( pCenterCards->m_cDiscardingType.m_nTypeValue > 
  499. pRightCards->m_cDiscardingType.m_nTypeValue )
  500. {
  501. return 1;  //合法;
  502. }
  503. else
  504. {
  505. return 0; //不合法;
  506. }
  507. }
  508. }
  509. else
  510. {
  511. m_nLordLock = 3;
  512. return 1;
  513. }
  514. return -1;
  515. }