Jump to content

  • Log In with Google      Sign In   
  • Create Account

y = mx + b for sloped tiles


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
12 replies to this topic

#1 Kain5056   Members   -  Reputation: 456

Like
0Likes
Like

Posted 27 September 2013 - 09:56 AM

I'm trying to implement slopes in my first platform game in C++, and I seem to have some trouble.

I need to calculate the player's y position in a 45 degrees slope using the slope's size and coordinates and the player's x position.

I have found the equation y = m * x + b, but I'm not sure how to use it.

 

I need to find position.y using position.x, tile.x, tile.y, tile_size and player_size (both the player and the tiles are square so their width and their height are equal).

 

I know that m = ( y2 - y1 ) / ( x2 - x1 ) and b = y1 - m * x1

 

But I don't know how to find y1, y2, x1 and x2 based on the slope's degree.

 

I searched Google and found nothing, so if someone more experienced could help I would really appreciate it.

Thank you in advance. smile.png



Sponsor:

#2 frob   Moderators   -  Reputation: 21434

Like
2Likes
Like

Posted 27 September 2013 - 10:07 AM

How much math have you had?

 

The math of a line is often taught in middle school math before algebra, so if you needed to look it up it implies you may not have math math skills yet for this.

 

I'm worried that giving a reply in how to compute the values may not help if you don't have the requisite skills.


Check out my personal indie blog at bryanwagstaff.com.

#3 Kain5056   Members   -  Reputation: 456

Like
0Likes
Like

Posted 27 September 2013 - 11:03 AM

Even though I graduated more than a decade ago, I'm not really that good at math.

I'm willing to give it a try, though. The most I can lose is some of my time. smile.png

 

Here is what I figured out so far:

 

   float x , y1 , y2 , x1 , x2 , m , b;
    x = position.x + size - collision_box_position.x;
    y1 = Tile->y + tile_size;
    y2 = Tile->y;
    x1 = Tile->x + tile_size;
    x2 = Tile->x;
    m = ( y2 - y1 ) / ( x2 - x1 );
    b = y1 - m * x1;

    if( position.y + size >= m * x + b ) position.y = m * x + b - size;

 

With the above code it works quite nicely, but for some reason it is offset horizontally by the player's size. I tried adding and subtracting it, but it dod not work.



#4 Paradigm Shifter   Crossbones+   -  Reputation: 5379

Like
1Likes
Like

Posted 27 September 2013 - 11:12 AM

x = position.x + size - collision_box_position.x;

 

That looks wrong. It depends whether you are approaching the slope from the left or the right side, whether you want to adjust the x position by the player size or not (and whether it is an upwards or downwards slope too). EDIT: I suspect it works for approaching slopes from one direction but not the other, or that it works for upward slopes but not downwards ones.

 

It's probably best to have the logical sprite position to be in the middle at the players feet as well.


Edited by Paradigm Shifter, 27 September 2013 - 11:16 AM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#5 cdoty   Members   -  Reputation: 491

Like
0Likes
Like

Posted 27 September 2013 - 12:14 PM

slope = (y2 - y1) / (x2 - x1). Which gives you the number of y pixels to move for each x pixel.

 

For a 45 degree angle, the slope is 1 (1 pixel up for each pixel right)

 

So:

 

position.y = (tile.y + (tilesize - 1) + (position.x - tile.x) * slope) - playersize;

 

or 

 

position.y = (tile.y + (tilesize - 1) - (position.x - tile.x) * slope) - playersize / 2;

 

The first one positions the sprite using the top of the rectangle, the second one uses the center point of the character. Depending on how your tiles are designed, this may put you on top of a pixel.


Edited by cdoty, 27 September 2013 - 12:22 PM.

Check out Super Play, the SNES inspired Game Engine: http://www.superplay.info


#6 Paradigm Shifter   Crossbones+   -  Reputation: 5379

Like
0Likes
Like

Posted 27 September 2013 - 12:23 PM

And for any given angle theta, the slope is tan(theta). Note tan expects angles in radians though.


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#7 superman3275   Crossbones+   -  Reputation: 2061

Like
0Likes
Like

Posted 01 October 2013 - 06:33 PM

Don't have time to explain the basic functions up through Algebra I, but I can say this:

 

y = mx + b is just an equation for a line. It doesn't solve for anything, really. Just some context:

 

m is the slope of the line.

 

y / x are just used to represent y and x in a coordinate plane. They're fairly abstract, but you can solve for them if you have m, b, and either x or y.

 

y2 / y1 and all of those mean that they're numbers you need to solve the equation.


I'm a game programmer and computer science ninja ph34r.png!

Here's my 2D RPG-Ish Platformer Programmed in Python + Pygame, with a Custom Level Editor and Rendering System!

 

Here's my Custom IDE / Debugger Programmed in Pure Python and Designed from the Ground Up for Programming Education!

Want to ask about Python, Flask, wxPython, Pygame, C++, HTML5, CSS3, Javascript, jQuery, C++, Vimscript, SFML 1.6 / 2.0, or anything else? Recruiting for a game development team and need a passionate programmer? Just want to talk about programming? Email me here:

hobohm.business@gmail.com

or Personal-Message me on here smile.png!


#8 farmdve   Members   -  Reputation: 194

Like
0Likes
Like

Posted 02 October 2013 - 12:55 PM

