📄 chitchecker.cpp
字号:
//////////////////////////////////////////////////////////////////////
// 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);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -