本系列文章由 net_assassin 整理编写,转载请注明出处。
http://blog.csdn.net/net_assassin/article/category/1100363
到目前为止,我们能够在屏幕上绘制精灵,不过要制作游戏,这是远远不够的,仅仅只是开始而已。真正的游戏有许多精灵相互交互,例如子弹和火箭击中敌人的飞船造成爆炸。作者:net_assassin 邮箱: net_assassin@hotmail.com 期待着与志同道合的朋友们相互交流
碰撞检测是可继承到游戏中的最简单(也是最重要)的物理类型。
检测精灵碰撞主要有两种算法(或方法):边界框 及 基于距离的碰撞检测。
真正让一个游戏鹤立鸡群的是程序对碰撞的响应能有多好。
边界框碰撞检测:
关键在于识别两个精灵在屏幕上的位置,然后比较它们的边界框(或矩形),看是否重叠。
使用Windows API 函数
IntersectRect 来检测两个矩形是否有交集。
碰撞函数
更改sprite结构
//sprite structure
struct SPRITE
{
float x,y;
int frame, columns;
int width, height;
float scaling, rotation;
int startframe, endframe;
int starttime, delay;
int direction;
float velx, vely;
D3DCOLOR color;
SPRITE()
{
frame = 0;
columns = 1;
width = height = 0;
scaling = 1.0f;
rotation = 0.0f;
startframe = endframe = 0;
direction = 1;
starttime = delay = 0;
velx = vely = 0.0f;
color = D3DCOLOR_XRGB(255,255,255);
}
};
//bounding box collision detection
int Collision(SPRITE sprite1, SPRITE sprite2)
{
RECT rect1;
rect1.left = (long)sprite1.x;
rect1.top = (long)sprite1.y;
rect1.right = (long)sprite1.x + sprite1.width * sprite1.scaling;
rect1.bottom = (long)sprite1.y + sprite1.height * sprite1.scaling;
RECT rect2;
rect2.left = (long)sprite2.x;
rect2.top = (long)sprite2.y;
rect2.right = (long)sprite2.x + sprite2.width * sprite2.scaling;
rect2.bottom = (long)sprite2.y + sprite2.height * sprite2.scaling;
RECT dest; //ignored
return IntersectRect(&dest, &rect1, &rect2);
}
边界框演示程序:
基于距离的碰撞检测:
边界框碰撞检测产生相当精确的碰撞结果,而且非常快速。但有些情况下这种方法不能很好地适应,例如使用带有圆角的美工作品或非常复杂的形状。
在使用距离确定两个精灵是否碰撞时,我们必须计算每个精灵的中心点,计算精灵的半径(从中心点到边缘),然后检查两个中心点之间的距离。如果这个距离少于两个半径的和,那么就可以肯定两个精灵有重叠。
bool CollisionD(SPRITE sprite1, SPRITE sprite2)
{
double radius1, radius2;
//calculate radius 1
if (sprite1.width > sprite1.height)
radius1 = (sprite1.width * sprite1.scaling) / 2.0;
else
radius1 = (sprite1.height * sprite1.scaling) / 2.0;
//center point 1
double x1 = sprite1.x + radius1;
double y1 = sprite1.y + radius1;
D3DXVECTOR2 vector1(x1, y1);
//calculate radius 2
if (sprite2.width > sprite2.height)
radius2 = (sprite2.width * sprite2.scaling) / 2.0;
else
radius2 = (sprite2.height * sprite2.scaling) / 2.0;
//center point 2
double x2 = sprite2.x + radius2;
double y2 = sprite2.y + radius2;
D3DXVECTOR2 vector2(x2, y2);
//calculate distance
double deltax = vector1.x - vector2.x;
double deltay = vector2.y - vector1.y;
double dist = sqrt((deltax * deltax) + (deltay * deltay));
//return distance comparison
return (dist < radius1 + radius2);
}