Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've been trying to modify some slope code from an example I've found but I've come across an issue the way the method is designed it attaches the current slope and then based off that slope determines if the character is on it or not.

 protected CollisionPath attachedPath;

The issue with this though is when you try and lay down several slopes to make one continuous slope it doesn't work properly as this piece of code kicks in and makes you fall off the current slope you are standing on.

if (position.X < attachedPath.MinimumX || position.X > attachedPath.MaximumX)
{
    attachedPath = null;
}

While this isn't the case when you jump from one slope to another. I've tried to adapt the code used for jumping to one slope to another to solve the issue to no avail. The method in its entirety is below. any help with this would be really appreciated.

private void HandleSlopeCollisions( GameTime gameTime)
{
    collisionPaths = level.collisionPaths;
    float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

    if (velocity.Y >= 0)
    {
        if (attachedPath != null)
        {
            isOnGround = true;

            position.Y = attachedPath.InterpolateY(position.X);
            velocity.Y = 0;

            if (position.X < attachedPath.MinimumX || position.X > attachedPath.MaximumX)
            {
                attachedPath = null;
            }
        }
        else
        {
            Vector2 footPosition = position;
            Vector2 expectedFootPosition = footPosition + velocity * elapsed;

            CollisionPath landablePath = null;
            float landablePosition = float.MaxValue;

            foreach (CollisionPath path in collisionPaths)
            {
                if (expectedFootPosition.X >= path.MinimumX && expectedFootPosition.X <= path.MaximumX)
                {
                    float pathOldY = path.InterpolateY(footPosition.X);
                    float pathNewY = path.InterpolateY(expectedFootPosition.X);

                    if (footPosition.Y <= pathOldY && expectedFootPosition.Y >= pathNewY && pathNewY < landablePosition)
                    {
                        landablePath = path;
                        landablePosition = pathNewY;
                    }
                }
            }

            if (landablePath != null)
            {
                velocity.Y = 0;
                footPosition.Y = landablePosition;
                attachedPath = landablePath;


                position.Y = footPosition.Y;
            }
        }
    }
    else
    {
        attachedPath = null;
    }
}
share|improve this question

1 Answer 1

up vote 0 down vote accepted

Are your slopes perfectly in line such that one starts exactly after the other slope? If so, try overlapping them. Overlapping collision surfaces is a very common technique to avoid problems such as yours.

EDIT: You must change your logic a little bit with the above. In the above case, two surfaces will report collisions at some point. Simply add all the surfaces to an array (or stack) and when the array/stack reaches 0, the character should fall.

EDIT2: Something like this: (Note the name of the variables... the code is NOT going to work right off the bat, you will have to declare variables/containers etc.)

private void HandleSlopeCollisions( GameTime gameTime)
{
    collisionPaths = level.collisionPaths;
    float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

    if (velocity.Y >= 0)
    {
        if (attachedPathArray.size() > 0)
        {
            isOnGround = true;

            for (unsigned int i = 0; i < attachedPathArray.size(); i++) // convert to foreach
            {
                position.Y = attachedPathArray[i].InterpolateY(position.X);
                velocity.Y = 0;

                if (position.X < attachedPathArray[i].MinimumX || position.X > attachedPathArray[i].MaximumX)
                {
                    attachedPathArray.remove(i);
                    --i; // otherwise we would skip a path because the size just decreased
                }              
            }            
        }
        else
        {
            Vector2 footPosition = position;
            Vector2 expectedFootPosition = footPosition + velocity * elapsed;

            CollisionPath landablePath = null;
            float landablePosition = float.MaxValue;

            foreach (CollisionPath path in collisionPaths)
            {
                if (expectedFootPosition.X >= path.MinimumX && expectedFootPosition.X <= path.MaximumX)
                {
                    float pathOldY = path.InterpolateY(footPosition.X);
                    float pathNewY = path.InterpolateY(expectedFootPosition.X);

                    if (footPosition.Y <= pathOldY && expectedFootPosition.Y >= pathNewY && pathNewY < landablePosition)
                    {
                        landablePathArray.Add(path);
                        landablePosition = pathNewY;
                    }
                }
            }

            if (landablePathArray.size() > 0)
            {
                velocity.Y = 0;
                footPosition.Y = landablePosition;
                attachedPath = landablePathArray[?]; // which one would you select in the array? up to you, I can't tell from your code


                position.Y = footPosition.Y;
            }
        }
    }
    else
    {
        attachedPath = null;
    }
}
share|improve this answer
    
Tried doing that, didn't work unfortunately –  dbomb101 Oct 14 '11 at 17:59
    
See my additional edit –  Samaursa Oct 14 '11 at 18:21
    
Kind of unclear about how you would do the check on the array, do you mind elaborating ? –  dbomb101 Oct 14 '11 at 19:08
    
See my additional Edit2 –  Samaursa Oct 15 '11 at 3:03
    
I've tried that method but due to how the code is structured the entire path disappears the moment it runs. I think I found an alternative solution though –  dbomb101 Oct 15 '11 at 10:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.