Jumping and attacking [SOLVED]

maranpis

Member
Hello guys:

I was trying to figure out in GM2, how to perform a melee attack in the air maintaining the gravity and the previous horizontal and vertical speed.

At the moment when I perfom the attack in the air the player stops in the air and execute the animation.

This is the moving script

Code:
if attack=false
{
//MOVE RIGHT AND LEFT

        if keyboard_check(vk_right)
        {
        hospeed=20;
        sprite_index=s_Running
        image_xscale=1;
        mask_index=rough_player;
        }
        else if keyboard_check(vk_left)
        {
        hospeed=-20    ;
        sprite_index=s_Running
        image_xscale=-1;
        mask_index=rough_player;
        }
        else
        {
     
        hospeed=0;
        sprite_index=s_Idle;
        mask_index=rough_player;
        }
     
//GRAVITY AND JUMPING

        if !place_meeting (x,y+1,o_Ground)
        {
     
        vespeed+=grav
        sprite_index=s_Jump;
        mask_index=rough_player;
        }
        else
        {
        if keyboard_check_pressed(vk_up)
        {
     
        vespeed=-20;
        sprite_index=s_Jump;
        mask_index=rough_player;
        }
        }
     
}
                     

     
// COLLISION X
     
if place_meeting(x+hospeed,y,o_Ground)
{
        while !place_meeting (x+sign(hospeed),y,o_Ground)
        {
        x+=sign(hospeed);
        }
        hospeed=0;    
}

x+=hospeed;


// COLLISION Y

if place_meeting(x,y+vespeed,o_Ground)
        {
        while !place_meeting(x,y+sign(vespeed),o_Ground)
        {
        y+=sign(vespeed);
        }
        vespeed=0;
}

y+=vespeed;
and this is the Global Left mouse Pressed event

Code:
if attack=false
{
        attack=true;
        sprite_index=s_Attack;
        image_index=0;
        mask_index=rough_player;    
}
This is the animation End event

Code:
if attack=true
        {
        attack=false;
        script_execute(Move_state);    
     
        }
¿Where and how can i set the conditions to perform the attack maintaining the gravity and the previous horizontal and vertical speed?

Thanks for your help :)
 
B

Brian Le

Guest
I don't know much about gravity, because most of my games is top-viewed. However, maybe you can create a sprite in which the player is flying and attacking simultaneously? And then create a combo press, like W+Space, after that use sprite_index = spr_jump_attack
Hope that helps!
 

maranpis

Member
I don't know much about gravity, because most of my games is top-viewed. However, maybe you can create a sprite in which the player is flying and attacking simultaneously? And then create a combo press, like W+Space, after that use sprite_index = spr_jump_attack
Hope that helps!
Thanks! i'll try this option :) I think there is another way to do it with "if" statements in but at the moment i haven't found out
 
M

Mtyler87

Guest
It looks like you've put your movement code under attack=false which would cause your movement to stop as soon as you press the attack button due to attack=true being activated, try putting your movement code somewhere where it doesn't require the condition attack=true or attack=false to trigger.
Hope this helps.
 

maranpis

Member
It looks like you've put your movement code under attack=false which would cause your movement to stop as soon as you press the attack button due to attack=true being activated, try putting your movement code somewhere where it doesn't require the condition attack=true or attack=false to trigger.
Hope this helps.

Hi Mtyler87 at the moment I don't know how to do it in other way (my coding skills are very limited), right now I'm trying with state machines if I have some good results I will post it.

Thanks for your help :)
 
M

Mtyler87

Guest
Ah sorry, was a bit confusing how I said it, if you just remove
Code:
if attack=false
{
above the movement code and it's corresponding '}' that closes the code it should work fine.

Code:
//MOVE RIGHT AND LEFT

       if keyboard_check(vk_right)
       {
       hospeed=20;
       sprite_index=s_Running
       image_xscale=1;
       mask_index=rough_player;
       }
       else if keyboard_check(vk_left)
       {
       hospeed=-20    ;
       sprite_index=s_Running
       image_xscale=-1;
       mask_index=rough_player;
       }
       else
       {
   
       hospeed=0;
       sprite_index=s_Idle;
       mask_index=rough_player;
       }
   
