[SOLVED] Having Trouble with Variable Jumping

A

arirish

Guest
I'm pretty happy with how my movement is shaping up, but one thing I can't get my head around is variable jumping. I have tried, failed, moved on to something else, then come back to it 4 or 5 times already. I've studied various tutorials and videos, and looked at old forum posts on the subject, and nothing seems to work. I suspect it's to do with the way my FSM is set up.

In my IdleState script, here's the code for jumping:
Code:
if kjump && jumps>0 {
    vsp=-jmpspd;
    jumps-=1;
    StateSwitch("Jump");
}
kjump is keyboard_check_pressed(jumpbutton). StateSwitch switches to the JumpState script, which right now is an utter mess having been through countless tweaks and overhauls, but looks like this:

Code:
if kjumpheld {while vsp<-jmpspd  {vsp-=1}}
  
if keyboard_check_released(global.controls[4])
  {vsp*=0.5}
    
if vsp>0 {StateSwitch("Fall");}
I see WHY this doesn't work, but I don't see what I can do to make it work. Basically I need it so that a tap of the jump key gives a jump of about 75% maximum, while holding it gives you a higher jump. I tried 'vsp=-(jmpspd/2)' to give the player a boost of half the regular jump, hoping the 'kjumpheld' line would do the rest, even if it would look a bit odd, but it just gave me a very stunted jump. I'm lost.
 
M

maratae

Guest
I'm pretty happy with how my movement is shaping up, but one thing I can't get my head around is variable jumping. I have tried, failed, moved on to something else, then come back to it 4 or 5 times already. I've studied various tutorials and videos, and looked at old forum posts on the subject, and nothing seems to work. I suspect it's to do with the way my FSM is set up.

In my IdleState script, here's the code for jumping:
Code:
if kjump && jumps>0 {
    vsp=-jmpspd;
    jumps-=1;
    StateSwitch("Jump");
}
kjump is keyboard_check_pressed(jumpbutton). StateSwitch switches to the JumpState script, which right now is an utter mess having been through countless tweaks and overhauls, but looks like this:

Code:
if kjumpheld {while vsp<-jmpspd  {vsp-=1}}
 
if keyboard_check_released(global.controls[4])
  {vsp*=0.5}
   
if vsp>0 {StateSwitch("Fall");}
I see WHY this doesn't work, but I don't see what I can do to make it work. Basically I need it so that a tap of the jump key gives a jump of about 75% maximum, while holding it gives you a higher jump. I tried 'vsp=-(jmpspd/2)' to give the player a boost of half the regular jump, hoping the 'kjumpheld' line would do the rest, even if it would look a bit odd, but it just gave me a very stunted jump. I'm lost.
I don't understand your need for the while loop.
If what you're trying to accomplish is a variable jump height, try something like:
Code:
if (!kjumpheld && vsp < 0){vsp = vsp * 0.5}
(and adjust that 0.5)
I'm doing this from memory but the logic is something like that.
 
A

arirish

Guest
As I said, the current code is a mess, cobbled together from various bits and pieces and with no real expectation on my part that it would work. I tried your suggestion, but with the same end result. That's not to say your code doesn't work in theory; I'm pretty sure it's the way my states are set up and changing, rather than the variable jump code itself.
 
I'm not sure about he first line, I think you can remove it really. The rest should be enough. Can you comment it out and see what happens?

Also just a tip, you can organize the states with a enum instead. It's much easier to keep track of them and you won't have to worry about misspelling when you change state.

enum state {
idle, move, jump, fall, attack, etc...
}
Then you simply call one of them like this:
state.fall

The best part is that they are included in the autocomplete and they are faster since behind the hood they are really just numbers.
 
P

Pyxus

Guest
I'm pretty happy with how my movement is shaping up, but one thing I can't get my head around is variable jumping. I have tried, failed, moved on to something else, then come back to it 4 or 5 times already. I've studied various tutorials and videos, and looked at old forum posts on the subject, and nothing seems to work. I suspect it's to do with the way my FSM is set up.

In my IdleState script, here's the code for jumping:
Code:
if kjump && jumps>0 {
    vsp=-jmpspd;
    jumps-=1;
    StateSwitch("Jump");
}
kjump is keyboard_check_pressed(jumpbutton). StateSwitch switches to the JumpState script, which right now is an utter mess having been through countless tweaks and overhauls, but looks like this:

Code:
if kjumpheld {while vsp<-jmpspd  {vsp-=1}}
 
if keyboard_check_released(global.controls[4])
  {vsp*=0.5}
   
if vsp>0 {StateSwitch("Fall");}
I see WHY this doesn't work, but I don't see what I can do to make it work. Basically I need it so that a tap of the jump key gives a jump of about 75% maximum, while holding it gives you a higher jump. I tried 'vsp=-(jmpspd/2)' to give the player a boost of half the regular jump, hoping the 'kjumpheld' line would do the rest, even if it would look a bit odd, but it just gave me a very stunted jump. I'm lost.
Code:
var vacc, on_ground;
vacc = 6;
on_ground = place_meeting(x, y+1, obj_solid);

if (jump_input && on_ground) {
   vsp = -vacc;
}
if(jump_input_released && vsp <= -vacc/3) {
   vsp = -vacc/3
}
 
N

NeZvers

Guest
my 2 cents, how I'd be setting up your approach
Code:
var kjump = keyboard_check_pressed(jumpbutton);
var grounded = place_meeting(x,y+1, o_solid); //whatever you are naming your solid/ wall objects

if (kjump && (grounded || jumps>0))
{
    vsp=-jmpspd;
    jumps--;
    StateSwitch("Jump");
}

//jump state
if (kjumpheld && vsp<0) // holding jump button and going up
{
    vsp += grav; //gravity is set in create event, try starting with 0.2
} 
else // released jump button
{
    vsp = lerp(vsp, 0, 0.02); // loose momentum, change 0.02 speed
    if(vsp<0 && vsp>0.01){vsp = 0;} //lerp can go endlessly to actually reach 0
}
if (vsp>0) {StateSwitch("Fall");}

// Fall state
var grounded = place_meeting(x,y+1, o_solid); //whatever you are naming your solid/ wall objects

if (!grounded)
{
    vsp+= grav
}
 
Last edited:
A

arirish

Guest
Also just a tip, you can organize the states with a enum instead. It's much easier to keep track of them and you won't have to worry about misspelling when you change state.
I actually just switched FROM an enum system because I found this one more flexible (and just personally find it easier to type "Jump" than to remember state.jump). My states are pretty well organized so I'm not too concerned about keeping track. I probably could combine the two systems and get the best of both worlds, but at this point I don't feel like changing everything over again.

Thanks everybody for your input. While I was laying in bed last night thinking about this, I thought of a couple of other (what I thought were very trivial) things I wanted to tweak, and after implementing them they seem to have fixed the problem. My variable jumping works now. Here's the code:

IdleState:
Code:
if kjump && jumps>0 {
    vsp=-jmpspd
    jumps-=1;
    StateSwitch("Jump");
}
JumpState:
Code:
statefall=1;   
  
if (!kjumpheld && vsp < 0){vsp = vsp * 0.5}
if kjumpheld {if vsp>-jmpspd {vsp+=-jmpspd/10}}
and then in my regular step event:
Code:
    //Check if the player should fall
    if vsp>1 && statefall=1 {StateSwitch("Fall")};
statefall is a variable which decides whether or not the player should fall in any given state (for example I don't want them to fall if they're floating in water, or climbing a ladder). Originally statefall was 0 in the jump code, and the Jump script had it's own vsp check to see if it should start falling.

EDIT: Funny. Now that it's working correctly, I've had to change my jmpspd variable and waaay lower it. Guy was doing mega moon jumps :D I LOVE my movement now!
 
Last edited by a moderator:
Top