[Beginner] Platformer Movement Acceleration and Jumping

C

camscottbryce

Guest
I've done a bit of searching because I thought this topic was on the old GMC but alas- I've been working with GM for a long time but still am pretty garbage when it comes to programming (including drag and drop).

All I want to know is how to add acceleration to the player's movement. So that once you hold down "right," the player starts accelerating right, and once you release right, the player slows down and stops, similar to the movement in Super Mario Bros. or Super Mario Bros. 3. I've tried doing this on my own but I have issues with collision and with moving in the opposite direction.

EDIT: Another thing is I'm looking to do that style of "jumping" where holding down space causes you to jump higher (at a non static rate), meaning that I want to be able to tap space to do a small jump, hold space to do a high jump, and be able to release space at any time to do a low-medium-high jump. Is there an easy way of implementing this? I've tried a couple of things, between keep gravity lower when space is held or adding to the vspeed when the key is held down but both of those ended up being pretty wonky and it feels like there's another solution.

As stated earlier, I'm complete garbage when it comes to programming, so please be patient and try to explain things as you would to a beginner. I know that's a lot to ask but I'm just trying to learn, thanks.
 
Last edited by a moderator:

BLang

Member
The way I like to do this is set up a hspd variable that actually controls the movement of the player, while the movement keys just control the variable.
So, kinda like this:

Code:
if (keyboard_check(vk_right)){
    hspd+=1;
}

if (keyboard_check(vk_left)){
    hspd-=1;
}

if (!keyboard_check(vk_left) && !keyboard_check(vk_right)){
    hspd-=sign(hspd);
}

//the code up until now is basically what I've explained
//above - the movement keys control hspd

hspd = clamp(hspd, -maxhspd, maxhspd);
//this makes sure hspd doesn't exceed
//the maximum movement speed

if (place_meeting(x+hspd, y, o_wall)){
    while (!place_meeting(x+sign(hspd), y, o_wall)){
        x+=sign(hspd);
    }
    hspd=0;
}
//the above is your basic horizontal collision. 
//If the player is going to collide with the wall,
//move them pixel by pixel until they're right 
//next to the wall, then set hspd to 0.

x+=hspd;
//if the player didn't collide with the wall,
//then just move him to where he's supposed to be
If you fiddle with this a bit and give it some thought, I'm sure you can get it to work!
Feel free to ask for further explanation if you didn't understand some part of this.
 

TheouAegis

Member
var key = keyboard_check(vk_right)-keyboard_check(vk_left);
hspeed += (key + ( (key==0 && hspeed<0) - (key==0 && hspeed>0) << 1 ) )/ 8;
 
C

camscottbryce

Guest
The way I like to do this is set up a hspd variable that actually controls the movement of the player, while the movement keys just control the variable.
So, kinda like this:

//code

If you fiddle with this a bit and give it some thought, I'm sure you can get it to work!
Feel free to ask for further explanation if you didn't understand some part of this.
Hey, thanks for this, it helped a lot. That works for me!

I do have another question, though it is entirely unrelated to this thread and so I can post it elsewhere if the mods just want to close this down:

I'm looking to do that style of "jumping" where holding down space causes you to jump higher (at a non static rate), meaning that I want to be able to tap space to do a small jump, hold space to do a high jump, and be able to release space at any time to do a low-medium-high jump. Is there an easy way of implementing this? I've tried a couple of things, between keep gravity lower when space is held or adding to the vspeed when the key is held down but both of those ended up being pretty wonky and it feels like there's another solution.
 
W

wagyu_so_gud

Guest
Hey, thanks for this, it helped a lot. That works for me!

I do have another question, though it is entirely unrelated to this thread and so I can post it elsewhere if the mods just want to close this down:

I'm looking to do that style of "jumping" where holding down space causes you to jump higher (at a non static rate), meaning that I want to be able to tap space to do a small jump, hold space to do a high jump, and be able to release space at any time to do a low-medium-high jump. Is there an easy way of implementing this? I've tried a couple of things, between keep gravity lower when space is held or adding to the vspeed when the key is held down but both of those ended up being pretty wonky and it feels like there's another solution.

you can do something like:

Code:
if vspd < 0 && keyboard_check_released(vk_space) //essentially, if you let go of the jump key (when your vspd is neg/jumping state), the vspd is cut short which gives you a more precise jump.
{
vspd *= 0.25;
}
 

BLang

Member
The solution is to change the vspeed when you release the space key. So I guess like this:

Code:
if (keyboard_check_pressed(vk_space) && on_ground){
    vspd=-12; //or whatever, this is just basic jumping
}

