Momentum and other Additions to Shaun Spalding's Player Code

Shawn Basnett

Discount Dev
GM Version: Game Maker Studio 1 (should work in v.2)
Target Platform: PC (should work for HTML5 and mobile modules)
Description: character movement with momentum, wall sliding, and wall jumping

After a bit of work, I've created a version of Shaun Spalding's player code that includes momentum, wall sliding, and wall jumping.

First, in the Create event, Add two new variables; max_hsp, and normal_grav

lower your movespeed and your grav variable, your Create Event should be similar to this:

Code:
///Initialize variables
grav = 1;
hsp = 0;
vsp = 0;
jumpspeed = 11;
movespeed = .5;
max_hsp = 7;
normal_grav = 1;
max_hsp will provide as a cap to your speed left or right, this will keep you from shooting through the wall by keeping your momentum under the number you set it to.

normal_grav is a sort of reference for the wall sliding later implemented.

Next, Change your Step event to this:

Code:
///Get the Player's Input
key_right = keyboard_check(vk_right);
key_left = -keyboard_check(vk_left);
key_jump = keyboard_check_pressed(vk_up);

//React to the player's inputs
move = key_left + key_right;
if (key_left = -1) previous_dir = -1;
if (key_right = 1) previous_dir = 1;

//Acceleration
if (hsp < max_hsp) && (hsp > -max_hsp)
{
    hsp += move * movespeed;
}
else if (hsp = max_hsp)
{
    if (key_right)
    {
        hsp = max_hsp;
    }
    else
    {
        hsp -= 1
    }
}
else if (hsp = -max_hsp)
{
    if (key_left)
    {
        hsp = -max_hsp;
    }
    else
    {
        hsp += 1;
    }
}
if (hsp > 0) && (key_left = 0) && (key_right = 0) && (place_meeting(x,y+1,obj_wall)) {hsp -= .5}

if (hsp < 0) && (key_left = 0) && (key_right = 0) && (place_meeting(x,y+1,obj_wall)) {hsp += .5}

//Gravity
if (vsp < 10) vsp += grav;

if (place_meeting(x,y+1,obj_wall))
{
    vsp = key_jump * -jumpspeed
}
//Wall Jumps
if (place_meeting(x+1,y,obj_wall)) && (!place_meeting(x-1,y,obj_wall))
{
    if (key_jump) && (!place_meeting(x,y+1,obj_wall))
    {
        vsp -= 15;
        hsp -= 5;
    }
}

if (place_meeting(x-1,y,obj_wall)) && (!place_meeting(x+1,y,obj_wall))
{
    if (key_jump) && (!place_meeting(x,y+1,obj_wall))
    {
        grav = normal_grav;;
        vsp -= 15;
        hsp += 5;
    }
}
//Wall Slides Left
    if (key_left = -1) && (vsp > 0) && (place_meeting(x-1,y,obj_wall)) && (!place_meeting(x,y+1,obj_wall))
    {
        if (vsp <= 11) && (vsp > 1.5) vsp -= 1;
        if (vsp <= 11)  && (vsp > 0) grav = .05;
  
    }
    if (key_left = -1 && (place_meeting(x-1,y,obj_wall)) && (!place_meeting(x,y+1,obj_wall)))
    {
        grav = normal_grav;
    }
    if (key_left = 0)
    {
        grav = normal_grav;
    }
//Wall Slides Right
    if (key_right = 1) && (vsp > 0) && (place_meeting(x+1,y,obj_wall)) && (!place_meeting(x,y+1,obj_wall))
    {
        if (vsp <= 16) && (vsp > 1.5) vsp -= 1;
        if (vsp < 10)  && (vsp > 0) grav = .05;
  
    }
    if (key_right = 1 && (place_meeting(x+1,y,obj_wall)) && (!place_meeting(x,y+1,obj_wall)))
    {
        grav = normal_grav;
    }
    if (key_right = 0)
    {
        grav = normal_grav;
    }
//Horizontal Collision
if (place_meeting(x+hsp,y,obj_wall))
{
while(!place_meeting(x+sign(hsp),y,obj_wall))
{
 x += sign(hsp);
}
hsp = 0;
}
x += hsp;

//Vertical Collision
if (place_meeting(x,y+vsp,obj_wall))
{
while(!place_meeting(x,y+sign(vsp),obj_wall))
{
 y += sign(vsp);
}
vsp = 0;
}

y += vsp;
This code should cause your player to accelerate until it hits maximum speed in any direction.

Wall jumping is set up to carry up the momentum of the player, this means that if the player is to move at maximum speed to the right and jump at and off of the right wall, the momentum will carry the player higher than if it were to just jump at it from a still position.

The Wall sliding Mechanic is simply there to compliment the wall jump. When the player holds the movement key towards the right, as long as the player's vsp is positive, the player will slowly lose momentum until they hit the floor, this loss of momentum caps off at a vsp of 1.5 and a grav of .05


[Issues to Note]

For some reason, if the player hits terminal velocity going down (I believe it to be 16), The momentum on the wall slide will not decrease.

If wall jumps are done consecutively on walls that are too close together, the vsp will continue to decrease until you either hit a ceiling or shoot through it.

The Collision code should be added in as well, his collision code should work perfectly with this.

