| |
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
|