Coritani

Hi, I'm learning how to use collision detection in sprites, and I've decided to use Rectangles. Basically, I program the game to make a rectangle around each of the 2 sprites and, when I move the sprites via keyboard input, it moves the box with them.(

Now, I'm doing this to test collision detection. Heres the bit of code that doesn't work:

if(Sprite1box.Right == Sprite2box.Left)
{
Sprite1pos.X += 5;
Sprite1box.X += 5;
}

(Where Sprite1box = The rectangle aroudn the first sprite, Sprite2box = the rectangle around the 2nd sprite, and Sprite1pos is the vector of the 1st sprite)

This doesn't work - the sprite just moves right through the second sprite.

Now, I figured I must've done something wrong with the rectangles. But when I do:

if (Sprite1box.Bottom == Sprite2box.Top)
{
Sprite1pos.Y += -5;
Sprite1box.Y += -5;
}

It runs fine; the sprite doesn't go below the top of the Sprite2box.

What's wrong



Re: XNA Game Studio Express Rectangle collision detection help

Bill Reiss

I could probably use a little more detail of the code, but I'll give it a shot.

A couple of possibilities...one is that maybe your the bottom and top don't meet up exactly, and you're off by a pixel or 2, so you never get into your conditional logic. However more likely is that since Rectangles are value types, if you're doing this in a method and passing in the Rectangles as arguments you need to specify "ref" before the argument or any changes you make to it in the method will be discarded when the method completes.

Bill






Re: XNA Game Studio Express Rectangle collision detection help

ProfEclipse

I would agree with Bill as to your problem. I'm wondering, though, why you don't use the BoundingBox structure It has an Intersects method that will take care of this for you.

 





Re: XNA Game Studio Express Rectangle collision detection help

Micky D

It may not be a ref problem since it is already in an object.

I agree that it is probably the logic used to test for collision. Your code would only work if the boundaries exactly matched - which would only occur if the boxes velecity was 1.

A better way would be to compare the boundaries of the two rectangles for overlap ie. intersection. There was a Rectangle.Intersect() in plain .NET but not XNA.

Luckily there's a BoundingBox class in XNA that you could use, it's 3d but you could ignore the 3rd dimension.






Re: XNA Game Studio Express Rectangle collision detection help

Coritani

 ProfEclipse wrote:

I would agree with Bill as to your problem. I'm wondering, though, why you don't use the BoundingBox structure It has an Intersects method that will take care of this for you.


I should use BoundingBoxes, but I don't know how to make them.


Edit: I worked out how to make them, now I just gotta figure out how to move it with the sprite.




Re: XNA Game Studio Express Rectangle collision detection help

Ivel

i would be interested in hearing more about your solution to this problem.

I solved the problem by evaluating the X and Y bounds of each sprint, and changing the direction of them if they ever intersect (i can post the code later tonight if you'd like to see it) but i would prefer to use a bounding box. I tried the example in the help docs, but i found it to be confusing since it worked in 3d, yet i am looking for a 2d example.

I'm sure if i spent some more time on it i would have figured it out, but i wanted to see it work before heading off to bed last night :-)





Re: XNA Game Studio Express Rectangle collision detection help

Bill Reiss

This may help... if you create a BoundingRectangle struct that wraps the BoundingBox struct, it may make your 2D collision handling easier. Here is an example (you would want to add the other properties and methods you would need):

struct BoundingRectangle
{
public BoundingBox box;
public BoundingRectangle(Vector2 min, Vector2 max)
{
box.Min =
new Vector3(min, 0);
box.Max = new Vector3(max, 0);
}

public BoundingRectangle(Rectangle rect)
{
box.Min =
new Vector3(rect.X, rect.Y, 0);
box.Max = new Vector3(rect.X + rect.Width, rect.Y + rect.Height, 0);
}

public bool Intersects(BoundingRectangle rect)
{
return box.Intersects(rect.box);
}
}






Re: XNA Game Studio Express Rectangle collision detection help

Ivel

perfect. I like the idea of using the bounding box and will try to impliment what you have tonight.

If anyone is looking for a way to handle collisions w/o a boundingBox, here's what i did with my sprites. i also have logic here to adjust the speed, but not to exceed a certain value. (this is just tech demo code, so it aint the purdiest...)


/// <summary>
/// Checks to see if the two sprites have collided.
/// </summary>
private void CollisionCheck()
{
if (spritePosition.X > spritePosition2.X && spritePosition.X < spritePosition2.X + myTexture.Width)
{
AdjustSpriteSpeed();
}

if (spritePosition2.X > spritePosition.X && spritePosition2.X < spritePosition.X + myTexture.Width)
{
AdjustSpriteSpeed();
}

if (spritePosition.Y > spritePosition2.Y && spritePosition.Y < spritePosition2.Y + myTexture.Width)
{
AdjustSpriteSpeed();
}

if (spritePosition2.Y > spritePosition.Y && spritePosition2.Y < spritePosition.Y + myTexture.Width)
{
AdjustSpriteSpeed();
}
}

/// <summary>
/// This is used to adjust the speed of the sprite when it collides with another sprite
/// </summary>
protected void AdjustSpriteSpeed()
{
if ((spriteSpeed.X >= -200 && spriteSpeed.X <= 200) || (spriteSpeed2.X >= -200 && spriteSpeed2.X <= 200))
{
spriteSpeed.X *= -2;
spriteSpeed2.X *= -2;
}
else
{
spriteSpeed.X *= -1;
spriteSpeed2.X *= -1;
}
}






Re: XNA Game Studio Express Rectangle collision detection help

Ivel

btw, how do you get syntax highlighting in these forums





Re: XNA Game Studio Express Rectangle collision detection help

Ivel

ya know, never mind on that code posted above... I just change the origin of my sprites and found they do not function as expected.

to fulfill my promise of non a bounding box way of detecting a collision, i will fix it and repost.





Re: XNA Game Studio Express Rectangle collision detection help

Ivel

ok, second time's the charm.....



/// <summary>
/// Checks to see if the two sprites have collided.
/// </summary>
private void CollisionCheck()
{
if ((spritePosition.X > spritePosition2.X && spritePosition.X < spritePosition2.X + myTexture.Width) && (spritePosition.Y > spritePosition2.Y && spritePosition.Y < spritePosition2.Y + myTexture.Height))
{
AdjustSpriteSpeed();
}

if ((spritePosition2.X > spritePosition.X && spritePosition2.X < spritePosition.X + myTexture.Width) && (spritePosition2.Y > spritePosition.Y && spritePosition2.Y < spritePosition.Y + myTexture.Height))
{
AdjustSpriteSpeed();
}
}

/// <summary>
/// This is used to adjust the speed of the sprite when it collides with another sprite
/// </summary>
protected void AdjustSpriteSpeed()
{
//Adjust the X speed
if ((spriteSpeed.X >= -200 && spriteSpeed.X <= 200) || (spriteSpeed2.X >= -200 && spriteSpeed2.X <= 200))
{
spriteSpeed.X *= -2;
spriteSpeed2.X *= -2;
}
else
{
spriteSpeed.X *= -1;
spriteSpeed2.X *= -1;
}

//Adjust the Y speed
if ((spriteSpeed.Y >= -200 && spriteSpeed.Y <= 200) || (spriteSpeed2.Y >= -200 && spriteSpeed2.Y <= 200))
{
spriteSpeed.Y *= -2;
spriteSpeed2.Y *= -2;
}
else
{
spriteSpeed.Y *= -1;
spriteSpeed2.Y *= -1;
}
}







Re: XNA Game Studio Express Rectangle collision detection help

Coritani

Alright, I'm almost done. I've made the Boundingboxes and made them move with the sprites, but I have one last problem:

if(Sprite1box.Intersects(Sprite2box))
{

if (Sprite1box.Max.X < Sprite2box.Max.X)
{
Sprite1pos.X += -5;
Max.X += -5;
Min.X += -5;
}
if (Sprite1box.Min.X > Sprite2box.Min.X)
{
Sprite1pos.X += 5;
Max.X += 5;
Min.X += 5;
}
if (Sprite1box.Max.Y < Sprite2box.Max.Y)
{
Sprite1pos.Y += -5;
Max.Y += -5;
Min.Y += -5;
}
if (Sprite1box.Min.Y > Sprite2box.Min.Y)
{
Sprite1pos.Y += 5;
Max.Y += 5;
Min.Y += 5;
}

(Min and Max are the 2 points that make up the Boundingboxes; they are not the problem)

Now, that all works fine - almost. The problem is almost that it works too well! The top 2 'ifs' 'interfere' with the bottom 2, and vice versa. Basically, If I move the first sprite against the second sprite's left side, the first sprite moves up or down. Can anyone tell me a way to split up the four ifs so that if the X axis conditions are met, it does not check for the Y axis as well




Re: XNA Game Studio Express Rectangle collision detection help

Micky D

You could make it much easier by using a Vector2 that holds the sprite's velocity.

Let's say you want to move sprite1 to the right at 1 units-per-second until it collides with sprite2. When it does collide you want sprite1 to bounce back to the left - the way it came.

Vector2 velocity = new Vector2();
velocity.X = 1;
velocity.Y = 0;

// move sprite1
sprite1pos.X += velocity.X;
sprite1pos.Y += velocity.Y;

Now either move bounding box or just recreate it.
// test for intersection
if(Sprite1box.Intersects(Sprite2box))
{
velocity.X *= -1; // reverse velocity
sprite1pos.X += velocity.X; // sprite is now going in the other direction
sprite1pos.Y += velocity.Y;
.
.
.








Re: XNA Game Studio Express Rectangle collision detection help

Bill Reiss

Micky D wrote:

You could make it much easier by using a Vector2 that holds the sprite's velocity.

Let's say you want to move sprite1 to the right at 1 units-per-second until it collides with sprite2. When it does collide you want sprite1 to bounce back to the left - the way it came.

Vector2 velocity = new Vector2();
velocity.X = 1;
velocity.Y = 0;

// move sprite1
sprite1pos.X += velocity.X;
sprite1pos.Y += velocity.Y;

Now either move bounding box or just recreate it.
// test for intersection
if(Sprite1box.Intersects(Sprite2box))
{
velocity.X *= -1; // reverse velocity
sprite1pos.X += velocity.X; // sprite is now going in the other direction
sprite1pos.Y += velocity.Y;
.
.
.




Even easier, you don't need to set the X and Y separately, instead of this:

sprite1pos.X += velocity.X;
sprite1pos.Y += velocity.Y;

you can do this:

sprite1pos += velocity;

because Vector2 has a "+" operator defined which does exactly that.






Re: XNA Game Studio Express Rectangle collision detection help

Coritani

Excellent. I used this, and it works, except that now the sprite gets stuck inside the other sprite as it constantly reverses its velocity.