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: