GMS 2 Jumping mechanic issue

F

Felipe Paluco

Guest
Hello Guys, i'm actually trying to study GML/Programation Logic and in the same time developing a game. (On GMS 2)
I'm studying with videos on YouTube. On the past 2 weeks i'm developing and studying the method to create a game using the HeartBeast video's, to be more precise, the "Hack'n'Slash Course" of him.

I successfully create the horizontal colision, learned the sprite animation process using the method of state-machine. I expanded the functions that he presents on the video, creating a "crounch state" or a third attack on the combo mechanic that he apply on the course.

But i having issues to do a thing: A Jump Mechanic with vertical colision.

How i pretend to make this work:
  • The player jumps, the sprite changes to the jumping sprite
  • When the player reach the maximum determined altitude, the player start to fall and the sprite changes to the falling sprite (this sprite will be applied everytime the player fall's, independent of him jumping or not, e.g: falling in a hole.)
  • The player cannot attack, slide (the same thing to the roll state created by HeartBeast on the course, i changed a little heh) and must importantly he cannot jump on the air. Just in contact with a solid surface.
(probably i should use the state-machine, like "while player jumping, he execute blablablabla)

But i tried on many forms using the way he make on the course, but i don't get success. (and putting some code of another guys of plataform to understand and adapt to my code)
If i make the player jump and collide, i can't make stop be possible to slide or attack on the air, or vice versa.
And i don't give any idea how to make that, or apply to the code and logic of HeartBeast.

move_and_collide script (the collision script)
Code:
///@arg Xspeed
///@arg Yspeed

if not place_meeting(x+argument0, y, obj_ground)
{
    x += argument0;
}

if place_meeting(x, y+argument1, obj_ground)
{
    y += argument1;
}
Step Event of the Player Object:
Code:
key_mapping()
switch (state) {
 
    #region Move State
    case "Move":
    if right {
        move_and_collide(run_speed, 0);
        image_xscale = 2;
        sprite_index = s_player_run;
        image_speed = 0.8;
    } if left {
        move_and_collide(-run_speed, 0);
        image_xscale = -2;
        sprite_index = s_player_run;
        image_speed = 0.8;
    }
    if not right and not left {
        sprite_index = s_player_idle;
        image_speed = 1.1;
    }
    if slide {
    image_index = 0;
    state = "Slide";
    }
    if attack {
        image_index = 0;
        state = "Attack_One";
    }
    if crounch {
        sprite_index = s_player_crounch;
        image_speed = 1.1;
        state = "Crounching"
    }
    break;
    #endregion
     #region Slide State
    case "Slide":
        sprite_index = s_player_slide;
        image_speed = 1.6;
        if image_xscale == 2 {
            move_and_collide(slide_speed, 0);
        }
        if image_xscale == -2 {
            move_and_collide(-slide_speed, 0);
        }
    break;
    #endregion
    #region Crounching State
 
    case "Crounching":
    if crounch {
        sprite_index = s_player_crounch;
        image_speed = 1.1;
    }
    if keyboard_check_released(vk_down) {
    state = "Move"
    }
    break;
    #endregion
 
    #region Attack One
    case "Attack_One":
        sprite_index =  s_player_attack_one;
        image_speed = 0.8;
        if right then image_xscale = 2;
        if left then image_xscale = -2;
    if attack and animation_hit_frame_range(3.5, 5)
    {
        image_index = 0;
        state = "Attack_Two"
    }
    break;
    #endregion
    #region Attack Two
    case "Attack_Two":
        sprite_index = s_player_attack_two;
        image_speed = 0.8;
        if right then image_xscale = 2;
        if left then image_xscale = -2;
    if attack and animation_hit_frame_range(2, 5)
    {
        image_index = 0;
        state = "Attack_Three"
    }
    break;
    #endregion
    #region Attack Three
    case "Attack_Three":
    sprite_index = s_player_attack_three;
    image_speed = 0.8;
        if right then image_xscale = 2;
        if left then image_xscale = -2;
    break;
    #endregion
}
Create Event of Object Player:
Code:
 image_speed = 0.6;
state = "Move";
run_speed = 3.5;
slide_speed = 8;
Animation End Event of Object Player:

Code:
if state == "Attack_One" or state == "Attack_Two" or state == "Attack_Three" or state == "Slide" {
    state = "Move";
    image_index = 0;
}
Animation_hit_frame_range Script:
Code:
///@description Verify the number of index sprite frame to a other higher than.
///@arg low
///@arg high

return image_index >= argument0 and image_index <= argument1;

Key_Mapping Script:
Code:
//Key Mapping
left = keyboard_check(vk_left)
right = keyboard_check(vk_right)
slide = keyboard_check_pressed(vk_shift)
attack = keyboard_check_pressed(ord("Z"))
crounch = keyboard_check_pressed(vk_down)

Thank's for the becoming support. :duck:














 
Last edited by a moderator:

Slyddar

Member
His move and collide script is different to how he/I would normally do it. It doesn't seem very flexible, and doesn't cater for vertical movement stopping once it jumps. It's just for a simple game, as far as I can tell. You really would be better off using a horiztonal speed and vertical speed variable, like hsp and vsp, and controlling things yourself.

So you would normally have a key assigned to jump, added to your key_mapping script.
Code:
jump = keyboard_check_pressed(vk_space)
Then in your move case, check for the jump key being pressed, change state, change sprite, set image_index to 0.
Code:
if jump {
  state = "Jump";
  sprite_index = s_player_jump;
  image_index = 0;
  vsp = -6;  //how high you want to jump
}
Then create a jump state that runs in the air.
Code:
//jump state
vsp += 0.3;  //gravity
y+=vsp;
The problem above is no collision code, so you will never exit the state or land. You need a vertical collision script. Just use the standard hsp/vsp script, like this:
Code:
/// collision()
if place_meeting(x+hsp, y, obj_ground)
{
while !place_meeting(x + sign(hsp), y, obj_ground)
    x += sign(hsp);
    hsp = 0;
}
x+=hsp;

if place_meeting(x, y+vsp, obj_ground)
{
while !place_meeting(x, y + sign(vsp), obj_ground)
    y += sign(vsp);
    vsp = 0;
}
y+=vsp;
Now the jump state can be:
Code:
//jump state
vsp += 0.3;  //gravity
if place_meeting(x, y + 1, obj_ground) state = "Move";
//run the collision script
collision();
Changes would need to be made else where in his code to cater for these changes though, but I'll leave that for you. Check out Shaun Spalding's tutorial for a better method. My series even does it better imho, but it's in DnD.
 
Last edited:
F

Felipe Paluco

Guest
Alright, i have adapted your code to mine. (and the most importantly, i understood him)

Apparently all jump mechanic is OK, including vertical and horizontal collision, but have a 2 problems:
  • he doens't moving to right and left.
  • he doens't fall naturally without i press the jump key in any moment. (just start to apply the "gravity" when i press jump key)
I trying to use the hsp = +3 to right direction (and hsp = -3 for left direction) for that.
But doesn't seem have any effect. And about the "falling problem" i think that i used to put something on the Create Event, but i don't have any idea.

Create Event
Code:
image_speed = 0.6; // Moving speed of idle/run animation
state = "Move"; // defines the default state.
Step Event

Code:
key_mapping()
switch (state) {
 
    #region Move State
    case "Move":
    if right {
        hsp = 4;
        image_xscale = 2;
        sprite_index = s_player_run;
        image_speed = 0.8;
    } if left {
        hsp = -4;
        image_xscale = -2;
        sprite_index = s_player_run;
        image_speed = 0.8;
    }
      if jump {
        state = "Jump";
        sprite_index = s_player_jump;
        image_index = 0;
        vsp = -4;
    }
    if not right and not left {
        sprite_index = s_player_idle;
        image_speed = 1.1;
    }
    if slide {
    image_index = 0;
    state = "Slide";
    }
    if attack {
        image_index = 0;
        state = "Attack_One";
    }
    if crounch {
        sprite_index = s_player_crounch;
        image_speed = 1.1;
        state = "Crounching"
    }
    break;
    #endregion
    #region Slide State
    case "Slide":
        sprite_index = s_player_slide;
        image_speed = 1.6;
        if image_xscale == 2 {
            hsp = 8;
        }
        if image_xscale == -2 {
            hsp = -8;
        }
    break;
    #endregion
    #region Crounching State
 
    case "Crounching":
    if crounch {
        sprite_index = s_player_crounch;
        image_speed = 1.1;
    }
    if keyboard_check_released(vk_down) {
    state = "Move"
    }
    break;
    #endregion
 
    #region Jump State
    case "Jump":
    vsp += 0.3;  //gravity
    if place_meeting(x, y + 1, obj_ground) state = "Move";
    //run the collision script
    collision();
    break;
    #endregion
 
    #region Attack One
    case "Attack_One":
        sprite_index =  s_player_attack_one;
        image_speed = 0.8;
        if right then image_xscale = 2;
        if left then image_xscale = -2;
    if attack and animation_hit_frame_range(3.5, 5)
    {
        image_index = 0;
        state = "Attack_Two"
    }
    break;
    #endregion
    #region Attack Two
    case "Attack_Two":
        sprite_index = s_player_attack_two;
        image_speed = 0.8;
        if right then image_xscale = 2;
        if left then image_xscale = -2;
    if attack and animation_hit_frame_range(2, 5)
    {
        image_index = 0;
        state = "Attack_Three"
    }
    break;
    #endregion
    #region Attack Three
    case "Attack_Three":
    sprite_index = s_player_attack_three;
    image_speed = 0.8;
        if right then image_xscale = 2;
        if left then image_xscale = -2;
    break;
    #endregion
}
 
Last edited by a moderator:

Slyddar

Member
You replaced your collision script, so you now need to run the new collision() script in all states at the end of them. Add the "vsp += 0.3; //gravity" line to the top of the collision script instead of in the jump state.

In coding, you need to take a step back, think what you want to do, and how it can be achieved when you run into problems. I'm not going to rewrite everything, as there are lots of changes to get it to do what you want. As I mentioned, I really suggest you watch Shaun Spaldings tutorial series, it's much better, and you will learn the skills you need.
 
F

Felipe Paluco

Guest
All right, I'll check out these videos and take a few steps back! Thanks for the help. :p
 
Top