cHitChecker.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:6k
源码类别:

游戏

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. // cHitChecker.cpp: implementation of the cHitChecker class.
  3. //
  4. //////////////////////////////////////////////////////////////////////
  5. #include "stdafx.h"
  6. #include "cHitChecker.h"
  7. #include <stdio.h>
  8. //////////////////////////////////////////////////////////////////////
  9. // Construction/Destruction
  10. //////////////////////////////////////////////////////////////////////
  11. cHitChecker::cHitChecker()
  12. {
  13. hBoundingPoly = NULL;
  14. }
  15. cHitChecker::~cHitChecker()
  16. {
  17. if(hBoundingPoly != NULL)
  18. {
  19. DeleteObject(hBoundingPoly);
  20. }
  21. }
  22. void cHitChecker::RemovePolyFromBound(LPPOINT lpPoints, int iCount, int iX, int iY)
  23. {
  24. // Use the combine Rgn API to remove a poly from the class internal region
  25. HRGN hRgnSrc = NULL;
  26. LPPOINT pStart = lpPoints;
  27. if(iX != 0)
  28. {
  29. for(int i=0;i<iCount;i++)
  30. {
  31. lpPoints->x = lpPoints->x + iX;
  32. lpPoints->y = lpPoints->y + iY;
  33. lpPoints++;
  34. }
  35. lpPoints = pStart;
  36. }
  37. hRgnSrc = CreatePolygonRgn(lpPoints, iCount, ALTERNATE);
  38. if(hRgnSrc == NULL)
  39. {
  40. DXTRACE_MSG("ERROR !");
  41. }
  42. CombineRgn(hBoundingPoly, hBoundingPoly, hRgnSrc, RGN_DIFF);
  43. DeleteObject(hRgnSrc);
  44. if(iX != 0)
  45. {
  46. for(int i=0;i<iCount;i++)
  47. {
  48. lpPoints->x = lpPoints->x - iX;
  49. lpPoints->y = lpPoints->y - iY;
  50. lpPoints++;
  51. }
  52. lpPoints = pStart;
  53. }
  54. }
  55. void cHitChecker::CreatePolygonBound(LPPOINT lpPoints, int nCount)
  56. {
  57. //使用区域API创建多边形边界区域
  58. Destroy();
  59. hBoundingPoly = CreatePolygonRgn(lpPoints, nCount, ALTERNATE);
  60. }
  61. BOOL cHitChecker::HaveHitted(cHitChecker *pHitCheck, int nX, int nY, int nSrcX, int nSrcY)
  62. {
  63. HRGN hSrcObjectRgn;
  64. HRGN hCompObjectRgn;
  65. BOOL bResult = FALSE;
  66. DWORD dwSize;
  67. UINT i = 0;
  68. RGNDATA* rgnData;
  69. //首先检测包围盒矩形,用来快速排除非碰撞的情形
  70. RECT rcObj;
  71. GetRgnBox(pHitCheck->hBoundingPoly,&rcObj);
  72. rcObj.top  += nY; rcObj.bottom  += nY;
  73. rcObj.left += nX; rcObj.right   += nX;
  74. if(nSrcX!=0 && nSrcY!=0)
  75. {
  76. //将自己的多边形边界进行偏移
  77. OffsetRgn(hBoundingPoly, nSrcX, nSrcY);
  78. //判断目标的包围盒是否和自己的多边形边界相交
  79. if(RectInRegion(hBoundingPoly, &rcObj) == 0)
  80. {
  81. //不相交,则对自己的多边形边界进行反偏移,回到初始状态
  82. OffsetRgn(hBoundingPoly, -nSrcX, -nSrcY);
  83. return FALSE;
  84. }
  85. //对自己的多边形边界进行反偏移,回到初始状态
  86. OffsetRgn(hBoundingPoly, -nSrcX, -nSrcY);
  87. }
  88. else
  89. {
  90. //这是一步优化操作,因为nSrcX和nSrcY等于0,所以它可以节约上面几个函数的调用过程,
  91. if(RectInRegion(hBoundingPoly, &rcObj) == 0)
  92. return FALSE;
  93. }
  94. //进一步检测是否相交
  95. //首先拷贝一份目标区域的多边形边界数据
  96. dwSize = GetRegionData(pHitCheck->hBoundingPoly, sizeof(RGNDATA), NULL);
  97. rgnData = (RGNDATA*) malloc(dwSize);
  98. GetRegionData(pHitCheck->hBoundingPoly, dwSize, rgnData);
  99. hSrcObjectRgn = ExtCreateRegion(NULL, dwSize, rgnData);
  100. //加入偏移量
  101. OffsetRgn(hSrcObjectRgn, nX, nY);
  102. //重新获得目标区域的多边形边界数据
  103. dwSize = GetRegionData(hSrcObjectRgn, sizeof(RGNDATA), NULL);
  104. rgnData = (RGNDATA*) realloc(rgnData, dwSize);
  105. GetRegionData(hSrcObjectRgn, dwSize, rgnData);
  106. if(nSrcX !=0 && nSrcY !=0)
  107. {
  108. RGNDATA* rgnData2;
  109. //和上面的操作一样,拷贝一份边界多边形数据
  110. dwSize = GetRegionData(hBoundingPoly, sizeof(RGNDATA), NULL);
  111. rgnData2 = (RGNDATA*) malloc(dwSize);
  112. GetRegionData(hBoundingPoly, dwSize, rgnData2);
  113. hCompObjectRgn = ExtCreateRegion(NULL, dwSize, rgnData2);
  114. //加入偏移量
  115. OffsetRgn(hCompObjectRgn, nSrcX, nSrcY);
  116. bResult = TRUE;
  117. //遍历选取多边形边界的连续的两个顶点作为矩形区域。
  118. for(i=0;i<rgnData->rdh.nCount;i++)
  119. {
  120. memcpy(&rcObj, &rgnData->Buffer[i*sizeof(RECT)], sizeof(RECT));
  121. //相交判断
  122. if(RectInRegion(hCompObjectRgn, &rcObj) != 0)
  123. {
  124. bResult = FALSE;
  125. break;
  126. }
  127. }
  128. free(rgnData2);
  129. DeleteObject(hCompObjectRgn);
  130. }
  131. else
  132. {
  133. bResult = TRUE;
  134. for(i=0;i<rgnData->rdh.nCount;i++)
  135. {
  136. memcpy(&rcObj, &rgnData->Buffer[i*sizeof(RECT)], sizeof(RECT));
  137. if(RectInRegion(hBoundingPoly, &rcObj) != 0)
  138. {
  139. bResult = FALSE;
  140. break;
  141. }
  142. }
  143. }
  144. // Old stuff
  145. /*if(nSrcX !=0)
  146. {
  147. // Same copy for the region being tested
  148. dwSize = GetRegionData(hBoundingPoly, sizeof(RGNDATA), NULL);
  149. rgnData = (RGNDATA*) realloc(rgnData, dwSize);
  150. GetRegionData(hBoundingPoly, dwSize, rgnData);
  151. hTmpObjectRgn = ExtCreateRegion(NULL, dwSize, rgnData);
  152. //free((void*)rgnData);
  153. OffsetRgn(hTmpObjectRgn, nSrcX, nSrcY);
  154. OffsetRgn(hCompObjectRgn, nSrcX, nSrcY);
  155. CombineRgn(hCompObjectRgn, hCompObjectRgn, hSrcObjectRgn, RGN_DIFF);
  156. CombineRgn(hCompObjectRgn, hCompObjectRgn, hTmpObjectRgn, RGN_OR);
  157. // Combine the source object region with the object region
  158. // If the combination result in a different region
  159. // The regions are overllaping and HitChecking is TRUE;
  160. CombineRgn(hTmpObjectRgn, hTmpObjectRgn, hSrcObjectRgn, RGN_DIFF);
  161. // Compare the combine resulting
  162. bResult = EqualRgn(hTmpObjectRgn, hCompObjectRgn);
  163. DeleteObject(hTmpObjectRgn);
  164. }
  165. else
  166. {
  167. // Combine the source object region with the object region
  168. // If the combination result in a different region
  169. // The regions are overllaping and HitChecking is TRUE;
  170. CombineRgn(hCompObjectRgn, hCompObjectRgn, hSrcObjectRgn, RGN_DIFF);
  171. // Compare the combine resulting
  172. bResult = EqualRgn(hCompObjectRgn, hBoundingPoly);
  173. }
  174. */
  175. //释放目标物体资源
  176. free((void*)rgnData);
  177. DeleteObject(hSrcObjectRgn);
  178. return !bResult;
  179. }
  180. void cHitChecker::Destroy()
  181. {
  182. //如果原来就有区域数据,则把它删掉
  183. if(hBoundingPoly != NULL)
  184. {
  185. DeleteObject(hBoundingPoly);
  186. }
  187. }