• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Slopes in top down game

C

Cristiander

Guest
I'm working on a game with a top down view (like an rpg). The player can move anywhere on the map.
The collisions for simple squares was not a problem. However making it for slopes has turned out to be a challenge.

The code I'm currently using is this one:
Code:
///scr_player_colisions


if(place_meeting_rounded(x + x_speed, y + y_speed, obj_wall))
{
    x = round(x);
    y = round(y);

    //if the colision is horisontal   
    if(place_meeting_rounded(x + x_speed, y, obj_wall)) {
       
        var yplus = 0;
       
        //can we go above?
        while(place_meeting_rounded(x + x_speed, y - yplus, obj_wall) && yplus <= abs(x_speed)) yplus += 1;
        if ((!place_meeting_rounded(x + x_speed, y - yplus, obj_wall)) && (!down_held)) {
            //if you can go up, then go up
            y -= yplus; 
            if (abs(x_speed) > (_max/sqrt(2) - 1)) then { x_speed = sign(x_speed)*(_max/sqrt(2));}
            }
        else {
            //we can't go above it   
            //can we go below?
            while(place_meeting_rounded(x + x_speed, y + yplus, obj_wall) && yplus <= abs(x_speed)) yplus += 1;
            if ((!place_meeting_rounded(x + x_speed, y + yplus, obj_wall)) && (!up_held)) {
                //if we can go down, then we'll go down
                y += yplus;
                if (abs(x_speed) > (_max/sqrt(2) - 1)) then { x_speed = sign(x_speed)*(_max/sqrt(2));}
                }
            else {
                //we can't go below it
                //we get as close as we can to the wall and stop
                while(!place_meeting_rounded(x + sign(x_speed), y, obj_wall))
                    x += sign(x_speed);
                x_speed = 0;
                }           
            }
        }
       
       
    //if the colision is vertical   
    if(place_meeting_rounded(x, y + y_speed, obj_wall)) {
   
        var xplus = 0;
       
        //can we go to the left?
        while(place_meeting_rounded(x - xplus, y + y_speed, obj_wall) && xplus <= abs(y_speed)) xplus += 1;
        if ((!place_meeting_rounded(x - xplus, y + y_speed, obj_wall)) && (!right_held)) {
            //if you can go to the left, then go to the left
            x -= xplus; 
            if (abs(y_speed) > (_max/sqrt(2) - 1)) then { y_speed = sign(y_speed)*(_max/sqrt(2));} // reduce the speed when the player goes diagonally
            }
        else {
            //we can't go to the left   
            //can we go to the right?
            while(place_meeting_rounded(x + xplus, y + y_speed, obj_wall) && xplus <= abs(y_speed)) xplus += 1;
            if ((!place_meeting_rounded(x + xplus, y + y_speed, obj_wall)) && (!left_held)) {
                //if we can go to the right, then we'll go right
                x += xplus;
                if (abs(y_speed) > (_max/sqrt(2) - 1)) then { y_speed = sign(y_speed)*(_max/sqrt(2));} // reduce the speed when the player goes diagonally
                }
            else {
                //we can't go right
                //we get as close as we can to the wall and stop
                while(!place_meeting_rounded(x, y+ sign(y_speed), obj_wall))
                    y += sign(y_speed);
                y_speed = 0;
                }           
            }
        }   
    }


if(!place_meeting_rounded(x + x_speed, y, obj_wall)) x += x_speed;
if(!place_meeting_rounded(x, y + y_speed, obj_wall)) y += y_speed;
It works fine, it doesn't slow down the player when he moves on slopes, however the movement is sometimes very janky.

For example, if he moves up a slope then the movement is perfect and smooth. But if he moves down a slope then he just teleports 3-4 pixels below the slope and moves forward, and then he teleports again when he gets close to the slope.

I don't understand why this is happening, the code is identical for both situations, however the result is different.

Any help is welcomed. Credit will be given.

Thank you :)
 
Top