📄 ps.cpp
字号:
#include <windows.h>
#include "ps.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);
}
PhysicalSprite::PhysicalSprite(PIXELVALUE* pix, int w, int h,
PIXELVALUE transparent)
: width(w),
height(h),
x(0),
y(0)
{
CalculateBitArray(pix,transparent);
}
PhysicalSprite::~PhysicalSprite()
{
delete[] bitarray;
}
void PhysicalSprite::CalculateBitArray(PIXELVALUE* pix,
PIXELVALUE transparent)
{
groups_number = width/32;
int extra=width%32;
if (extra != 0) groups_number++;
bitarray=new unsigned[height*groups_number];
for(int i=0;i<height;i++)
{
int base=i*groups_number;
int basepix = i*width;
for(int k=0;k<groups_number;k++)
{
// Initialize the integer bit array, before using it.
bitarray[base+k]=0;
for(int j=k*32;j<width && j<(k+1)*32;j++)
{
// Determine if the pixel is solid or transparent
bool solid = (pix[basepix+j] != transparent);
// Shift the bit array left by 1
bitarray[base+k] <<= 1;
// Set the lowest bit to this pixel's value
bitarray[base+k] |= (solid ? 1 : 0);
}
}
if (extra!=0)
bitarray[base+groups_number-1]<<=(32-extra);
}
}
unsigned PhysicalSprite::GetBitArray(int x, int y) const
{
// Check vertical bounds
if (y<0 || y>=height) return 0;
// Prepare calculated values.
int gx = x / 32;
int extra = x % 32;
int base = y * groups_number;
// If the position is 32 bit aligned, simply return the value
if (extra == 0) return bitarray[base+gx];
// If the horizontal position is invalid, return 0
if (gx < 0 || gx >= groups_number) return 0;
// Take the bits from the value to the left of this position
unsigned result = bitarray[base+gx] << extra;
// If no other value is available (right edge) return what we've got
if (gx+1 >= groups_number) return result;
// Add the bits from the value to the right of this position
return result | (bitarray[base+gx+1] >> (32 - extra));
}
bool PhysicalSprite::DetectCollision(const PhysicalSprite& other)
{
// Calculate the other sprite's offset relative to this one.
int ox = other.x - x;
int oy = other.y - y;
// Calculate the intersection rectangle
// Remember that the coordinates are relative to the current sprite.
RECT isect;
isect.left = Max(ox,0);
isect.right = Min(ox+other.width,width);
isect.top = Max(oy,0);
isect.bottom = Min(oy+other.height,height);
// See if the intersection rectangle is valid (width and height > 0)
// If the rectangle is not valid, there is no collision
if (isect.right<isect.left || isect.bottom<isect.top) return false;
// Width of the rectangle
int bits_to_check = isect.right - isect.left;
// Height of the rectangle
int rows_to_check = isect.bottom - isect.top;
int groups_to_check = bits_to_check / 32;
int extra = bits_to_check % 32;
if (extra != 0) groups_to_check++;
for(int i=0;i<rows_to_check;i++)
{
int row=isect.top+i;
int group = groups_to_check;
// Check in groups of 32 pixels
for(int j=isect.left;j<=isect.right;j+=32)
{
unsigned bits1=GetBitArray(j,row);
unsigned bits2=other.GetBitArray(j-ox,row-oy);
if ((bits1 & bits2) != 0) return true;
}
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -