Ramps
Home Up Event Sequence Simple Example Ramps curved surfaces Old version

 

Ramps in platform games

The code will replace the standard behaviour with "move_contact" actions that will make the object free fall normally, "land" on solid objects and further to this it will follow ramps of up to 45 degrees up or down.

Important note:

This is an update of my earlier ramp_platform code. The script now rounds the distances to integer numbers of pixels so avoiding the slightly erratic movement seen previously. 

It will be up to the developer to add keyboard actions, set a gravity, friction, select sprites etc. As the keyboard handling is separated from the engine it is easy to create "monsters" under computer control.

Note that the code requires a flag called "jump" which should be set in the create event

Jump is required as the ramp code ignores "vspeed" causing the player to stick to the platform even if the platform curves down steeper than freefall. Setting jump to true will "unstick" the player from the platform.

var y1;
//Roll back movement
//This is necessary as GM may or may not have carried out "Solid" behaviour
x=xprevious
y=yprevious
//Check if we're on the ground
if not (jump or place_free(x,y+1))
{
  jump=false  
  //We're on the ground so check we haven't just walked off a cliff
  y1=abs(round(x+hspeed)-round(x))
  if not place_free(x+hspeed,round(y)+y1+1)
  {
      //Search for the ground level
      x+=hspeed;
      y1+=(y1=0)
      y=round(y+y1)
      move_outside_solid(90,y1*2)  
      //Roughly set vspeed for the benefit of any AIs that may use it
      vspeed=(y-yprevious)
      //Check if we hit a wall.
      if not place_free(x,y)
      {
          x=xprevious
          y=yprevious
          if hspeed<>0
          {
            move_contact_solid(180*(hspeed<0),abs(hspeed))
          }  
          hspeed=0
          vspeed=0
      }
  }
  else
  {
    //Lookout!! Cliff!!
    // vspeed=0
    //Just move out horizontally
    move_contact_solid(180*(hspeed<0),abs(hspeed))
    jump=true
  }  
}
else
{
  //Freefall code
  //check for no collision at all
  if place_free(x+hspeed,y+vspeed)
  {
    x+=hspeed
    y+=vspeed
  }
  else
  {
    //collision so find out where
    //Move horizontally
    if hspeed<>0
    {
      move_contact_solid(180*(hspeed<0),abs(hspeed))
      if not (place_free(x+sign(hspeed),y) or place_free(x+sign(hspeed),y-2))
      {
        hspeed=0
      }
    }
    //Move vertically
    if vspeed<>0
    {
      move_contact_solid(90+180*(vspeed>0),abs(vspeed))
      if not place_free(x,y+sign(vspeed))
      {
        if vspeed>0
        {
          jump=false
        }
        vspeed=0
      }
    }
  }
}

It will be seen that this code "glues" the player to the platform at times when possibly they ought to free-fall. I find the effect can be pleasing though.

No extra effort is required to run uphill (yet). A more sophisticated engine would allow for gravity when running up and down.

Unlike the simple platform code, here there is separate code for a platform and for freefall.

The platform code moves the player down into the platform at a 45 degree angle, then "floats" them to the surface of the platform using move_outside.
The freefall code first checks for a collision. If no collision then the player is moved normally using a minimum of code. If there is a collision then the player is first moved horizontally as far as possible then vertically as far as possible.
Important footnote: I am finding that jumping is sometimes inconsistent and it seems as if testing for collision at "y+1" doesn't always give the expected results, under GM Studio this may need changing to "round(y+1)". My suspicion (unproven) is that normal instance positions are rounded but collision test functions "floor()" their arguments instead of rounding them.

Note that at this time there is no support for special (non-solid) platforms. It should not be hard to add though, as if the player does not have solid platform under them then the player is assumed to be falling. It should be a simple matter to detect an alternative platform type, either using place_meeting or a collision event.

More to follow...

Demo: 

ramp_platform2.gmd