I can't pinpoint what I'm doing wrong. The concept is a rectangular object navigating slopes (collision line). Im using draw_line to debug, but it "looks" like the collision line is off by just a few pixels, which is enough to throw off the whole system, but only in a certain quadrant. I'm pretty dumb sometimes so I'm hoping its something simple that I'm breezing over lol

The movement code tests for a possible 1px jump when a standard collision is detected. It works great on slopes going "down", as in starting higher and ending lower (left to right), and mostly works on slopes going up. However there exists a tiny discrepancy somewhere causing unexpected behavior on upward slopes. The rectangle will mount the downward slope from the bottom, but refuses to do so on the upward.

Here is the movement code

^^In the corner, as expected.

^^collision kicks in 2 pixels and disallows the 1px jump despite graphic...

here is the draw line code

here are the line values

The movement code tests for a possible 1px jump when a standard collision is detected. It works great on slopes going "down", as in starting higher and ending lower (left to right), and mostly works on slopes going up. However there exists a tiny discrepancy somewhere causing unexpected behavior on upward slopes. The rectangle will mount the downward slope from the bottom, but refuses to do so on the upward.

Here is the movement code

GML:

```
///////////////////input definitions/////////////////////////////////////////////////////
x_change = (keyboard_check(key_move_right)-keyboard_check(key_move_left));
y_change = (keyboard_check(key_move_down)-keyboard_check(key_move_up));
var magnitude = point_distance(0,0,x_change,y_change);
if magnitude > 0
{
x_change /= magnitude;
y_change /= magnitude;
x_momentum_limit = x_momentum_target_limit/magnitude;
y_momentum_limit = y_momentum_target_limit/magnitude;
}
x_momentum += x_change*x_accelerate;
x_momentum = median(-x_momentum_limit,x_momentum,x_momentum_limit);
y_momentum += y_change*y_accelerate;
y_momentum = median(-y_momentum_limit,y_momentum,y_momentum_limit);
x_momentum_sign = sign(x_momentum);
x_momentum_abs = abs(x_momentum);
x_momentum_round = floor(x_momentum_abs);
x_momentum_remain += x_momentum_abs-x_momentum_round;
y_momentum_sign = sign(y_momentum);
y_momentum_abs = abs(y_momentum);
y_momentum_round = floor(y_momentum_abs);
y_momentum_remain += y_momentum_abs-y_momentum_round;
if x_momentum_abs < 0.25
{
x_momentum = 0;
};
if x_momentum_remain > 1
{
x_momentum_round++;
x_momentum_remain--;
//show_debug_message("pop x "+string(x_momentum_remain));
};
if y_momentum_abs < 0.25
{
y_momentum = 0;
};
if y_momentum_remain > 1
{
y_momentum_round++;
y_momentum_remain--;
//show_debug_message("pop y "+string(y_momentum_remain));
};
x_count = x_momentum_round;
y_count = y_momentum_round;
var x_climb = true;
var y_climb = true;
var x_move = 0;
var y_move = 0;
/////////////////////physical movement///////////////////////////////////////////////////
if (x_momentum_round+y_momentum_round) > 0
{
repeat(max(x_momentum_round,y_momentum_round))
{
if x_count > 0
{
x+=x_momentum_sign;
x_count --;
if line_check()
{
if x_climb
{
x_climb = false;
y_move = x_momentum_sign*c_data;
y+=y_move;
if line_check()
{
y-=y_move;
x-=x_momentum_sign;
}
}
else
{
x-=x_momentum_sign;
x_climb = true;
}
}
}
if y_count > 0
{
y+=y_momentum_sign;
y_count --;
if line_check()
{
if y_climb
{
y_climb = false;
x_move = y_momentum_sign*c_data;
x+=x_move;
if line_check()
{
x-=x_move;
y-=y_momentum_sign;
}
}
else
{
y-=y_momentum_sign;
y_climb = true;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
x_momentum = lerp(x_momentum,0,x_damp);
y_momentum = lerp(y_momentum,0,y_damp);
function line_check()
{
for (var i = 0; i < (array_length(line_xy)); ++i)
{
var x1 = line_xy[i].x1;
var x2 = line_xy[i].x2;
var y1 = line_xy[i].y1;
var y2 = line_xy[i].y2;
var check = collision_line(x1,y1,x2,y2,OBJ_1,true,false)
if check
{
var angle = sign(y1-y2)*-1;
if angle != 0
{
c_data = angle;
};
show_debug_message(c_data);
return check;
}
}
}
///////////////////////////debug/////////////////////////////////////////////////////////
if keyboard_check(ord("X"))
{
line_xy[2].x2 = get_integer("x value",768);
}
if keyboard_check(ord("Y"))
{
line_xy[2].y2 = get_integer("y value",128);
}
```

^^In the corner, as expected.

^^collision kicks in 2 pixels and disallows the 1px jump despite graphic...

here is the draw line code

GML:

```
draw_self();
draw_set_color(c_white);
draw_line(line_xy[0].x1,line_xy[0].y1,line_xy[0].x2,line_xy[0].y2);
draw_line(line_xy[1].x1,line_xy[1].y1,line_xy[1].x2,line_xy[1].y2);
draw_line(line_xy[2].x1,line_xy[2].y1,line_xy[2].x2,line_xy[2].y2);
draw_text(0,0,string(x));
draw_text(0,32,string(y));
```

GML:

```
//debug
line_xy[0] = new Line(128,128,128,256);
line_xy[1] = new Line(128,256,512,256);
line_xy[2] = new Line(512,256,512,128);
```

Last edited: