• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Flinch effect (knockback when player takes damage)

R

Rafael Apolinário

Guest
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.
 

Kyon

Member
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.
 

Ido-f

Member
Add this in your step somewhere:
Code:
if knockx<0{knockx+=.5;} if knockx>0{knockx-=.5;}
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:
R

Rafael Apolinário

Guest
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.

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 :(
 

Attachments

R

Rafael Apolinário

Guest
Just increase the value of the knockback.
Thats in that collision part. Instead of -3 do -6 or something.
(other.knockx=-6;)
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
 

Kyon

Member
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.
 
Top