//GRAVITY AND JUMPING

       if !place_meeting (x,y+1,o_Ground)
       {
   
       vespeed+=grav
       sprite_index=s_Jump;
       mask_index=rough_player;
       }
       else
       {
       if keyboard_check_pressed(vk_up)
       {
   
       vespeed=-20;
       sprite_index=s_Jump;
       mask_index=rough_player;
       }
       }
   

                   

   
// COLLISION X
   
if place_meeting(x+hospeed,y,o_Ground)
{
       while !place_meeting (x+sign(hospeed),y,o_Ground)
       {
       x+=sign(hospeed);
       }
       hospeed=0;   
}

x+=hospeed;


// COLLISION Y

if place_meeting(x,y+vespeed,o_Ground)
       {
       while !place_meeting(x,y+sign(vespeed),o_Ground)
       {
       y+=sign(vespeed);
       }
       vespeed=0;
}

y+=vespeed;
 

maranpis

Member
Hello Mtyler87 actually this is an old code at the moment and I'm experimenting with the state machines that is giving way better results. I will now try to solve the jumping and attacking issue with this new code i'm making.
 

Simon Gust

Member
right now I'm trying with state machines if I have some good results I will post it.
Thanks for your help :)
Here is some things that are good to know when doing state machines:
- never have physical Motion in a state, leave it outside the machine
Code:
//GRAVITY AND JUMPING
if (!place_meeting (x, y+1, o_Ground))
{
    vespeed += grav;
}
else
{
  if keyboard_check_pressed(vk_up)
  {
    vespeed=-20;
  }
}

switch (state)
{
  case idle:
  case attack:
  ...
}
note that I removed the sprite_index = and the mask_index =.
This is because Animation should be handled in state machines but motion shouldn't.

As for states to use, you should consider doing a state that handles Walking, Standing, jumping in one single state.
I usually call this state "chill". It has 3 substates (animations):
Standing, Walking, jumping.

Code:
switch (state)
{
  case chill:
  {
    if (on_ground)
    {
      if (moving)
      {
        sprite_index = spr_player_move;
        image_speed = abs(hospeed) / 8;
      }
      else
      {
        sprite_index = spr_player_chill;
        image_speed = 0;
      }
    }
    else
    {      
      sprite_index = spr_player_jump;
      image_speed = 0;
    }
  }
  break;
}
PS. this is pseudocode

Every other action should occupy a state.
In that state you are allowed to do animation and limited motion like a push forward or increased speed for duration of time.

One last Thing is that the order of functions is very important.
first comes Motion and physics,
then comes collision checking
and last comes animation handling of the basic states as Long as they don't feature any kind of motion code.
 

TheouAegis

Member
Code:
if state==idle_state || state==walking_state
{
    hospeed = (keyboard_check(vk_right) - keyboard_check(vk_left) ) * 20;
    if hospeed != 0
    {
        sprite_index = s_running;
        image_xscale = sign(hospeed);
        state = walking_state;
    }
    else
    {
        sprite_index = s_idle;
    }
}
Or better yet, put the movement code inside a script and call that script from the idle and walking states.

So your movement code only happens when the player is idle or running. Your horizontal speed won't be able to be changed outside any other state unless acted upon by external forces such as a wall.
 

maranpis

Member
I think i reached to some kind of "solution"(seems working fine) i will introduce you step by step:

1 I learned about how to do state machines in this tutorial:

2.I did this in my create Player event
enum states
{
idle,
jumping,
attacking,
attacking_jumping
}

state=states.idle;

3. In the move state i change for the attack state script (if the player on the ground) and attack_jumping state(if the player is in the air) :

Code:
//MOVE RIGHT AND LEFT AND JUMP

        if keyboard_check(vk_right)
        {  
        hospeed=20;  
        mask_index=rough_player;
        sprite_index=s_Running
        image_speed=1;
        image_xscale=1;
       
        }
        else if keyboard_check(vk_left)
        {
        hospeed=-20    ;
        sprite_index=s_Running
        image_xscale=-1;
        image_speed=1;
       
        mask_index=rough_player;
        }
        else
        {
       
        hospeed=0;
        sprite_index=s_Idle;
        image_speed=1;
        mask_index=rough_player;
        }
       
//JUMP , NUMBER OF JUMPS,PREVENTING WALL JUMP  
       
    //NUMBER OF MAXIMUM JUMPS  
       
        if place_meeting(x,y+1,o_Ground)
        {
        jump=jumpsmax;
        }
       
    //JUMP  
        if keyboard_check(vk_up) and jump > 0
        {
        jump-=1;
        vespeed=-40;
        sprite_index=s_Jump;
        image_speed=1;
        mask_index=rough_player;
        }
               
        if keyboard_check(vk_up) and place_meeting(x+1,y,o_Ground)||place_meeting(x-1,y,o_Ground)
        {
        jump=0;
        }
       
//ATTACK STATE

        if mouse_check_button_pressed (mb_left) and place_meeting(x,y+1,o_Ground) // ground attack
        {
        state=states.attacking;
        }
        else if mouse_check_button_pressed (mb_left) and !place_meeting(x,y+1,o_Ground) //air attack
        {
        state=states.attacking_jumping;
        }
       
       
       
       
               
sc_Collisions_Gravity();
4.This is the attack state script if the player is on the ground:

Code:
/SETTING THE FRAME TO  FRAME=0

if sprite_index!=s_Attack{
sprite_index=0;
}

//ATTACK


hospeed=0;
vespeed=0;
sprite_index=s_Attack;
image_speed=1;
mask_index=rough_player;




// attack one time and change state

if image_speed>0 and image_index==24
{
hospeed=0;
vespeed=0;
image_speed=0;
state=states.idle;
}
5.This is the attack state if the player is in the air:

Code:
//SETTING THE FRAME TO TO FRAME=0

if sprite_index!=s_Attack
            {
            sprite_index=0;
            }

//ATTACK
if vespeed>0
            {

            sprite_index=s_Attack;
            image_speed=1;
            mask_index=rough_player;
            }
else if vespeed<0
            {

            sprite_index=s_Attack;
            image_speed=1;
            mask_index=rough_player;
            }
else if vespeed=0
            {
            sprite_index=s_Attack;
            image_speed=1;
            mask_index=rough_player;
            }


if image_speed>0 and image_index==24
{
image_speed=0;
state=states.idle;
}





sc_Collisions();
I know this is a pretty rough code but at the moment works.
 

maranpis

Member
Here is some things that are good to know when doing state machines:
- never have physical Motion in a state, leave it outside the machine
Code:
Every other action should occupy a state.
In that state you are allowed to do animation and limited motion like a push forward or increased speed for duration of time.

One last Thing is that the order of functions is very important.
first comes Motion and physics,
then comes collision checking
and last comes animation handling of the basic states as Long as they don't feature any kind of motion code.[/QUOTE]
Thanks for your information guys :)
 

maranpis

Member
Code:
if state==idle_state || state==walking_state
{
    hospeed = (keyboard_check(vk_right) - keyboard_check(vk_left) ) * 20;
    if hospeed != 0
    {
        sprite_index = s_running;
        image_xscale = sign(hospeed);
        state = walking_state;
    }
    else
    {
        sprite_index = s_idle;
    }
}
Or better yet, put the movement code inside a script and call that script from the idle and walking states.

So your movement code only happens when the player is idle or running. Your horizontal speed won't be able to be changed outside any other state unless acted upon by external forces such as a wall.
Now i have problem about blurriness.

When the player moves, looks so blurry i set the game preference at 60fps and my animations has at least 25 frames(sub_images). :(
 

TheouAegis

Member
if it is blurring horizontally, then either your view is being moved at fractional intervals or somehow your horizontal speed is being modified such that it is a fraction. it is also entirely possible that your monitor is just causing coasting and it is simply an optical illusion. You could try taking a screenshot of the blur, if it does not show up in the screen shot then it is just your monitor.

but like I said, simply moving left and right should not cause any blurry. but if this is happening while you are jumping and attacking, then the blur is typically because you are moving at fractional intervals and the view is being updated at fractional intervals.
 
Top