# Topdown RPG slopes?

This topic is 2550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

A Link to the past had basic tilemap collision, but it also had slopes, as shown in the picture.

I am making a topdown rpg, similar to that.
My current code for checking simple, square tiles, is as follows:
 void collide(ENTITY* e, int** tilemap, int map_width, int map_height) { /* x1,y1____x2,y1 | | | | | | x1,y2____x2,y2 */ int i, x1, x2, y1, y2; i = e->h > TILE_SIZE ? TILE_SIZE : e->h; for (;;) { /*horizontal movement*/ x1 = (e->x + e->dirx) / TILE_SIZE; x2 = (e->x + e->dirx + e->w /*- 1*/) / TILE_SIZE; y1 = (e->y) / TILE_SIZE; y2 = (e->y + i - 1) / TILE_SIZE; if (x1 >= 0 && x2 < map_width && y1 >= 0 && y2 < map_height) { if (e->dirx > 0) { /* Trying to move right */ if ((tilemap[y1][x2] != T_BLANK) || (tilemap[y2][x2]!= T_BLANK)) { if ((tilemap[y1][x2] == T_BLOCK) || (tilemap[y2][x2] == T_BLOCK)) { /* Place the player as close to the solid tile as possible */ e->x = x2 * TILE_SIZE; e->x -= e->w + 1; e->dirx = 0; } if ((tilemap[y1][x2] == T_SLOPE_DR) || (tilemap[y2][x2] == T_SLOPE_DR)) { /*?*/ } if ((tilemap[y1][x2] == T_SLOPE_UR) || (tilemap[y2][x2] == T_SLOPE_UR)) { /*?*/ } } } else if (e->dirx < 0) { /* Trying to move left */ if ((tilemap[y1][x1] != T_BLANK) || (tilemap[y2][x1]!=T_BLANK)) { if((tilemap[y1][x1] == T_BLOCK) || (tilemap[y2][x1] == T_BLOCK)) { /* Place the player as close to the solid tile as possible */ e->x = (x1 + 1) * TILE_SIZE; e->dirx = 0; } if ((tilemap[y1][x1] == T_SLOPE_DL) || (tilemap[y2][x1] == T_SLOPE_DL)) { /*?*/ } if ((tilemap[y1][x1] == T_SLOPE_UL) || (tilemap[y2][x1] == T_SLOPE_UL)) { /*?*/ } } } } if (i == e->h) { break; } i += TILE_SIZE; if (i > e->h) { i = e->h; } } /* Now test the vertical movement */ i = e->w > TILE_SIZE ? TILE_SIZE : e->w; for (;;) { /*vertical movement*/ x1 = (e->x) / TILE_SIZE; x2 = (e->x + i) / TILE_SIZE; y1 = (e->y + e->diry) / TILE_SIZE; y2 = (e->y + e->diry + e->h) / TILE_SIZE; if (x1 >= 0 && x2 < map_width && y1 >= 0 && y2 < map_height) { if (e->diry > 0) { /* Trying to move down */ if ((tilemap[y2][x1] != T_BLANK) || (tilemap[y2][x2]!=T_BLANK)) { if (((tilemap[y2][x1] == T_BLOCK) || (tilemap[y2][x2] == T_BLOCK))) { /* Place the player as close to the solid tile as possible */ e->y = y2 * TILE_SIZE; e->y -= e->h; e->diry = 0; } if ((tilemap[y2][x1] == T_SLOPE_DR) || (tilemap[y2][x2] == T_SLOPE_DR)) { if (e->dirx == 0) e->dirx=-e->diry; } if ((tilemap[y2][x1] == T_SLOPE_DL) || (tilemap[y2][x2] == T_SLOPE_DL)) { if (e->dirx == 0) e->dirx=e->diry; } } } else if (e->diry < 0) { /* Trying to move up */ if ((tilemap[y1][x1] != T_BLANK) || (tilemap[y1][x2]!=T_BLANK)) { if ((tilemap[y1][x1] == T_BLOCK) || (tilemap[y1][x2] == T_BLOCK)) { /* Place the player as close to the solid tile as possible */ e->y = (y1 + 1) * TILE_SIZE; e->diry = 0; } if ((tilemap[y1][x1] == T_SLOPE_UR) || (tilemap[y1][x2] == T_SLOPE_UR)) { /*?*/ } if ((tilemap[y1][x1] == T_SLOPE_UL) || (tilemap[y1][x2] == T_SLOPE_UL)) { /*?*/ } } } } if (i == e->w) { break; } i += TILE_SIZE; if (i > e->w) { i = e->w; } } /* Now apply the movement */ e->x += e->dirx; e->y += e->diry; if (e->x < 0) { e->x = 0; } else if (e->x + e->w >= map_width * 32) { e->x = map_width * 32 - e->w - 1; } } 

What this does is it takes the coordinates his four corners, and checks to see if there is a tile in front of the coordinates, based on his current speed vector (dirx and diry), and if that is true, then he will basically be 'snapped' to the grid. This is quite robust. The areas with no code and commented with a ? are when he 'collides' (or will collide) with some kind of slope tile, either Down-left, Down-right, Up-left, or Up-right.
I already know whether or not he will be in the bounding box of the slope, but how do I check whether he will collide with the hypotenuse? And how would I go about response, sliding him down the slope like in LTTP? They are only 45 degree slopes, but in 4 directions. Keep in mind this is only C, and the tiles are not data structures with coordinates, just a single number representing what type of tile it is. I had an idea to make his speed in the other direction equivalent to his speed in the direction he's going, to make him move diagonally whenever he came within the bounding box of the slope, but this technique had many problems. I need something more robust, but nothing too complicated.

##### Share on other sites
Filthy trick: don't try to make slopes.

Consider this hypothetical approach: There are tiles that are painted to look like vertical surfaces. There are tiles which are marked obstructed to prevent you from "climbing" them. Then there are tiles which are marked passable, and painted to look like ramps, stairs, etc.

Now you get the visual effect of 2.5D terrain without writing a single line of code. It's all down to art and level design.

##### Share on other sites

Filthy trick: don't try to make slopes.

Consider this hypothetical approach: There are tiles that are painted to look like vertical surfaces. There are tiles which are marked obstructed to prevent you from "climbing" them. Then there are tiles which are marked passable, and painted to look like ramps, stairs, etc.

Now you get the visual effect of 2.5D terrain without writing a single line of code. It's all down to art and level design.

No, I understand that trick and have been using it for other projects. But I want to know how to do strictly 2-dimensional slopes in a top-down environment.
Like in this image on the corners of the room:

##### Share on other sites
Just to clarify: By "slopes" you mean walls that run diagonally on a 2D surface? It's a bit confusing since the first image seems to contain ACTUAL slopes,as well as diagonal walls.

Can't you replace the bounding boxes of the diagonal walls with polygons or (if they are always on the outer part of the level) even just line segments?

##### Share on other sites
Yeah, i think he means going in the diagonal direction

##### Share on other sites

No, I understand that trick and have been using it for other projects. But I want to know how to do strictly 2-dimensional slopes in a top-down environment.
Like in this image on the corners of the room:

What you see in that room is not what I would call a "slope." There is no elevation change. All you are seeing is a rendering/artwork trick.

##### Share on other sites

Just to clarify: By "slopes" you mean walls that run diagonally on a 2D surface? It's a bit confusing since the first image seems to contain ACTUAL slopes,as well as diagonal walls.

Can't you replace the bounding boxes of the diagonal walls with polygons or (if they are always on the outer part of the level) even just line segments?

I mean 2d walls going diagonally. Where in that image do you see anything else? The game contains vertical slopes, but not the image...
My game doesn't do a bounding box check, it does a grid-based check. Dividing the player's coordinates by the tile size, and checking the data grid if the player's location is passable (0 on the grid).
And in that game, they weren't a graphical trick either. The player would actually slide along them diagonally.

##### Share on other sites
[s]Ok, to clarify things up. What re you meaning? the corners? or the grass, that is in diagonal lines? or another thing?

please try to be more clear[/s]
[s]
[/s]
[s]
[/s]
ok, the walls cutting half a grid square.. now it's clear.

If you have a squre you can find the Hypotenuse, and have a square cut in half....

But it must have another way of doing this....

##### Share on other sites

Ok, to clarify things up. What re you meaning? the corners? or the grass, that is in diagonal lines? or another thing?

please try to be more clear

I fail to see what isn't clear about this. It really isn't easy to explain in words, so I'm gonna fire up GIMP.
This is what I mean when I say 'slopes':
[attachment=4467:Slopes.png]

If Link comes into contact with a 'slope', and continues moving:
[attachment=4468:Start.png]
[attachment=4469:end.png]

He will slide along it, like in the above picture.
This is what I want. However, my code checks if he is coming into contact with the slope's bounding box. I want to know how to check if he has collided with the hypotenuse, and how to slide him along the slope like in LTTP. The tiles aren't objects, but numbers in a grid of data known in my code as tilemap[][].

##### Share on other sites
Ah, you're talking about diagonal walls.

That's easy: you mark which corner is clear (only four possibilities: top left, top right, bottom left, bottom right). Based on that, you know the slope of the diagonal itself (it will be either +1 or -1) and the side of the diagonal (above or below) that should be passable. Then you write a total of five collision check cases:

• No corners are clear, i.e. the block is solid - use your existing code
• Top left corner is clear
• Top right corner is clear
• Bottom left corner is clear
• Bottom right corner is clear
For the solid block case, do as you already do. For diagonals, you just do an intersection between the line that defines the diagonal, and the player's bounding box. If they hit, move the player back "out" of the wall and slide them along it. If they don't overlap, allow the player to move freely.

1. 1
Rutin
24
2. 2
3. 3
JoeJ
20
4. 4
5. 5

• 9
• 46
• 41
• 23
• 13
• ### Forum Statistics

• Total Topics
631746
• Total Posts
3002022
×