DirectX游戏编程入门——第二部分(游戏编程工具箱) ——精灵编程之碰撞检测

        本系列文章由 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);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值