1. Hey! Guest! The 35th GMC Jam will take place between November 28th, 12:00 UTC - December 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice

Momentum and other Additions to Shaun Spalding's Player Code

Discussion in 'Tutorials' started by Shawn Basnett, Jan 6, 2017.

  1. Shawn Basnett

    Shawn Basnett Discount Dev

    Joined:
    Jan 5, 2017
    Posts:
    104
    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: Mar 22, 2017
  2. chance

    chance predictably random Forum Staff Moderator

    Joined:
    Apr 22, 2016
    Posts:
    799
    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.
     
  3. Shawn Basnett

    Shawn Basnett Discount Dev

    Joined:
    Jan 5, 2017
    Posts:
    104
    Understandable, I'll make some changes to the post.
     
  4. plant

    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?
     
  5. Shawn Basnett

    Shawn Basnett Discount Dev

    Joined:
    Jan 5, 2017
    Posts:
    104
    You shouldn't need to tick anything? Are you certain you're placing the code in the correct events?
     
  6. plant

    plant Guest

    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: Mar 7, 2017
    Shawn Basnett likes this.
  7. Shawn Basnett

    Shawn Basnett Discount Dev

    Joined:
    Jan 5, 2017
    Posts:
    104
    No problem. I'll check it out on Thursday, when I get back from California. ^_^
     
  8. plant

    plant Guest

    thank you vm :)
     
    Shawn Basnett likes this.
  9. dj_midknight

    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: Mar 9, 2017
    Shawn Basnett likes this.
  10. Shawn Basnett

    Shawn Basnett Discount Dev

    Joined:
    Jan 5, 2017
    Posts:
    104
    Holy crap. I'm so very sorry, I'm looking into it now. I entirely forgot about this, very busy this last week. I'll pm you about it later today.
     
  11. Shawn Basnett

    Shawn Basnett Discount Dev

    Joined:
    Jan 5, 2017
    Posts:
    104
    @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.
     
  12. plant

    plant Guest

    Thats probably quite obv to most but im new to it. It works now thanks :)
     
    Shawn Basnett likes this.
  13. Shawn Basnett

    Shawn Basnett Discount Dev

    Joined:
    Jan 5, 2017
    Posts:
    104
    No problem :p Have fun with your game!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice