1. Hey! Guest! The 34th GMC Jam will take place between August 22nd, 12:00 UTC (Thursday noon) and August 26th, 12:00 UTC (Monday noon). Why not join in! Click here to find out more!
    Dismiss Notice

Flinch effect (knockback when player takes damage)

Discussion in 'Programming' started by Rafael Apolinário, Jan 6, 2019.

  1. Rafael Apolinário

    Rafael Apolinário Member

    Joined:
    Jan 6, 2019
    Posts:
    3
    Hi there!

    I am new on Gamemaker Studio 2 and been following Shaun Spalding's youtube videos as I wanted to make my first platformer game. My obj_Player moving system looks pretty much like his:

    var move = key_right - key_left;
    hsp = move * walkspeed;
    vsp = vsp + grv;
    x = x + hsp;
    y = y + vsp;

    I've been trying to make obj_Player get knocked back when it takes damage, not only for visual feedback but to stop taking continuous damage too, as my "timer" system only prevents it to take damage for 1 second

    obj_Player CREATE:
    timer = 60

    obj_Enemy collision w/ obj_Player:

    if (timer <= 0)
    {
    hp--;
    timer = 50
    }

    With this, how can I make the knockback? I've tried to add obj_Player.hspeed -= 1 and obj_Player.vspeed -=1 to the collision event, but it makes my obj_Player fly all over away the room. Also tried obj_Player.hsp -= 3 and obj_Player.vsp -=3 but it only makes the player jump, it looks like hsp doesn't work for this.
     
  2. Kyon

    Kyon Member

    Joined:
    Jun 27, 2016
    Posts:
    467
    I'm not familiar with Shaun's movement system. And because I don't want to rewrite that code, I'd go with a knockback variable.
    CREATE:
    Code:
    knockx=0;
    That first part of your movement code:
    Code:
    var move = key_right - key_left;
    hsp = move * walkspeed;
    vsp = vsp + grv;
    x = x + hsp + knockx;
    y = y + vsp; 
    Add this in your step somewhere:
    Code:
    if knockx<0{knockx+=.5;} if knockx>0{knockx-=.5;}
    Enemy collide w/ obj_player:
    Code:
    if (timer <= 0)
    {
    hp--;
    timer = 50
    other.knockx=-3;
    }


    Anyway, you made a little knockback now. Maybe check for image_xscale or direction he is facing and make it other.knockx=3 if he needs to knockback to the right instead of left.
    To make it really really cool, change the image_blend while being knocked back.
    So that part could be this:
    Code:
    if knockx<0{knockx+=.5; image_blend=c_red;}else if knockx>0{knockx-=.5; image_blend=c_red;}else{image_blend=c_white;}



    Kyon.


    EDIT:
    if it ain't clear what this does exactly. I made a variable called knockx and your player moves updates the x position with x+knockx. So if knockx = 3 it'll move to the right with 3 pixels a frame.
    What I did in the step is, when knockx is higher of lower than 0, gradually get it back to 0.
    At collision knockx is set to -3. but then slowly to 0 because of that step event code, making a smooth knockback effect.
    The last part makes it so that if your player is still in "knockback-mode" it's image_blend is c_red, giving it a red tint. c_white resets it back to normal.
     
    Rafael Apolinário likes this.
  3. Ido-f

    Ido-f Member

    Joined:
    Feb 19, 2018
    Posts:
    117
    This part would cause problems if he changes the knockback value to not be a whole multiplication of 0.5. I'd use an Approach script that doesn't overshoot a target value, in this case 0.
    Will edit with that script when I get to my pc.

    edit- this is shaun spaulding's:
    Code:
    ///@func Approach(input, destination, step)
    ///@arg input
    ///@arg destination
    ///@arg step
    // Moves "a" towards "b" by "amount" and returns the result
    // Nice because it will not overshoot "b", and works in both directions
    // Examples:
    //      speed = Approach(speed, max_speed, acceleration);
    //      hp = Approach(hp, 0, damage_amount);
    //      hp = Approach(hp, max_hp, heal_amount);
    //      x = Approach(x, target_x, move_speed);
    //      y = Approach(y, target_y, move_speed);
    
    if (argument0 < argument1)
    {
        argument0 += argument2;
        if (argument0 > argument1)
            return argument1;
    }
    else
    {
        argument0 -= argument2;
        if (argument0 < argument1)
            return argument1;
    }
    return argument0;
    
     
    Last edited: Jan 6, 2019
    Rafael Apolinário likes this.
  4. Rafael Apolinário

    Rafael Apolinário Member

    Joined:
    Jan 6, 2019
    Posts:
    3

    I tried with these values, but the knockback ended being short, so if I keep pressing "D" to walk, the player will keep going right and pass through the enemy :(
     

    Attached Files:

  5. Kyon

    Kyon Member

    Joined:
    Jun 27, 2016
    Posts:
    467
    Just increase the value of the knockback.
    Thats in that collision part. Instead of -3 do -6 or something.
    (other.knockx=-6;)
     
    Rafael Apolinário likes this.
  6. Rafael Apolinário

    Rafael Apolinário Member

    Joined:
    Jan 6, 2019
    Posts:
    3
    Feeling a bit ashamed for not thinking this before lol Thank you anyway!
    And is there a way that I can make the player not capable of walking right after being hit? Just to prevent it to keep moving for a bit before it can walk again
     
  7. Kyon

    Kyon Member

    Joined:
    Jun 27, 2016
    Posts:
    467
    Yeah sure!
    Code:
    var move = key_right - key_left;
    hsp = move * walkspeed;
    if knockx!=0{hsp=0;}
    vsp = vsp + grv;
    x = x + hsp + knockx;
    y = y + vsp;
    
    So this resets hsp and makes it 0 when the player is still being knocked back.
    Also, take note of what Ido-f said. Do not change the knockx to a amount that's not a multiplication of 0.5
    Otherwise it won't work haha.
     

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