How much math have you had?

 

The math of a line is often taught in middle school math before algebra, so if you needed to look it up it implies you may not have math math skills yet for this.

 

I'm worried that giving a reply in how to compute the values may not help if you don't have the requisite skills.

You'd be surprised by how many people have ADHD and are affected in such a way that they were never able to understand math. I myself struggle with simple addition and subtraction like 14.37 - 10.85, It's going to take me a while to do this in my head and the answer might be wrong in the end.

 

I also can't do fractions,equations, rational expressions, exponentiation and many more things, simply because I couldn't understand them waay back in middle school and earlier which affected me in later grades.

 

Sad to say, you will meet more people like this. They won't necessarily have ADD/ADHD, but they could be affected by something else.


Edited by farmdve, 02 October 2013 - 01:00 PM.


#9 Godmil   Members   -  Reputation: 744

Like
0Likes
Like

Posted 02 October 2013 - 01:29 PM

Don't think anyone mentioned that b is the starting point on the Y axis. So if the slope was flat (m=0), or if you hadn't gone any distance up or down the slope (x=0) the equation reduces to Y = b.


Edited by Godmil, 02 October 2013 - 01:30 PM.


#10 DekuTree64   Members   -  Reputation: 986

Like
0Likes
Like

Posted 02 October 2013 - 06:39 PM

Slope tile collision is deceptively difficult, depending on how many situations you want it to deal with. And indeed, there's very little info on the net about it. Particularly doing anything more than 45 degree tiles where you climb up with the corner of your collision box rather than the center/feet of the character.

 

One of these days I'll write an article on it... when I understand it better myself.

 

45 degree slopes, on the ground only (not ceiling) are probably doable for a relative newbie... I assume you already have solid tile collision working? What approach are you using, separate X and Y movement steps?

 

As for your line equation, for 45 degree tiles the slope is 1, so it cancels out... no multiplication is necessary. X and Y (within the tile) are always equal to eachother, either positively or negatively.

 

So assuming positive X is right, positive Y is down, and you're on a 45 degree slope tile where the bottom left is solid and top right is open... then to stand on the slope, figure your X position within the tile, and set Y within the tile equal to that. For the other direction (bottom right solid, top left open), set Y equal to tilesize - 1 - X. Notice the -1. That's one of the things that makes it so difficult. One direction is always off by 1 pixel from the other.

 

Another problem is that when walking up a slope onto flat ground, with your center point resting on the slope, then the bottom corner of your collision box will ruin into the "wall" of the flat ground tile before you get to the top of the slope.

 

Draw lots of diagrams and study the situations that come up when you're in the air, walking on the ground, walking up a slope, down a slope, whether there's a flat ground tile at the top/bottom of the slope, or a wall... lots of situations, and in my experience, there's no simple, elegant solution.



#11 Kain5056   Members   -  Reputation: 456

Like
0Likes
Like

Posted 05 October 2013 - 03:22 AM

Oh, I figured it out a few days ago, sorry I forgot to post it. wacko.png

bool entity::slope_collision_detection( tile * Tile )
{
    float y1 , y2 , x1 , x2 , m , b , x;
    y1 = Tile->y;
    y2 = Tile->y + tile_size;
    x1 = Tile->x;
    x2 = Tile->x + tile_size;
    m = ( y2 - y1 ) / ( x2 - x1 );

    if( Tile->tile_type == slope_right )
    {
        if( last_position.x + width - collision_box_position.x - FPS::FPS_control.last_time >= Tile->x + tile_size ) return false;
        m *= -1;
    }

    if( Tile->tile_type == slope_left )
    {
        if( last_position.x + collision_box_position.x + 1 + FPS::FPS_control.last_time <= Tile->x ) return false;
    }

    if( last_position.y + height - collision_box_position.y - 1 + FPS::FPS_control.last_time >= Tile->y + tile_size ) return false;

    b = y1 - m * x1;
    x = position.x + collision_box_position.x * m;


    if( position.y + height >= m * x + b + 1 )
    {
        on_ground = true;
        position.y = m * x + b - height + 1 - FPS::FPS_control.last_time;
        return true;
    }
    return true;
}

The additions and subtractions of 1 and FPS::FPS_control.last_time ( = time step ) are added so the sprite does not jitter, and for the slopes to line up perfectly to each other, so the sprite does not jump when traversing multi-tiled slopes. smile.png

The code works perfectly for me. smile.png


Edited by Kain5056, 05 October 2013 - 03:23 AM.


#12 farmdve   Members   -  Reputation: 194

Like
0Likes
Like

Posted 05 October 2013 - 03:57 AM

Use fixed timestep to avoid problems later on if a frame gets by some reason rendered even a few milliseconds slower than before.



#13 Kain5056   Members   -  Reputation: 456

Like
0Likes
Like

Posted 05 October 2013 - 04:14 AM

FPS::FPS_control.last_time is my delta time as seconds * 32. I also use it for the entities movement and collision detection, so I only include it here because the sprite jitters on the slope without it I'm not really sure what you mean above.

I'm also planning to add the options to enable Vertical Sync and FPS Lock at 60 FPS in the Options Menu. Does that help?

I don't really want to permanently lock the FPS, though, because I want to always test the performance with a build-n FPS counter.


Edited by Kain5056, 05 October 2013 - 04:27 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS