Jump to content
  • Advertisement
Sign in to follow this  
Zmurf

Smooth movementy along walls.

This topic is 4700 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using the following code to stop my character in an FPS from going through walls.
void CPlayer::Collision(){
	double sh, ch, X, Z, x, y, z;

	for(double j = 0; j < 360; ++j){
		sh = sin(j * DEGTORAD);
		ch = cos(j * DEGTORAD);

		X = m_X + 4.0 * ch;
		Z = m_Z + 4.0 * -sh;

		for(int i = 0; i < m_Walls->Count(); ++i){
			m_Walls->GetXYZ(i, x, y, z);
			if ((X > x && X < x + 16.0)
				&& (Z > z - 16.0 && Z < z)){
				sh = sin((m_DirH + 180) * DEGTORAD);
				ch = cos((m_DirH + 180) * DEGTORAD);

				m_X -= m_Speed * -ch;
				m_Z -= m_Speed * sh;

				sh = sin((m_DirH - 90) * DEGTORAD);
				ch = cos((m_DirH - 90) * DEGTORAD);

				m_X -= m_Strafe * -ch;
				m_Z -= m_Strafe * sh;

				}
			}
		}
	}
}
It works by first updating the x,z of the character, then, if he's collided with a wall, they move the x,z back and re-render. This works resonably well except that, once the character hits the wall he just stops. I want him to slide along the wall if hes facing diagonally at the wall. IE: | /| | | || | | O | It's kinda hard to visualise but maybe you can understand what i'm trying to achieve, does anyone know how to do this? I don't want to totally recode my collision system though unless it's totally necessary.

Share this post


Link to post
Share on other sites
Advertisement
First, don't move back and re-render, test first if you're going to hit a wall, and don't render to begin with if you are.

As for your problem, if updating z would put the character through a wall, you can still test and possible update y and vice versa.

Share this post


Link to post
Share on other sites
From your code it looks like your player is a circle and your walls are square tiles. Here's some code based on that assumption that you might try - you can just comment yours out and drop this in, and see if it works (no guarantees):


void CPlayer::Collision(){
double radius = 4.0;

for(int i = 0; i < m_Walls->Count(); ++i){
m_Walls->GetXYZ(i, x, y, z);
double minx = x;
double maxx = minx + 16.0;
double maxz = z;
double minz = maxz - 16.0;

double cx = m_X;
if (cx < minx) {
cx = minx;
} else if (cx > maxx) {
cx = maxx;
}
double cz = m_Z;
if (cz < minz) {
cz = minz;
} else if (cz > maxz) {
cz = maxz;
}

// The following assumes that although the player circle may be intersecting
// the wall, the player center is outside the wall. This is a reasonable
// assumption if the player velocity is not too great.
double dx = m_X-cx;
double dz = m_Z-cz;
double length = sqrt(dx*dx+dz*dz);
if (length < radius) {
dx /= length;
dz /= length;
double dist = radius - length + 0.01;
m_X += dx * dist;
m_Z += dz * dist;
}
}
}

Share this post


Link to post
Share on other sites
thanks thats perfect, i will try and make it so it checks if it will hit the wall, and then move it the position is empty

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!