# How to Prevent Sticking to Overhead Slopes

I am having an issue with overhead slopes in my 2D platformer.

I implement slopes using a LineSegment class. My player sprite has a spine attribute which is just a line segment from the midtop of his bounding rect to its midbottom. If this spine ever intersects a slope's line segment, the sprite is adjusted upwards or downwards so that his midtop or midbottom is at the intersection point. To determine which direction to adjust, I look at where the previous bounding rect's center is in relation to this intersection point.

def collide_with_slopes(sprite, slopes):

# create midline for the sprite
spine = LineSegment(sprite.game, sprite.midtop, sprite.midbottom)

# check if midline intersects any slope
slopes = [slope for slope in slopes if spine.intersects_segment(slope)]

if slopes:
slope = slopes[0]
intersection_point = spine.intersects_segment_at_point(slope)

# sprite above slope
if sprite.previous_bounding_rect.centery < intersection_point.y:

sprite.on_slope = True
sprite.pos.y = intersection_point.y - sprite.bounding_rect.height/2
sprite.vel.y = 0

# sprite below slope
elif sprite.previous_bounding_rect.centery > intersection_point.y:

sprite.on_slope = False
sprite.pos.y = intersection_point.y + sprite.bounding_rect.height/2 + 1
sprite.vel.y = 0

elif not slopes:
sprite.on_slope = False


This approach works well for slopes under the player, but I am having an issue with overhead slopes.

They work fine when the player jumps without horiztonal movement.

The problem is when the player is moving in the same direction that the overhead slope descends.

The sprite sticks to the ceiling and glides down the slope as if zip-lining.

I believe the problem is that even after slope resolution, if the player is pressing right, the sprite's new position will still be intersecting the slope on the subsequent frame, causing the slope code to keep readjusting the midtop point to be on the slope.

How can I fix this issue?

I have tried adjusting the sprite down a few extra pixels upon upward collision with a slope, but the result looks and feels bad.

I have also tried decomposing the update to my position into its x and y component, and only checking for slope intersections after one or the other. This did not solve the issue.

What I usually do when it comes to collision-detection is to first add the x velocity to the position then check if that is intersecting. If it is, set the x velocity to 0. Then do the same for y only.

if sprite.pos + sprite.vel.y intersects line:
sprite.vel.y = 0

if sprite.pos + sprite.vel.x intersects line:
sprite.vel.x = 0

sprite.pos += sprite.vel