# 45° Slopes in a Tile based 2D platformer

I want to have simple 45° slopes in my tile based platformer, however I just cant seem to get the algorithm down. Please take a look at the code and video, maybe I'm missing the obvious?

//collisionRectangle is the collision rectangle of the player with
//origin at the top left and width and height
//wantedPosition is the new position the player will be set to.
//this is determined elsewhere by checking the bottom center point of the players rect
if(_leftSlope || _rightSlope)
{
//Test bottom center point
var calculationPoint = new Vector2(collisionRectangle.Center.X, collisionRectangle.Bottom);
//Get the collision rectangle of the tile, origin is top-left
Rectangle cellRect =
_tileMap.CellWorldRectangle(
_tileMap.GetCellByPixel(calculationPoint));
//Calculate the new Y coordinate depending on if its a left or right slope
//CellSize = 8
float newY = _leftSlope
? (calculationPoint.X % CellSize) + cellRect.Y
: (-1 * (calculationPoint.X % CellSize) - CellSize) + cellRect.Y;
//reset variables so we dont jump in here next frame
_leftSlope = false;
_rightSlope = false;
//now change the players Y according to the difference of our calculation
wantedPosition.Y += newY - calculationPoint.Y;
}


Video of what it looks like: http://youtu.be/EKOWgD2muoc

• Aren't Vectors awesome? :D Feb 3, 2012 at 13:47

From what I understand reading your question, you want to calculate the correct Y position, given a X position of the player. This is rather trivial. Have a look at this image: Assuming your slope-tile is at a given position x,y (origin is bottom left as in the image). You have the player position x1 and the width and the height of the sloped tile (u, v). x, y and x1 are world coordinates.

Given these parameters, your players Y-position (y1) would be:

y1 = y + (x1 - x) * (v / u)


If you're only dealing with 45 degree angles, then it gets even simpler:

y1 = y + (x1 - x)


If the slope is the other way round, it's:

y1 = y + (v - (x1 - x))

• after applying @SkimFlux fix plus your new formular plus some stupid things I overlooked it worked. thanks. Feb 3, 2012 at 15:33
• Couldn't you use y=mx+b for a simpler calculation? Jun 1, 2012 at 21:26
• @ashes999 I don't think it gets much simpler than what I wrote. What are m and b in your calculation? Jun 2, 2012 at 9:09
• @bummzack m is your slope (1 for a 45-degree slope downward, -1 for upward) and b would be the intercept on the x-axis. Grade 9 algebra. Just sayin'. Jun 2, 2012 at 9:10
• @ashes999 Yeah it has been a long time. Feel free to post this equation as an answer. Jun 2, 2012 at 10:11

Although this is already answered, allow me to offer another equation: y = mx + b, where y is the coordinate calculated, m is the slope (-1 for down at 45 degrees, 1 for up at 45 degrees), and b is the y-intercept -- the y-coordinate where x=0.

This allows you slightly more flexibility; you can change m to calculate a different slope other than 45-degrees. For example, an m of pi/3 gives you a slope of 30 degrees.

You may find a lot of value in this site: http://info.sonicretro.org/Sonic_Physics_Guide

Specifically for what you are looking for check out the Solid Tiles: Slopes and Curves section. It basically shows you how it is believed this was accomplished in the early Sonic games.

• interesting read, but too complex. This kind of slope is the only one I want, thus should simplify the solution. A height map/sensor/scanner system would be overkill for this. Thanks for digging up the link, though. Feb 3, 2012 at 14:57

You might want to look into the Seperate Axis Theorm, It will solve your slope issue, but it does require quite a bit of maths and the theory itself takes a while to get your head round. I've linked you to a tutorial and a book which explains it better

metanetsoftware Tutorial

Real-Time-Collision-Detection

• thats too much, imo. This is a highly simplified case and there'd be no need for other uses of SAT. Thanks for taking the time to pull up the links, though. Feb 3, 2012 at 14:56

I think you either have an off-by-one error somewhere else, or you aren't setting _leftSlope/_rightSlope flags at the right time. This code does not touch the X movement at all, but that seems to be your problem in the video.

You should check if those flags are triggered at all. Then check your horizontal collision detection: you don't want it to trigger on a slope.

• oh god right. I actually dont want either horizontal or vertical collision detection when this happens. I totally forgot to disable that. Looks somehow better now, but not done yet. Thanks. Feb 3, 2012 at 15:24