12
\$\begingroup\$

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

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Aren't Vectors awesome? :D \$\endgroup\$ Feb 3, 2012 at 13:47

5 Answers 5

10
\$\begingroup\$

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:

slope

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))
\$\endgroup\$
5
  • \$\begingroup\$ after applying @SkimFlux fix plus your new formular plus some stupid things I overlooked it worked. thanks. \$\endgroup\$
    – xNidhogg
    Feb 3, 2012 at 15:33
  • \$\begingroup\$ Couldn't you use y=mx+b for a simpler calculation? \$\endgroup\$
    – ashes999
    Jun 1, 2012 at 21:26
  • \$\begingroup\$ @ashes999 I don't think it gets much simpler than what I wrote. What are m and b in your calculation? \$\endgroup\$
    – bummzack
    Jun 2, 2012 at 9:09
  • \$\begingroup\$ @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'. \$\endgroup\$
    – ashes999
    Jun 2, 2012 at 9:10
  • \$\begingroup\$ @ashes999 Yeah it has been a long time. Feel free to post this equation as an answer. \$\endgroup\$
    – bummzack
    Jun 2, 2012 at 10:11
8
\$\begingroup\$

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.

\$\endgroup\$
4
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – xNidhogg
    Feb 3, 2012 at 14:57
2
\$\begingroup\$

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

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – xNidhogg
    Feb 3, 2012 at 14:56
2
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – xNidhogg
    Feb 3, 2012 at 15:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .