cHitChecker.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:6k
- //////////////////////////////////////////////////////////////////////
- // cHitChecker.cpp: implementation of the cHitChecker class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "cHitChecker.h"
- #include <stdio.h>
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- cHitChecker::cHitChecker()
- {
- hBoundingPoly = NULL;
- }
- cHitChecker::~cHitChecker()
- {
- if(hBoundingPoly != NULL)
- {
- DeleteObject(hBoundingPoly);
- }
- }
- void cHitChecker::RemovePolyFromBound(LPPOINT lpPoints, int iCount, int iX, int iY)
- {
- // Use the combine Rgn API to remove a poly from the class internal region
- HRGN hRgnSrc = NULL;
- LPPOINT pStart = lpPoints;
- if(iX != 0)
- {
- for(int i=0;i<iCount;i++)
- {
- lpPoints->x = lpPoints->x + iX;
- lpPoints->y = lpPoints->y + iY;
- lpPoints++;
- }
- lpPoints = pStart;
- }
- hRgnSrc = CreatePolygonRgn(lpPoints, iCount, ALTERNATE);
- if(hRgnSrc == NULL)
- {
- DXTRACE_MSG("ERROR !");
- }
- CombineRgn(hBoundingPoly, hBoundingPoly, hRgnSrc, RGN_DIFF);
- DeleteObject(hRgnSrc);
- if(iX != 0)
- {
- for(int i=0;i<iCount;i++)
- {
- lpPoints->x = lpPoints->x - iX;
- lpPoints->y = lpPoints->y - iY;
- lpPoints++;
- }
- lpPoints = pStart;
- }
- }
- void cHitChecker::CreatePolygonBound(LPPOINT lpPoints, int nCount)
- {
- //使用区域API创建多边形边界区域
- Destroy();
- hBoundingPoly = CreatePolygonRgn(lpPoints, nCount, ALTERNATE);
- }
- BOOL cHitChecker::HaveHitted(cHitChecker *pHitCheck, int nX, int nY, int nSrcX, int nSrcY)
- {
- HRGN hSrcObjectRgn;
- HRGN hCompObjectRgn;
- BOOL bResult = FALSE;
- DWORD dwSize;
- UINT i = 0;
- RGNDATA* rgnData;
- //首先检测包围盒矩形,用来快速排除非碰撞的情形
- RECT rcObj;
- GetRgnBox(pHitCheck->hBoundingPoly,&rcObj);
- rcObj.top += nY; rcObj.bottom += nY;
- rcObj.left += nX; rcObj.right += nX;
- if(nSrcX!=0 && nSrcY!=0)
- {
- //将自己的多边形边界进行偏移
- OffsetRgn(hBoundingPoly, nSrcX, nSrcY);
- //判断目标的包围盒是否和自己的多边形边界相交
- if(RectInRegion(hBoundingPoly, &rcObj) == 0)
- {
- //不相交,则对自己的多边形边界进行反偏移,回到初始状态
- OffsetRgn(hBoundingPoly, -nSrcX, -nSrcY);
- return FALSE;
- }
- //对自己的多边形边界进行反偏移,回到初始状态
- OffsetRgn(hBoundingPoly, -nSrcX, -nSrcY);
- }
- else
- {
- //这是一步优化操作,因为nSrcX和nSrcY等于0,所以它可以节约上面几个函数的调用过程,
- if(RectInRegion(hBoundingPoly, &rcObj) == 0)
- return FALSE;
- }
- //进一步检测是否相交
- //首先拷贝一份目标区域的多边形边界数据
- dwSize = GetRegionData(pHitCheck->hBoundingPoly, sizeof(RGNDATA), NULL);
- rgnData = (RGNDATA*) malloc(dwSize);
- GetRegionData(pHitCheck->hBoundingPoly, dwSize, rgnData);
- hSrcObjectRgn = ExtCreateRegion(NULL, dwSize, rgnData);
-
- //加入偏移量
- OffsetRgn(hSrcObjectRgn, nX, nY);
- //重新获得目标区域的多边形边界数据
- dwSize = GetRegionData(hSrcObjectRgn, sizeof(RGNDATA), NULL);
- rgnData = (RGNDATA*) realloc(rgnData, dwSize);
- GetRegionData(hSrcObjectRgn, dwSize, rgnData);
-
- if(nSrcX !=0 && nSrcY !=0)
- {
- RGNDATA* rgnData2;
- //和上面的操作一样,拷贝一份边界多边形数据
- dwSize = GetRegionData(hBoundingPoly, sizeof(RGNDATA), NULL);
- rgnData2 = (RGNDATA*) malloc(dwSize);
- GetRegionData(hBoundingPoly, dwSize, rgnData2);
- hCompObjectRgn = ExtCreateRegion(NULL, dwSize, rgnData2);
-
- //加入偏移量
- OffsetRgn(hCompObjectRgn, nSrcX, nSrcY);
- bResult = TRUE;
- //遍历选取多边形边界的连续的两个顶点作为矩形区域。
- for(i=0;i<rgnData->rdh.nCount;i++)
- {
- memcpy(&rcObj, &rgnData->Buffer[i*sizeof(RECT)], sizeof(RECT));
- //相交判断
- if(RectInRegion(hCompObjectRgn, &rcObj) != 0)
- {
- bResult = FALSE;
- break;
- }
- }
- free(rgnData2);
- DeleteObject(hCompObjectRgn);
- }
- else
- {
- bResult = TRUE;
- for(i=0;i<rgnData->rdh.nCount;i++)
- {
- memcpy(&rcObj, &rgnData->Buffer[i*sizeof(RECT)], sizeof(RECT));
- if(RectInRegion(hBoundingPoly, &rcObj) != 0)
- {
- bResult = FALSE;
- break;
- }
- }
- }
-
- // Old stuff
- /*if(nSrcX !=0)
- {
- // Same copy for the region being tested
- dwSize = GetRegionData(hBoundingPoly, sizeof(RGNDATA), NULL);
- rgnData = (RGNDATA*) realloc(rgnData, dwSize);
- GetRegionData(hBoundingPoly, dwSize, rgnData);
- hTmpObjectRgn = ExtCreateRegion(NULL, dwSize, rgnData);
- //free((void*)rgnData);
-
- OffsetRgn(hTmpObjectRgn, nSrcX, nSrcY);
- OffsetRgn(hCompObjectRgn, nSrcX, nSrcY);
- CombineRgn(hCompObjectRgn, hCompObjectRgn, hSrcObjectRgn, RGN_DIFF);
- CombineRgn(hCompObjectRgn, hCompObjectRgn, hTmpObjectRgn, RGN_OR);
- // Combine the source object region with the object region
- // If the combination result in a different region
- // The regions are overllaping and HitChecking is TRUE;
- CombineRgn(hTmpObjectRgn, hTmpObjectRgn, hSrcObjectRgn, RGN_DIFF);
- // Compare the combine resulting
- bResult = EqualRgn(hTmpObjectRgn, hCompObjectRgn);
- DeleteObject(hTmpObjectRgn);
- }
- else
- {
- // Combine the source object region with the object region
- // If the combination result in a different region
- // The regions are overllaping and HitChecking is TRUE;
- CombineRgn(hCompObjectRgn, hCompObjectRgn, hSrcObjectRgn, RGN_DIFF);
- // Compare the combine resulting
- bResult = EqualRgn(hCompObjectRgn, hBoundingPoly);
- }
- */
- //释放目标物体资源
- free((void*)rgnData);
- DeleteObject(hSrcObjectRgn);
- return !bResult;
- }
- void cHitChecker::Destroy()
- {
- //如果原来就有区域数据,则把它删掉
- if(hBoundingPoly != NULL)
- {
- DeleteObject(hBoundingPoly);
- }
- }