if (keyboard_check_released(vk_space) && vspd<0){
    //essentially, if we release space and the player is
    //going upwards
    vspd/=2; //then, halve the vspd
}
Edit: Ninja'd by @wagyu_so_gud :D
Well, might as well add something to this - you don't necessarily have to halve the vspd. You might do vspd/=3 or vspd/=4 or whatever feels right. You can even do vspd=0, but usually that's a bit abrupt and looks weird. Basically, as long as you bring vspd towards 0, it's gonna work.
 
C

camscottbryce

Guest
you can do something like:

Code:
if vspd < 0 && keyboard_check_released(vk_space) //essentially, if you let go of the jump key (when your vspd is neg/jumping state), the vspd is cut short which gives you a more precise jump.
{
vspd *= 0.25;
}
The solution is to change the vspeed when you release the space key. So I guess like this:

Code:
if (keyboard_check_pressed(vk_space) && on_ground){
    vspd=-12; //or whatever, this is just basic jumping
}

if (keyboard_check_released(vk_space) && vspd<0){
    //essentially, if we release space and the player is
    //going upwards
    vspd/=2; //then, halve the vspd
}
Edit: Ninja'd by @wagyu_so_gud :D
Well, might as well add something to this - you don't necessarily have to halve the vspd. You might do vspd/=3 or vspd/=4 or whatever feels right. You can even do vspd=0, but usually that's a bit abrupt and looks weird. Basically, as long as you bring vspd towards 0, it's gonna work.
Wow, this is way better and way easier than everything else I was doing. Thanks to both you, much appreciated. Also glad to know that people in this community are actually willing to help complete beginners. Thanks again.
 
E

EmreSins

Guest
The way I like to do this is set up a hspd variable that actually controls the movement of the player, while the movement keys just control the variable.
So, kinda like this:

Code:
if (keyboard_check(vk_right)){
    hspd+=1;
}

if (keyboard_check(vk_left)){
    hspd-=1;
}

if (!keyboard_check(vk_left) && !keyboard_check(vk_right)){
    hspd-=sign(hspd);
}

//the code up until now is basically what I've explained
//above - the movement keys control hspd

hspd = clamp(hspd, -maxhspd, maxhspd);
//this makes sure hspd doesn't exceed
//the maximum movement speed

if (place_meeting(x+hspd, y, o_wall)){
    while (!place_meeting(x+sign(hspd), y, o_wall)){
        x+=sign(hspd);
    }
    hspd=0;
}
//the above is your basic horizontal collision.
//If the player is going to collide with the wall,
//move them pixel by pixel until they're right
//next to the wall, then set hspd to 0.

x+=hspd;
//if the player didn't collide with the wall,
//then just move him to where he's supposed to be
If you fiddle with this a bit and give it some thought, I'm sure you can get it to work!
Feel free to ask for further explanation if you didn't understand some part of this.
It worked very well! But there's a problem.
I changed hspd += 1 and hspd -= 1 to hspd += 0.2 and hspd -= 0.2
It works but when i stop, the player slightly moves. Please help
 

Simon Gust

Member
It worked very well! But there's a problem.
I changed hspd += 1 and hspd -= 1 to hspd += 0.2 and hspd -= 0.2
It works but when i stop, the player slightly moves. Please help
what is your maxhspd variable set to? If it has decimals, you might get in trouble.
Say your hspd is 3.5 currently, if you press nothing
it will reduce to 2.5, then 1.5 then 0.5, then -0.5, then 0.5 again but will never be 0.
The effect will be the player shacking.

I can also come down to a floating point precision error where values end up with something like 0.999999999 making it -0.000000001 in the next step and back to 0.999999999, a back and forth but never 0.
The effect will be the player moving to the right every second step.
 
E

EmreSins

Guest
what is your maxhspd variable set to? If it has decimals, you might get in trouble.
Say your hspd is 3.5 currently, if you press nothing
it will reduce to 2.5, then 1.5 then 0.5, then -0.5, then 0.5 again but will never be 0.
The effect will be the player shacking.

I can also come down to a floating point precision error where values end up with something like 0.999999999 making it -0.000000001 in the next step and back to 0.999999999, a back and forth but never 0.
The effect will be the player moving to the right every second step.
My maxhspd is 5
 
I wrote myself a simple script the other day to do this. You send it the value you want to change, the target value, and the amount you want to change it by.
But I also got it to check if the difference between the two values is larger than the change. If it isn't, then it just makes the value equal the target.
I don't have my PC with me but it was something like this:
Code:
if((max(current_value, target_value) - min(current_value, target_value)) < change_value)
{
    current_value = target_value;
}
Pretty sure that's what I have. It's part of what I use for my movement acceleration. I may post the whole script later, I don't know.
 
Top