Collision problem

Started by
2 comments, last by Fallen_Angel 19 years, 4 months ago
I'm having a problem at the moment with making my object (tank) collide with a wall as desired. At the moment I can get it so that the collision with the wall is detected. However, what I want to do is make it so that if the tank is moving in a 45 degree angle (up/right) and collides with the wall, the tank will continue moving up and just not to the right until it gets past the wall. At the moment, the second that my tank collides with the wall, all movement is halted altogether. Here's the code that I'm using to try and get this to work:

for (int i = 0; i < clsObjects.ObjectList.Count; i++)
{
	//Calculate level array position that object is on
	nPosX = (int)(clsObjects[0].PosX/5);
	if (nPosX < 0)
		nPosX += 9;
	else
		nPosX += 10;
	if (nPosX < 0)
		nPosX = 0;
	if (nPosX > 19)
		nPosX = 19;			
	nPosY = ((35 - (int)clsObjects[0].PosY)/5)-1;
	if (nPosY < 0)
		nPosY = 0;
	if (nPosY > 13)
		nPosY = 13;
	nLevelType = clsGlobal.GetCurrentLevel(nPosX, nPosY);
	//Calculate direction that object is moving
	if ((clsObjects.Direction < 90.0f) || (clsObjects.Direction > 270.0f))
		bUp = true;
	if ((clsObjects.Direction > 90.0f) && (clsObjects.Direction < 270.0f))
		bDown = true;
	if ((clsObjects.Direction < 360.0f) && (clsObjects.Direction > 180.0f))
		bLeft = true;
	if ((clsObjects.Direction > 0.0f) && (clsObjects.Direction < 180.0f))
		bRight = true;
	//Check if object is colliding with wall and prevent moving
	if (bUp)
	{
		nTempY = -1;
		if (clsObjects.Forward)
		{
			nTempY = nPosY + 1;
			if (nTempY > 13)
				nTempY = 13;
		}
		else if (clsObjects.Backward)
		{
			nTempY = nPosY - 1;
			if (nTempY < 0)
				nTempY = 0;						
		}
		if (nTempY != -1)
		{
			nLevelTypeMove = clsGlobal.GetCurrentLevel(nPosX, nTempY);
			if (nLevelTypeMove == 3)
				bMoveUp = false;
		}
	}
	if (bDown)
	{
		nTempY = -1;
		if (clsObjects.Forward)
		{
			nTempY = nPosY - 1;
			if (nTempY < 0)
				nTempY = 0;
		}
		else if (clsObjects.Backward)
		{
			nTempY = nPosY + 1;
			if (nTempY > 13)
				nTempY = 13;
		}
		if (nTempY != -1)
		{
			nLevelTypeMove = clsGlobal.GetCurrentLevel(nPosX, nTempY);
			if (nLevelTypeMove == 3)
				bMoveDown = false;
		}
	}
	if (bLeft)
	{
		nTempX = -1;
		if (clsObjects.Forward)
		{
			nTempX = nPosX;
			if (nTempX < 0)
				nTempX = 0;
		}
		else if (clsObjects.Backward)
		{
			nTempX = nPosX;
			if (nTempX > 19)
				nTempX = 19;
		}
		if (nTempX != -1)
		{
			nLevelTypeMove = clsGlobal.GetCurrentLevel(nTempX, nPosY);
			if (nLevelTypeMove == 3)
				bMoveLeft = false;
		}
	}
	if (bRight)
	{
		nTempX = -1;
		if (clsObjects.Forward)
		{
			nTempX = nPosX;
			if (nTempX > 19)
				nTempX = 19;
		}
		else if (clsObjects.Backward)
		{
			nTempX = nPosX;
			if (nTempX < 0)
				nTempX = 0;
		}
		if (nTempX != -1)
		{
			nLevelTypeMove = clsGlobal.GetCurrentLevel(nTempX, nPosY);
			if (nLevelTypeMove == 3)
				bMoveRight = false;
		}
	}
	//Check for forward movement
	if (clsObjects.Forward)
	{
		if ((bLeft && bMoveLeft) || (bRight && bMoveRight))
			clsObjects.PosX -= (float)Math.Sin(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedX * fSpeed;
		if ((bUp && bMoveUp) || (bDown && bMoveDown))
			clsObjects.PosY += (float)Math.Cos(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedY * fSpeed;
	}
	//Check for backwards movement
	if (clsObjects.Backward)
	{
		if ((bLeft && bMoveLeft) || (bRight && bMoveRight))
			clsObjects.PosX += (float)Math.Sin(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedX * fSpeed;
		if ((bUp && bMoveUp) || (bDown && bMoveDown))
			clsObjects.PosY -= (float)Math.Cos(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedY * fSpeed;
	}
}

I've been through this a few times and nothing is obviously standing out as the problem. Anyone got any ideas on this? Thanks
Advertisement
all you have to do is do the collison algoritm twice, once for the desired x motion and again for the y motion, that way if the x motion causes a colisson the y motion will be unafected

i cant follow you code but
take xpos and ypos
add motion to values
xnew=xpos+10
ynew=ypos+10

if thers no colion at xnew,ypos then
xpos=xnew

if thers no colion at xpos,ynew then
ypos=ynew
Quote:Original post by Kaze
all you have to do is do the collison algoritm twice, once for the desired x motion and again for the y motion, that way if the x motion causes a colisson the y motion will be unafected
i cant follow you code but
take xpos and ypos
add motion to values
xnew=xpos+10
ynew=ypos+10
if thers no colion at xnew,ypos then
xpos=xnew
if thers no colion at xpos,ynew then
ypos=ynew

I thought this is what I'm currently doing...well what I'm trying to do anyway, maybe I've got something wrong.

I'm calculating the new x,y positions here based on the direction that the tank is facing and whether it is moving forward or backwards:
if (bUp)	{		nTempY = -1;		if (clsObjects.Forward)		{			nTempY = nPosY + 1;			if (nTempY > 13)				nTempY = 13;		}		else if (clsObjects.Backward)		{			nTempY = nPosY - 1;			if (nTempY < 0)				nTempY = 0;								}		if (nTempY != -1)		{			nLevelTypeMove = clsGlobal.GetCurrentLevel(nPosX, nTempY);			if (nLevelTypeMove == 3)				bMoveUp = false;		}	}	if (bDown)	{		nTempY = -1;		if (clsObjects.Forward)		{			nTempY = nPosY - 1;			if (nTempY < 0)				nTempY = 0;		}		else if (clsObjects.Backward)		{			nTempY = nPosY + 1;			if (nTempY > 13)				nTempY = 13;		}		if (nTempY != -1)		{			nLevelTypeMove = clsGlobal.GetCurrentLevel(nPosX, nTempY);			if (nLevelTypeMove == 3)				bMoveDown = false;		}	}	if (bLeft)	{		nTempX = -1;		if (clsObjects.Forward)		{			nTempX = nPosX;			if (nTempX < 0)				nTempX = 0;		}		else if (clsObjects.Backward)		{			nTempX = nPosX;			if (nTempX > 19)				nTempX = 19;		}		if (nTempX != -1)		{			nLevelTypeMove = clsGlobal.GetCurrentLevel(nTempX, nPosY);			if (nLevelTypeMove == 3)				bMoveLeft = false;		}	}	if (bRight)	{		nTempX = -1;		if (clsObjects.Forward)		{			nTempX = nPosX;			if (nTempX > 19)				nTempX = 19;		}		else if (clsObjects.Backward)		{			nTempX = nPosX;			if (nTempX < 0)				nTempX = 0;		}		if (nTempX != -1)		{			nLevelTypeMove = clsGlobal.GetCurrentLevel(nTempX, nPosY);			if (nLevelTypeMove == 3)				bMoveRight = false;		}	}

And then only moving in the x or y directions based on the desired positions and the direction being moved here:
//Check for forward movement	if (clsObjects.Forward)	{		if ((bLeft && bMoveLeft) || (bRight && bMoveRight))			clsObjects.PosX -= (float)Math.Sin(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedX * fSpeed;		if ((bUp && bMoveUp) || (bDown && bMoveDown))			clsObjects.PosY += (float)Math.Cos(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedY * fSpeed;	}	//Check for backwards movement	if (clsObjects.Backward)	{		if ((bLeft && bMoveLeft) || (bRight && bMoveRight))			clsObjects.PosX += (float)Math.Sin(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedX * fSpeed;		if ((bUp && bMoveUp) || (bDown && bMoveDown))			clsObjects.PosY -= (float)Math.Cos(clsObjects.Direction * Math.PI / 180.0f) * clsObjects.SpeedY * fSpeed;	}

Maybe I'm doing it wrong though?
Well I've managed to slightly get this working after rewriting the code but there are still issues. For example, if my tank is moving up against a wall and then a wall appears above it, it will continue to move up and ignore the wall. Any suggestions as to why this is still failing?

Edit: Ignore this one. I've managed to get it working. The problem was actually being caused by my world space -> screen coordinates calculation being a bit off rather than my collision code.

[Edited by - Fallen_Angel on December 17, 2004 2:56:04 AM]

This topic is closed to new replies.

Advertisement