You're welcome.
Because I've been curious about this for a long time (I never actually implemented my "theory"), I changed your code to do proper "stop at collision" response using my tips above. If I'm curious enough, I'll add sliding too, a bit later.
Sorry, I don't know how to attach files here. Here's just the modified ResolveCollissions function:
var ResolveCollissions = function(px,py,velx,vely,iteration,slide) {
/* if (iteration > 100) {
this.x = pos_x_old;
this.y = pos_y_old;
return;
}*/
var velocityAmount = 1.0;
var pushx = 0.0;
var pushy = 0.0;
//i think i need to sort the lines for the first impaced line first etc instead of looping it in normal sort order!?!?!?
//lines.sort(compare);
for (var i = 0; i < lines.length; i++) {
var closestpoint = new ClosetPointOnLine(lines[i].x, lines[i].y, lines[i].x2, lines[i].y2, px, py);
var ln = new lineNormal(lines[i].x, lines[i].y, lines[i].x2, lines[i].y2);
var VdotN = velx * ln.dx + vely * ln.dy;
var lclosest = lineLength(px, py, closestpoint.x, closestpoint.y);
var ltotal = Math.abs(VdotN);
var newamount = Math.max(0.0, (lclosest - SPHERE_RADIUS) / ltotal);
if (newamount < velocityAmount)
{
velocityAmount = newamount;
pushx = (px - closestpoint.x) / lclosest;
pushy = (py - closestpoint.y) / lclosest;
}
}
px += velx * velocityAmount + pushx * 0.5;
py += vely * velocityAmount + pushy * 0.5;
if (slide)
{
// slideVelocity = dot_product(normalized_collided_line, velocity * (1.0 - velocityAmount)
// call ResolveCollissions again with px, py, slideVelocity and slide = false
}
//Return the calculated position.
this.x = px;
this.y = py;
}
First time you call it, you have to call it with the extra "slide" parameter set to true, although that doesn't do anything right now.
Notice that even now there's still a bit of sliding, because the player position is still being pushed away from the collided line by a small amount (currently 0.5, but it can be much, much smaller; Quake 3 - where I got my inspiration from - calls it "EPSILON", and defiens it as 0.03125f, or 1/32). This is to avoid the player going "through" the collided line due to floating point precision errors. This means that there will still be a bit of jittering at the corners, but it will hardly be noticeable, because this time you're only pushing the player back by a very small amount, not the whole radius. Also, instead of pushing back along the normal (which may cause "skipping" - even though it's hardly noticeable), it would probably be better to project (dot product) the EPSILON-length normal onto the original velocity vector, and push back by that amount (along the velocity vector, not the normal).