Skip to main content
GameDev.net gamedev.net
🔒 Locked

Rectangle Collition

Started by ravenx30 Apr 6, 2011 at 1:48 PM 4 replies 1.3k views
Original Post
ravenx30
ravenx30
Hey guys,

im having a problem with my collition result. there are blocks on my map which i want set as unwalkible. I have managed to do this by putting a rectangle around the block and the character then using intesect to determine collition. the test works but thats not the problem.

As when the collition does happen im unsure what to do as so far I have put the colltion in the directional keys so I know which way the charater is facing when the colltion happens. I set the posion opposite to the direction of the charecter when ther colliton occurs.

Problem is when the charater collides sometimes he doesn't get pushed back straight away so he still is colliding. and when I press another directional key that part of the code runs. for if he was stuck on the colltion moving from right to left then I pressed the up key that part of the code tells him to move down even know he is facing the east side of the block =/.

Ive tried hours to get this working and finding it really hard to fix any help would be appresiated my code for the directional keys is below. ps. using classes etc is behond me and not important for my project before you say it looks messy >< lol..



if (keyboardState.IsKeyDown(Keys.Left) || (gamepad1State.ThumbSticks.Left.X < 0f))
{
if (charBounds.Intersects(mBlock1))
{
skullPosition.X++;
}
else if (!charBounds.Intersects(mBlock1))
{

if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 1;
}
}
skullPosition.X -= skullSpeed;

}

}
else if (keyboardState.IsKeyDown(Keys.Right) || (gamepad1State.ThumbSticks.Left.X > 0f))
{
if (charBounds.Intersects(mBlock1))
{
skullPosition.X--;
}
else
{

if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 2;
}
}
skullPosition.X += skullSpeed;


}
}
else if (keyboardState.IsKeyDown(Keys.Up) || (gamepad1State.ThumbSticks.Left.Y > 0f))
{
if (charBounds.Intersects(mBlock1))
{
skullPosition.Y++;
}
else
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 3;
}
}

skullPosition.Y -= skullSpeed;


}
}
else if (keyboardState.IsKeyDown(Keys.Down) || (gamepad1State.ThumbSticks.Left.Y < 0f))
{
if (charBounds.Intersects(mBlock1))
{
skullPosition.Y--;
}
else
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 0;
}
}

skullPosition.Y += skullSpeed;


}
}



Basically the code is the same for each directional key doing the opposite on collition. its when the character doesn't get moved or gets stuck in the colltion and another key gets pressed is when I have the problem.

I really really apreshiate any help as tried so long to get this working and can't
Hunter-Killer
Hunter-Killer
I would suggest doing your collision code after the movement code. Not only will this be much faster and easier to follow but I think it will fix your problem too. Here is some pseudo code to show you what I mean.


// Create a temp vector to track where the player wants to move
Vector2 newPosition;
if (move_left_input)
newPosition.X--;
else if (move_right_input)
newPosition.X++;

if (move_up_input)
newPosition.Y++;
else if (move_down_input)
newPosition.Y--;

// Translate the old position by the movement vector to get the final position
newPosition += skullPosition;

// Run collision detection against the new position
Bounds newCharBounds = createBounds(newPosition);
if (!newCharBounds.Intersects(mBlock1))
{
// The new position is on a passable tile so let the player move
skullPosition = newPosition;
}
ravenx30
ravenx30

I would suggest doing your collision code after the movement code. Not only will this be much faster and easier to follow but I think it will fix your problem too. Here is some pseudo code to show you what I mean.


// Create a temp vector to track where the player wants to move
Vector2 newPosition;
if (move_left_input)
newPosition.X--;
else if (move_right_input)
newPosition.X++;

if (move_up_input)
newPosition.Y++;
else if (move_down_input)
newPosition.Y--;

// Translate the old position by the movement vector to get the final position
newPosition += skullPosition;

// Run collision detection against the new position
Bounds newCharBounds = createBounds(newPosition);
if (!newCharBounds.Intersects(mBlock1))
{
// The new position is on a passable tile so let the player move
skullPosition = newPosition;
}



Ill give it a go and let you know what happens give me 10mins
ravenx30
ravenx30
Modfied my code to do what you suggest but what happens now when the charater collides is the character gets stcuk to the block ie. doesn't move. he still animates but once collition has happened all movement is disabled. below is the modified code:



