# Smooth platform slope movement

No replies to this topic

### #1 decroded

decroded

GMC Member

• GMC Member
• 594 posts
• Version:GM:Studio

Posted 07 May 2012 - 09:54 AM

I'm getting nowhere on this one so I'm after a bit of help from the pros (suck up!!)

Here is an example of what I'm trying to achieve.
I'm trying to create smooth 2D platform movement on slopes which allows arbitrary speeds instead of jumping from 1, 2, 3...
I can't find any examples that let you do this and there is a noticeable difference when you can move/accelerate at sub-pixel speeds.

So far it moves pretty smoothly until there's a downward slope.
I'm also noticing some strange anomalies and can't work out why it sometimes goes inside par_solid.
Especially I don't think the last bit of the movement code where it finishes off by moving whatever is left < 1 pixel, I suspect this is not working but don't know how to fix it

I'm open to other approaches such as extra vars for the sub-pixel location and at the end of the step just moving the actual "x = round(subx); y = round(suby);".
Otherwise please can I have a some help with my code?
I'm keen for ALL feedback on how to code better even if it doesn't resolve the issue

Thanks!

Code if you don't want to download, currently dumped in Draw event:
```/*
//--METHOD:
//read inputs and set movement flags:
//calculate destination based on x/y speed, deceleration etc
//calculate distance to destination
//move in direction of destination 1 pixel at a time, until distance travelled (from start x/y to curr x/y) >= distance from start to the original destination
// if collision with solid, try to slip up the slope (and round y) or stop and break loop if can't
// if not airborne, but now not on solid ground, try to slip down a slope (and round y) to find solid ground again
// update destination y by distance travelled up/down on the slope movement (for recalculating next loop destinations)
// update actual x/y (error if collision!!)
//end loop.
//draw sprites etc...
*/
var newspeed,xdest,ydest,xnext,ynext,i,stepup,distdest,distcurr;

//read inputs and set movement flags:
goleft=false;
goright=false;
jump=false;
if keyboard_check(vk_left) {goleft=true;}
if keyboard_check(vk_right) {goright=true;}
if keyboard_check(vk_space) {jump=true;}
if goleft and goright {goleft=false; goright=false;}    //--cancellation

//add to horizontal speed if pressed left/right (+/-xspeed)
if goleft {xspeed-=run_acc;}
if goright {xspeed+=run_acc;}
if abs(xspeed) > run_max {xspeed=run_max*sign(xspeed);} //--running speed limit

//--slow down horizontal speed if not pressing left/right
if !goleft && !goright { //--stopping:
newspeed=xspeed-run_dec*sign(xspeed);
if sign(newspeed)=sign(xspeed) {
xspeed=newspeed;
} else {
xspeed=0;
}
}

//if not standing on ground, set airborne flag
if !place_meeting(x,y+1,par_solid) {airborne=true;} else {airborne=false;}

//if not airborne and pressed jump then move up (-yspeed), else fall down (+yspeed)
if airborne {
yspeed+=fall_acc;
if abs(yspeed) > fall_max {yspeed=fall_max*sign(yspeed);} //--falling speed limit
} else {
if jump {
yspeed=0-jump_speed;
} else {
y=ceil(y);
yspeed=0;
}
}

//calculate distance to destination
stepup=false;
xdest=x+xspeed;
ydest=y+yspeed;
xnext=x;
ynext=y;
distcurr=0;
distdest=point_distance(x,y,xdest,ydest);

//--loop towards destination...
while distcurr<=distdest {
//--get next dest:
if distdest-distcurr>=1 {
xnext=x+lengthdir_x(1,point_direction(x,y,xdest,ydest));
ynext=y+lengthdir_y(1,point_direction(x,y,xdest,ydest));
} else {
xnext=x+lengthdir_x(distdest-distcurr,point_direction(x,y,xdest,ydest));
ynext=y+lengthdir_y(distdest-distcurr,point_direction(x,y,xdest,ydest));
}
//--test for collision:
if place_meeting(xnext,ynext,par_solid) {
//try to step up slope:
if !airborne {
stepup=false;
for (i=1; i<=stepmax; i+=1) {
if !place_meeting(xnext,ynext-i,par_solid) {
ynext-=i;
distcurr+=i;
stepup=true;
break;
}
}
//stop if couldnt step up slope:
if !stepup {
if abs(xspeed>3) {sound_play(snd_bump);}
xnext=x;
xspeed=0;
break; //break the while loop
}
}
}
//go down slope...
if !jump && !place_meeting(xnext,ynext+1,par_solid) {
for (i=1; i<=stepmax; i+=1) {
if place_meeting(xnext,ynext+i,par_solid) {
ynext+=i;
distcurr+=i;
break;
}
}
}
//move to next position if there was nothing blocking:
x=xnext;
y=ynext;
distcurr+=1;
}

//DRAW:
draw_sprite_ext(sprite_index,image_index,x,y,img_dir,1,0,c_white,image_alpha);
draw_set_color(c_white);
draw_text(20,20,"X:"+string(x));
draw_text(20,40,"Y:"+string(y));
```

Edited by decroded, 07 May 2012 - 09:58 AM.

• 0
Don't forget to +1 if I have helped you ========>