Monday, May 2, 2016

xna - Collision Detection - Slide Around Sprite



I'm creating an RPG using XNA/C# and am trying to add some complicated collision detection code. I have the playable character 'Wizard' and when it collides with something, a method gets called in his class with the sprite which he collided with as a parameter.


Now what I want the wizard to do is be able to 'slide' around the sprite when he collides with (In this case it's a tree), both sprites are 8px x 8px (they are scaled up by x 8 when drawn to the screen). So far what I've done is find the co ordinates of each corner of both sprites and the co ordinates of the mid points of each side of both sprites and storing them as Vector2's.


Vector2 spriteTopLeft = new Vector2(sprite.X, sprite.Y);
Vector2 spriteTopRight = new Vector2(sprite.X + sprite.Width, sprite.Y);
Vector2 spriteBottomLeft = new Vector2(sprite.X + sprite.Height, sprite.Y + sprite.Height);
Vector2 spriteBottomRight = new Vector2(sprite.X + sprite.Width, sprite.Y + sprite.Height);

Vector2 wizardTopLeft = new Vector2(X, Y);
Vector2 wizardTopRight = new Vector2(X + Width, Y);
Vector2 wizardBottomLeft = new Vector2(X, Y + Height);

Vector2 wizardBottomRight = new Vector2(X + Width, Y + Height);

Vector2 spriteTopMid = new Vector2(spriteTopLeft.X + (sprite.Width / 2), spriteTopLeft.Y);
Vector2 spriteRightMid = new Vector2(spriteTopRight.X, spriteTopRight.Y + (sprite.Height / 2));
Vector2 spriteBottomMid = new Vector2(spriteBottomLeft.X + (sprite.Width / 2), spriteBottomLeft.Y);
Vector2 spriteLeftMid = new Vector2(spriteTopLeft.X, spriteTopLeft.Y + (sprite.Height / 2));

Vector2 wizardTopMid = new Vector2(wizardTopLeft.X + (Width / 2), wizardTopLeft.Y);
Vector2 wizardRightMid = new Vector2(wizardTopRight.X, wizardTopRight.Y + (Height / 2));
Vector2 wizardBottomMid = new Vector2(wizardBottomLeft.X + (Width / 2), wizardBottomLeft.Y);

Vector2 wizardLeftMid = new Vector2(wizardTopLeft.X, wizardTopLeft.Y + (Height / 2));

Then I'm comparing different corners of both sprites to decide which sides are being collided together, so wherever the wizard is on the top of the tree, to the left, right or underneath it. Next by using the midpoints of the sides of the 2 sprites, I'm calculating which way the wizard should slide.


For example, if the wizard in on the top of the tree, but on the right hand side of the top half, then it should slide around the right side of the tree. I've tried to show what I mean with the following image:


enter image description here


To try to achieve this, I've implemented this code:


    float leverage = 1.5f;
Vector2 temp = new Vector2(0, 0);

if (wizardBottomRight.Y <= spriteTopRight.Y + leverage && wizardBottomLeft.Y <= spriteTopLeft.Y + leverage)

{
//Top
if (wizardBottomMid.X <= spriteTopMid.X)
{
//Left
temp = new Vector2(-speed, 0);
}
else if (wizardBottomMid.X >= spriteTopMid.X)
{
//Top

temp = new Vector2(speed, 0);
}
}
else if (wizardTopRight.X <= spriteTopLeft.X + leverage && wizardBottomRight.X <= spriteTopLeft.X + leverage)
{
//Left
if (wizardRightMid.Y <= spriteLeftMid.Y)
{
//Top
temp = new Vector2(0, -speed);

}
else if (wizardRightMid.Y >= spriteLeftMid.Y)
{
//Bottom
temp = new Vector2(0, speed);
}
}
else if (wizardTopRight.Y >= spriteBottomRight.Y - leverage && wizardTopLeft.Y >= spriteBottomLeft.Y - leverage)
{
//Bottom

if (wizardTopMid.X <= spriteBottomMid.X)
{
//Left
temp = new Vector2(-speed, 0);
}
else if (wizardTopMid.X >= spriteBottomMid.X)
{
//Right
temp = new Vector2(speed, 0);
}

}
else if (wizardBottomRight.X >= spriteBottomLeft.X - leverage && wizardTopRight.X >= spriteTopLeft.X - leverage)
{
//Right
if (wizardLeftMid.Y <= spriteRightMid.Y)
{
//Top
temp = new Vector2(0, -speed);
}
else if (wizardLeftMid.Y >= spriteRightMid.Y)

{
//Bottom
temp = new Vector2(0, speed);
}
}

position += temp;

(The variable 'speed' is a float with the value 0.6, 'sprite' is the tree that gets passed into the method which the Wizard collides with)


So far this detection works 75% of the time, need to work on tweaking the leverage amount. At the moment the wizard sort of moves to the right/left and kinda jumps almost around the tree when walking in from the top or bottom and doesn't work correctly at all when walking in from the left/right.



Is this a good way of doing this? Or is there a better method? Also how would I get this code working correctly so that the wizard smoothly walks around the tree?


Thanks in advance!




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...