I know it's not perfect and it needs cleaned up a bit, but it's a basis for people to get an understanding of how it could be done.
 
Last edited:

chance

predictably random
Forum Staff
Moderator
I know it's not perfect and it needs cleaned up a bit, but it's a basis for people to get an understanding of how it could be done.
That's true (on both accounts). I think the conditionals in the STEP event could be simplified and optimized considerably. But I don't generally use platformer code, so I'll leave those optimizations for others. As you suggested, there's room for improvement. And that can be a learning process in itself.

Your post would also benefit from some explanation of the ideas here. A short description of your approach to sliding and wall jumping would help beginners under the code, and tailor it to their own needs.
 

Shawn Basnett

Discount Dev
That's true (on both accounts). I think the conditionals in the STEP event could be simplified and optimized considerably. But I don't generally use platformer code, so I'll leave those optimizations for others. As you suggested, there's room for improvement. And that can be a learning process in itself.

Your post would also benefit from some explanation of the ideas here. A short description of your approach to sliding and wall jumping would help beginners under the code, and tailor it to their own needs.
Understandable, I'll make some changes to the post.
 
P

plant

Guest
I'm currently making a 2D plat-former game and I wanted momentum and wall bouncing etc. so I tried put this code in my code and it didn't work so I opened a blank document with just a room, sprites and objects but the player doesn't move, isn't even effected by gravity. Should it work is there anything else I need to add? Do any boxes like Solid and Uses Physics need to be ticked?
 

Shawn Basnett

Discount Dev
I'm currently making a 2D plat-former game and I wanted momentum and wall bouncing etc. so I tried put this code in my code and it didn't work so I opened a blank document with just a room, sprites and objects but the player doesn't move, isn't even effected by gravity. Should it work is there anything else I need to add? Do any boxes like Solid and Uses Physics need to be ticked?
You shouldn't need to tick anything? Are you certain you're placing the code in the correct events?
 
P

plant

Guest
You shouldn't need to tick anything? Are you certain you're placing the code in the correct events?
I put the first section in the player create event and the second in the player step event and the object just floats in the room. Doesn't react to gravity and doesn't react to inputs. My objects share the same name as the ones used in the code and the only things that I have made are: the room, the player sprite / player object and the wall sprite / wall object. Any other ideas on why it might not be working?

edit*

I've uploaded the file so maybe you can look https://www.mediafire.com/?tjm7w30akevrba5 would be much a appreciated.

Thanks
 
Last edited by a moderator:
D

dj_midknight

Guest
I did something similar with shaun's basic platformer code. This is just a snipit to show the basics of my movement. This is grabbed from my gravity platformer so it has to work in all orientations, so you can ignore a few of the booleans.

Also note that any variable in all caps is a constant, and is probably being referenced in a bunch of locations. Using macros for stuff like this is great cus you can literally forget where you put the code and just tweak you values as needed from the config screen in GMS.

This example the player accelerates faster than drag is applied so when you release the stick/key you will carry momentum. Furthermore pressing the opposing direction increases drag applied, but does not immediately cancel out any forward motion. Thus you kinda skid like mario stopping from a full sprint.

Code:
///player movement

if(!controler.rewinding && !controler.spinning){
 
    //jump control
    if(CAN_JUMP(id) && obj_keys.key_button1){
        vsp -= JUMPSPEED;
    }
 
    //horizontal speed
    move = obj_keys.key_left + obj_keys.key_right;
    hsp += MOVESPEED * move;
    if(abs(hsp) > HSP_MAX){ hsp = HSP_MAX * sign(hsp); }
    if(abs(hsp) - DRAG > 0){
        hsp -= DRAG * sign(hsp);
    }
    else{ hsp = 0; }//needed to ensure that no fragment hsp remains
 
 
    if(vsp < FALL_SP){
        vsp += GRAV;
        if(vsp > FALL_SP){ vsp = FALL_SP; }//needed to ensure vsp NEVER exceeds max
    }
 
    if(controler.angle = 0){
           
        //horizontal position
        if(place_meeting(x+hsp,y,obj_map)){
            while(!place_meeting(x+sign(hsp),y,obj_map)){
                x += ACCURACY*sign(hsp);
            }
            hsp = 0;
        }
   
        //vertical position
        if(place_meeting(x,y+vsp,obj_map)){
            while(!place_meeting(x,y+sign(vsp),obj_map)){
                y += ACCURACY*sign(vsp);
            }
            vsp = 0;
        }
        x += hsp;
        y += vsp;
    }//end if angle = 0

//omit remaining 3 orientations
}
 
Last edited by a moderator:

Shawn Basnett

Discount Dev
@plant I just realized why it wasn't working. You don't have the collision code added... I've added it to the original post xP. My apologies. I guess I should've added it, instead of expecting people to know.
 

LanceCS

Member
Hey there. I know this is an old thread but I have a question. Everything in this code works fine, but I was wondering if there was a way to increase the speed slower than your code does. I want my character to start out walking and after a bit of time transition into a run.
 

xDGameStudios

GameMaker Staff
GameMaker Dev.
The variable movespeed is what you want to change. It corresponds to the “increase in speed every step you are pressing a key” so it’s what you might call acceleration
 
Top