if (keyboardState.IsKeyDown(Keys.Left) || (gamepad1State.ThumbSticks.Left.X < 0f))
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 1;
}
}
lastSkullposition.X -= skullSpeed;



}
else if (keyboardState.IsKeyDown(Keys.Right) || (gamepad1State.ThumbSticks.Left.X > 0f))
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 2;
}
}
lastSkullposition.X += skullSpeed;



}
else if (keyboardState.IsKeyDown(Keys.Up) || (gamepad1State.ThumbSticks.Left.Y > 0f))
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 3;
}
}

lastSkullposition.Y -= skullSpeed;



}
else if (keyboardState.IsKeyDown(Keys.Down) || (gamepad1State.ThumbSticks.Left.Y < 0f))
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 0;
}
}

lastSkullposition.Y += skullSpeed;



}

//lastSkullposition += skullPosition;



if (!charBounds.Intersects(mBlock1))
{
skullPosition = lastSkullposition;
}



not identicle to your phudou code but does the same thing >> lastSkullposition is where you had new position. and the translating thing doesn't work.. as fails to show the character at all so commeted it out. I then tested for collition between the charater and the block and allowed movement when it wasn't colliding. Although it saved a bit of code I now have another problem of the charater being stuck once collition occurs
ravenx30
ravenx30
I think I know what you are tring to do and may have an idea. Create 4 'bool' type varibles (N,S,E,W) and if it collide equal the bool to true.

Put the bool in the key stament as follows:



if ((keyboardState.IsKeyDown(Keys.Left) || (gamepad1State.ThumbSticks.Left.X < 0f)) && (W != true)
{
if (charBounds.Intersects(mBlock1))
{
W = true;
}
else
{
// move
{
}
else
{
W = false;
}



This would disable the corrisonding direction when collition has occured but because I have 4 bools for each direction woun't affect other directions?
ravenx30
ravenx30
Sweeeet thanks to your insperation Ive managed to do it. using the below code:



if ((keyboardState.IsKeyDown(Keys.Left) || (gamepad1State.ThumbSticks.Left.X < 0f)) && (Eblock==false))
{
if (charBounds.Intersects(mBlock1) && (Wblock == false) && (Sblock == false) && (Nblock == false))
{
Eblock = true;
}
else
{

if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 1;
}
}
skullPosition.X -= skullSpeed;


}

}
else if ((keyboardState.IsKeyDown(Keys.Right) || (gamepad1State.ThumbSticks.Left.X > 0f)) && (Wblock == false))
{
if ((charBounds.Intersects(mBlock1)) && (Eblock == false) && (Sblock == false) && (Nblock == false))
{
Wblock = true;
}
else
{

if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 2;
}
}
skullPosition.X += skullSpeed;

}


}
else if ((keyboardState.IsKeyDown(Keys.Up) || (gamepad1State.ThumbSticks.Left.Y > 0f)) && (Sblock == false))
{
if ((charBounds.Intersects(mBlock1)) && (Nblock == false) && (Wblock == false) && (Eblock == false))
{
Sblock = true;
}
else
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 3;
}
}

skullPosition.Y -= skullSpeed;

}

}
else if ((keyboardState.IsKeyDown(Keys.Down) || (gamepad1State.ThumbSticks.Left.Y < 0f)) && (Nblock == false))
{
if ((charBounds.Intersects(mBlock1)) && (Sblock == false) && (Eblock == false) && (Wblock == false))
{
Nblock = true;
}
else
{


if (skullTimeSinceLastFrame > skullMilliSecondsPerFrame)
{
skullTimeSinceLastFrame -= skullMilliSecondsPerFrame;
++skullCurrentFrame.X;
if (skullCurrentFrame.X >= 3)
{
skullCurrentFrame.X = 0;
skullCurrentFrame.Y = 0;
}
}

skullPosition.Y += skullSpeed;

}

}

if (!charBounds.Intersects(mBlock1))
{
Eblock = false;
Wblock = false;
Nblock = false;
Sblock = false;
}



although not the most efficiant way to do it in the world it works perfectly and makes the block truely unwalkible by disabling the directioal key in question now I just need to replicate this to the whole grid of blocks lol...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.