best practices to define terrain (polygons with slopes)

In order to keep a player “stuck” to the ground.

As it stands, I get contact when the player lands, determine the distance ratio for the vertex the player is on.

The issue is, when crossing to the next vertex, the player will go into an airborne state (or just follow the same path walking through the air).

I’ve looked to how others have handled similar problems, and it seems to be one of those that people keep close to the vest.

I figured there are three possible ways to tackle the issue, and while I try to implement these (or the one that works best), I was hopeful that others might be willing to give some insights into which might be best, or if these are not well thought out. (I wouldn’t bother asking if it weren’t for the limited time I get to work on the game).

Anyway;

option 1: When I loading the map polygons, get the vertex that would be walk-able, get the start and end points for that vertex loaded into an array.
This would wind up with an array of point vectors and when the player exits the current vertex it would grab the next point to determine the direction of the vertex.

The foreseeable issue with this is to determine whether the polygons are actual neighbors with a common start point or if its a gap in the terrain that would lead to a drop.

option 2: Would be to explicitly define, in an array of arrays of points that would define the ground segments, when the player lands on a segment of ground it would figure out which array it belongs to and if they go past the first or last point in that array that they would drop (unless its a wall).

This is a more brute force approach, and would probably be tedious to define, perhaps I could use custom properties in tiled to define that…

option 3: I would keep the polygons for collision detection, but then, use polylines over the walk-able terrain, then it seems it would be simple to get the next points once the player goes beyond the current line segment.

The only issue I have with this is it seems a bit redundant.

Well, as I was writing this, it seems clear to me now that option 3 is going to be the best bet and the simplest to implement, so I’ll try that one first…

any comments on these approaches is still appreciated though, so I’ll post it anyway.

Thanks, from the neighborhood novice.

In case you mean 3d terrain:

You could drop your triangles in a spatial data structure of any kind and then get the nearest ones and do ray to triangle collision to determine the intersection point.

This could be overkill, but it handles all kinds of terrain (split/irregular structure)

Assuming 3D, I agree with VaTTeRGeR. If you do this it’ll be a bottle neck though, so if I remember right I found this to be faster: http://pastebin.com/pS9Cg9Za (if not then I’m not sure why I chose it :-\ )

3D games also use Inverse Kinematic (IK) Solvers to make sure the feet look planted on the ground, otherwise they’d clip through.

If the game is 2D why can’t you just test the terrain polygon’s edges?

Thanks,

it’s actually for 2d, and I’ve been using the intersector class for collision detection, specifically the overlapconvexpolygon, for the narrow phase collision detection.

I had been thinking of using the nearestsegmentpoint, but it seemed more about how to keep the player on the current linesegment than in finding the neighboring polygon (if its there)

Thanks also, I’m still too much of a noob at this to try with 3d games, and I don’t really want to spend the next decade to have something playable that I wouldn’t be embarrassed to put out there.

I do test the edges, the issue is testing for the polygons neighbors, given other issues I’ve had in the past, I knew I would accidentally uncover some edge cases where things would break down. That’s why I was trying to think of a way that would be easiest to sort the relevant points, because from there its just a matter of getting current points and then getting the next one as appropriate.

I’d post code to demonstrate, but at the moment, things are quite ugly, and was going to get the player movement down before refactoring things to be more readable.

I can kinda imagine what your game looks like now,
but it would be good to see an actual screenshot, no matter how unfinished it looks. :stuck_out_tongue:

Sure, Im at work, but it’s not that I have any qualms about posting it… I’d even put all the code that gets executed at the moment, I have a fair bit more written but I was using box2d originally, but when I couldn’t get the movement physically real, I gutted boxed out of the project to make my own system that works how I like platform games to feel.

So, I’ll get some screens hots this evening. I might as well post the solution I’m working on… I don’t make fast progress because I only get a hand full of hours to spare to that in any given week.

Anyway, took a bit longer than I had hoped, but heres the screen shot.

I know, it looks like nothing, I turned off the graphics to make sure that the polygon outlines were clear.

So, the issue was that, in this screenshot, going down the hill was fine because the collision with the next angle would be detected, and start moving on the path, if climbing up a hill, would keep following the path through the air until another collision changed the movement.

Now, by adding in the polylines, I have a simple way to check all connected polygon edges to know, if the player walks past the edge, it’s time to fall, and it was that or jumping alone that I wanted to put the player into airborne state.

The text is just more or less random things that I figured would help me debug some stuff… not really a fan of the fonts there, but can’t complain about the price.

Just build a representation of the floor of line-segments and represent the player as an line cross or any other shape.
If the player doesn’t collide he’s falling.
If the player collides, determine what line he collided with and determine the lines normal vector

(nx,ny) = (-(l.x2-l.x1),l.y2-l.y1)

For this specific formula to work, your line-endpoints must be sorted so that the left point is (x1,y1) the normal-vector will be flipped 180 degrees otherwise.

Let’s say the player is going left or right while colliding, this means he either travels parallel to the line or cannot go further up because it’s too steep
You need to calculate the tangent vector that fits your desired movement direction, it’s either

(tx,ty) = (-nx,ny)

or

(tx,ty) = (nx,-ny)

after you have that just move the player along that vector by doing

(px,py) += (tx,ty).normalize().scale(speed).scale(deltaTime)

If it’s steep and the player should be falling, just move him like above but with the falling speed.

The names in the text do not fit the names in the picture!

First, thanks alot, thats actually how I got the movement going so far, but just needed to brainstorm on a method of getting the next line segment once crossed.

That’s why I had decided to use polylines as an overlay on the ground lines (which I will be able to add complexity to, I had just made a basic map so that I can test as I go through the process), this way I can easily sort the lines from left to right, and better, sort it into an array where each “block” of terrain can have an array of line segments. Then, on collision I get the correct block and line segment, and once I pass the bounds of the one line segment I look for the next line segment for the new angle.

The way I get the direction to move is just

direction = lineEnd.sub(lineStart);
direction.nor();

(sub is subtraction, nor is normalize, which is the same code as you put)

[quote]Let’s say the player is going left or right while colliding, this means he either travels parallel to the line or cannot go further up because it’s too steep
You need to calculate the tangent vector that fits your desired movement direction, it’s either

(tx,ty) = (-nx,ny)

or

(tx,ty) = (nx,-ny)

after you have that just move the player along that vector by doing

(px,py) += (tx,ty).normalize().scale(speed).scale(deltaTime)

If it’s steep and the player should be falling, just move him like above but with the falling speed.
[/quote]
This was going to be the next step, once I get the direction of movement correct, I was gonna have to think of a way to scale the speed going up or down slopes based on the angle, and probably a threshold where the player would slide down too steep of a slope.

btw, I have the diamond shaped polygon for collision detection, and it didn’t show up in the picture, but I have the 4 square corners as defined points as well so that the player wont drop off an edge premature.

The names in the text do not fit the names in the picture!
[/quote]
Thanks alot for those pointers, its confirmation that I’m on the right track. I really appreciate the help, I’m hoping to get things moving so that I can finally put something up as a WIP.

Record the x of each point as you move. Determine the position of the line the player needs to be at to be on it. Ex at pixel 100, player should be sitting at start+100, 50.