📄 bounds.cpp
字号:
#include "bounds.h"
template<class T>
T Min(T t1, T t2)
{
return (t1<t2 ? t1 : t2);
}
template<class T>
T Max(T t1, T t2)
{
return (t1>t2 ? t1 : t2);
}
const int INFINITY=9999999;
PhysicalSprite::PhysicalSprite(PIXELVALUE* pix, int pitch, int w, int h, PIXELVALUE transparent)
: top(new int[w]),
bottom(new int[w]),
left(new int[h]),
right(new int[h]),
width(w),
height(h),
x(0),
y(0)
{
CalculateBounds(pix,pitch,transparent);
}
PhysicalSprite::~PhysicalSprite()
{
delete[] top;
delete[] bottom;
delete[] right;
delete[] left;
}
void PhysicalSprite::CalculateBounds(PIXELVALUE* pix, int pitch, PIXELVALUE transparent)
{
for(int i=0;i<width;i++)
{
top[i]=INFINITY;
bottom[i]=-INFINITY;
}
for(int y=0;y<height;y++)
{
left[y]=INFINITY;
right[y]=-INFINITY;
PIXELVALUE* line = &pix[y*pitch];
for(int x=0;x<width;x++)
{
if (line[x]!=transparent)
{
left[y]=Min(left[y],x);
right[y]=Max(right[y],x);
top[x]=Min(top[x],y);
bottom[x]=Max(bottom[x],y);
}
}
}
}
// Compare an array of maxima with an array of minima.
// The indicies into the minima are adjusted by offset.
// delta is added to the minima before the compare.
// returns true if no maxima are >= the cooresponding minima + delta
static bool VectorsDisjoint(int *maxima, const int maximaCount,
int *minima, const int minimaCount,
const int offset, const int delta)
{
int count;
if (offset >= 0) {
maxima += offset;
count = Min(maximaCount - offset, minimaCount);
} else
{ // negative offset
minima -= offset;
count = Min(maximaCount, minimaCount + offset);
}
for (; count-- > 0; maxima++, minima++)
if ( *maxima >= (*minima + delta) )
return false;
return true;
}
// Checks for collision with another object, which is located at dx,dy relative
// to this one.
bool PhysicalSprite::DetectCollision(const PhysicalSprite& other)
{
// Calculate the offset between the sprites
int dx = other.x - x;
int dy = other.y - y;
// Check bounding rectangle intersection
if (width <= dx || height <= dy ||
other.width <= -dx || other.height <= -dy)
return false;
// Check the top of this sprite against the bottom of the other
if (VectorsDisjoint(other.bottom, other.width, top, width, -dx, -dy))
return false;
// Check the bottom of this sprite against the top of the other
if (VectorsDisjoint(bottom, width, other.top, other.width, dx, dy))
return false;
// Check the left of this sprite against the right of the other
if (VectorsDisjoint(other.right, other.height, left, height, -dy, -dx))
return false;
// Check the right of this sprite against the left of the other
if (VectorsDisjoint(right, height, other.left, other.height, dy, dx))
return false;
// Couldn't find any separation, so collision is reported.
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -