• 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!

How to make player recoil when hit by an enemy?

pixeltroid

Member
In the players collision event with the enemy I changed hspeed and vspeed -= 1 and it seems to somewhat work, EXCEPT the player starts to slide away from the enemy and with more hits, he becomes immobile.

Is there a better way to achieve the "recoil" effect (Example - the way Samus Aran acts when she is hit by an enemy)?

Any help would be appreciated!

P.S - Programming noob here. Please just tell me what code I can use and where to place it.
 
Last edited:
S

Shariku Onikage

Guest
Player's create Event
Code:
recoilSpeed=10;//set recoilSpeed as the speed you wish them to be flung backwards, reduce this if they recoil too fast
playerRecoil=-1;
Player's step event
Code:
if (whateverYourCodeIsForWhenThePlayerGetsShot){  //basically add this to whatever controls the effects of when your player gets hit
playerRecoil=20; // activates and controls how long the recoil effect lasts for, reduce this if they fly too far
}

if(playerRecoil!=-1){
    playerRecoil-=1;
   direction = image_angle-180; //opposite direction that the player is currently facing
   speed= recoilSpeed;
}
Hope that helps.
 

pixeltroid

Member
Player's create Event
Code:
recoilSpeed=10;//set recoilSpeed as the speed you wish them to be flung backwards, reduce this if they recoil too fast
playerRecoil=-1;
Player's step event
Code:
if (whateverYourCodeIsForWhenThePlayerGetsShot){  //basically add this to whatever controls the effects of when your player gets hit
playerRecoil=20; // activates and controls how long the recoil effect lasts for, reduce this if they fly too far
}

if(playerRecoil!=-1){
    playerRecoil-=1;
   direction = image_angle-180; //opposite direction that the player is currently facing
   speed= recoilSpeed;
}
Hope that helps.
what do you mean by "whatever controls the effects of when your player gets hit"?
I've just got a collision event with the enemy that reduces player hp by -1.
 
T

TDSrock

Guest
You need to detect the hit somehow. I for example would have a Boolean called hit that might get set to true, if it is true it means my character was hit.

So in the if he referenced I would place my Boolean.
 
S

Shariku Onikage

Guest
In that case :

create event
Code:
recoilSpeed=10;//set recoilSpeed as the speed you wish them to be flung backwards, reduce this if they recoil too fast
playerRecoil=-1;
playerStop=-1;
collision event
Code:
playerRecoil=20;
step event
Code:
if(playerRecoil!=-1){
    playerRecoil-=1;
   direction = image_angle-180; //opposite direction that the player is currently facing
   speed= recoilSpeed;
   playerStop=1;
}

if(playerRecoil=-1 && playerStop=1){
    speed=0;
    playerStop=-1;
    }
EDITED: Just realised that i hadn't given anything to have the player stop recoiling.
 
Last edited by a moderator:
T

TDSrock

Guest
Instead of asking us, throw it in your game, see if it works ;)
If not, come back, tell us what you did, what you expected and what actually happened.
 

pixeltroid

Member
In that case :

create event
Code:
recoilSpeed=10;//set recoilSpeed as the speed you wish them to be flung backwards, reduce this if they recoil too fast
playerRecoil=-1;
playerStop=-1;
collision event
Code:
playerRecoil=20;
step event
Code:
if(playerRecoil!=-1){
    playerRecoil-=1;
   direction = image_angle-180; //opposite direction that the player is currently facing
   speed= recoilSpeed;
   playerStop=1;
}

if(playerRecoil=-1 && playerStop=1){
    speed=0;
    playerStop=-1;
    }
EDITED: Just realised that i hadn't given anything to have the player stop recoiling.
Hey its actually working great!
Except, the player only recoils to the left, regardless of where he is facing. How do I fix this?
 
S

Shariku Onikage

Guest
Hey its actually working great!
Except, the player only recoils to the left, regardless of where he is facing. How do I fix this?
Good to hear.
Most likely it's happening because your characters image is fixed at a particular angle regardless of how it moves. The details of 'direction' are dependent on the game being made. In my example it presumes that the player's sprite is always facing the direction your character is moving, hence why 'direction=image_angle-180' (if the image facing forwards is at zero degrees then minus 180 would always be backwards). If it always goes left then it probably means that your player object's sprite stays in a fixed position (in terms of image_angle, 0 (the default)is right, 90 is down, 180 is left and 270 is up), so backwards is always left.

You basically want to set 'direction' in the code i provided to always be the reverse of when your character is moving forwards. If you're not sure what this is please paste your general movement code and we can try and figure it out.
 

pixeltroid

Member
Good to hear.
Most likely it's happening because your characters image is fixed at a particular angle regardless of how it moves. The details of 'direction' are dependent on the game being made. In my example it presumes that the player's sprite is always facing the direction your character is moving, hence why 'direction=image_angle-180' (if the image facing forwards is at zero degrees then minus 180 would always be backwards). If it always goes left then it probably means that your player object's sprite stays in a fixed position (in terms of image_angle, 0 (the default)is right, 90 is down, 180 is left and 270 is up), so backwards is always left.

You basically want to set 'direction' in the code i provided to always be the reverse of when your character is moving forwards. If you're not sure what this is please paste your general movement code and we can try and figure it out.
For basic player movement, I used a script I got from a youtube tutorial by "heartbeast". It is as follows:

{
//moving left right
if keyboard_check(ord("D")) && place_free(x+4,y) && !keyboard_check(ord("A")) {
if (place_free(x,y+1)) {
if (place_free(x+4,y+vspeed)) {
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = 2;
x+=4;
}
} else {
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = 2;
x+=4;
}
} else if keyboard_check(ord("A")) && place_free(x-4,y) && !keyboard_check(ord("D")) {
if (place_free(x,y+1)) {
if (place_free(x-4,y+vspeed)) {
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = -2;
x-=4;
}
} else {
x-=4;
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = -2;
}
} else {
sprite_index = spr_playerstand;
image_speed = .1

}

if (!place_free(x,y+1)) {

//jumping
if keyboard_check_pressed(ord('W')) {
vspeed = -10;
}
} else {
sprite_index = spr_playerjump;
}

if (!place_free(x,y+1)) {


}
}
 
T

TDSrock

Guest
I presume you are altering the direction of the player somewhere else in your code.
You'll need to lock the direction while recoiling.
So find all the places besides this where your player as a line that starts with "direction ="
and do this to them:
Code:
if(!recoiling){
direction = <whatever should be here>;
}

EDIT: based on the two ninja postes that just occured.

You have a four directional movement system. simply look at the states of image_scale_x/y.

You should be able to see some consistency there. From the code I gather this is a top down game(correct?).
 

pixeltroid

Member
You have a four directional movement system. simply look at the states of image_scale_x/y.

You should be able to see some consistency there. From the code I gather this is a top down game(correct?).
No its a platform game W is used for jump. The player should only recoil left or right.
I'm not a programmer have no idea what you mean by "simply look at the states of image_scale_x/y." :-/
 
S

Shariku Onikage

Guest
I presume you are altering the direction of the player somewhere else in your code.
You'll need to lock the direction while recoiling.
So find all the places besides this where your player as a line that starts with "direction ="
and do this to them:
Code:
if(!recoiling){
direction = <whatever should be here>;
}

EDIT: based on the two ninja postes that just occured.

You have a four directional movement system. simply look at the states of image_scale_x/y.

You should be able to see some consistency there. From the code I gather this is a top down game(correct?).
My code presumed top down, seeing this it beginning to look like a platformer (i suppose the Samus reference should of clued me in).

If it is a platformer, try making the following changes (this is kinda getting messy).

create
Code:
facing="right";   presumes the game starts with you facing right, if you're facing left change this to facing="left";
movement code: (look for the lines that start facing)
Code:
{
//moving left right
if keyboard_check(ord("D")) && place_free(x+4,y) && !keyboard_check(ord("A")) {
if (place_free(x,y+1)) {
if (place_free(x+4,y+vspeed)) {
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = 2;
facing="right";; //moving right
x+=4;
}
} else {
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = 2;
x+=4;
facing="right";; //moving right
}
} else if keyboard_check(ord("A")) && place_free(x-4,y) && !keyboard_check(ord("D")) {
if (place_free(x,y+1)) {
if (place_free(x-4,y+vspeed)) {
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = -2;
x-=4;
facing ="left"; //facing left
}
} else {
x-=4;
facing ="left"; //facing left
sprite_index = spr_playerwalk;
image_speed = .3;
image_xscale = -2;
}
} else {
sprite_index = spr_playerstand;
image_speed = .1

}

if (!place_free(x,y+1)) {

//jumping
if keyboard_check_pressed(ord('W')) {
vspeed = -10;
}
} else {
sprite_index = spr_playerjump;
}

if (!place_free(x,y+1)) {


}
}
and then back in the collision code:
Code:
if(playerRecoil!=-1){
    playerRecoil-=1;
    if (facing == "right"){ //facing right
         x-=4; //increase/decrease if the character doesn't recoil far enough
         } else if (facing == "left"){ //facing left
         x+=4;//increase/decrease if the character doesn't recoil far enough
        }
   speed= recoilSpeed;
   playerStop=1;
}

if(playerRecoil=-1 && playerStop=1){
    speed=0;
    playerStop=-1;
    }
Keep the step code i provided as it is.

That should work. Let me know if it does or not.

And honestly, if you''re this deep into game maker, it might pay you to go take a few lessons. Look up 'Tom Francis's Make a game in game maker with no experience' for a good starter course in gml.
 
Last edited by a moderator:
T

TDSrock

Guest
We could still use Therefor show us how you are choosing where you are shooting.
(this also opens up a couple fun map design mechanics where you use the knock-back to get to places you couldn't without.)
 

pixeltroid

Member
@ Shariku Onikage

I just added your code in. The player moves fine but now I am getting an error message when I bump into the enemy that was supposed to make me recoil

FATAL ERROR in
action number 2
of Step Eventobj_enemy4
for object obj_playerCOPY:

Variable obj_playerCOPY.playerRecoil(100011, -2147483648) not set before reading it.
at gml_Object_obj_playerCOPY_CollisionEvent_8_2 (line 4) - if(playerRecoil!=-1){
I added the collision event in the players object.
 
T

TDSrock

Guest
Make sure to define the value playerRecoil in the create event in the default state ;)
(presumably 0 )
 
S

Shariku Onikage

Guest
@ Shariku Onikage

I just added your code in. The player moves fine but now I am getting an error message when I bump into the enemy that was supposed to make me recoil



I added the collision event in the players object.
Sorry. Mixing events up.

collision code:
Code:
playerRecoil=20;
step code:
Code:
if(playerRecoil!=-1){
    playerRecoil-=1;
    if (facing == "right"){ //facing right
         x-=4; //increase/decrease if the character doesn't recoil far enough
         } else if (facing == "left"){ //facing left
         x+=4;//increase/decrease if the character doesn't recoil far enough
        }
   speed= recoilSpeed;
   playerStop=1;
}

if(playerRecoil=-1 && playerStop=1){
    speed=0;
    playerStop=-1;
    }
And make sure you've kept the three variables from earlier in the create event (playerRecoil, playerStop and recoilSpeed).
 

pixeltroid

Member
Sorry. Mixing events up.

collision code:
Code:
playerRecoil=20;
step code:
Code:
if(playerRecoil!=-1){
    playerRecoil-=1;
    if (facing == "right"){ //facing right
         x-=4; //increase/decrease if the character doesn't recoil far enough
         } else if (facing == "left"){ //facing left
         x+=4;//increase/decrease if the character doesn't recoil far enough
        }
   speed= recoilSpeed;
   playerStop=1;
}

if(playerRecoil=-1 && playerStop=1){
    speed=0;
    playerStop=-1;
    }
And make sure you've kept the three variables from earlier in the create event (playerRecoil, playerStop and recoilSpeed).
hi. Thanks.
But Once again, the player recoils to just one direction, no matter where he is facing. :-//
 
T

TDSrock

Guest
We could still use Therefor show us how you are choosing where you are shooting.
(this also opens up a couple fun map design mechanics where you use the knock-back to get to places you couldn't without.)
 
T

TDSrock

Guest
In your code you should have something along the lines of:
Code:
if(shoot){
inst = create_instance(x,y,bullet);
inst.direction = value;
}
 

pixeltroid

Member
In your code you should have something along the lines of:
Code:
if(shoot){
inst = create_instance(x,y,bullet);
inst.direction = value;
}
Actually my charecter as well as the enemies shoot as I want them to.
What I'm trying to achieve is have my charecter recoil back a bit when he takes a hit from an enemy...kinda like how Samus does when she takes a hit,

I implemented Shariku Onikages code and its working well - except that the player is just recoiling to the right side even when he is facing left,
 
S

Shariku Onikage

Guest
Could you throw us the gmx file (File > Export Project)? Most likely a small tweak is needed, but i'll need to see it to find it.
 
T

TDSrock

Guest
Well then, don I look silly for not understanding that point all this time!

Here's what I would do.

On collision between the player and the enemy projectile I would figure out the angle that their centre's have.
Luckily that isen too hard as GML already has this function.

https://docs.yoyogames.com/source/d...e/maths/vector functions/point_direction.html

So on a hit before deleting anything calculate the angle via point_direction, then use that angle as your knock-back direction and you should be golden.
 
S

Shariku Onikage

Guest
Yeah there's no attachment service on the forum. It'll have to be a a cloud storage system.
 

pixeltroid

Member
https://drive.google.com/open?id=0Bz3M7gWNpxJCbktaQnYwbkdIX0U

Here. I uploaded it on google drive.

Please see what you can do with it. Notice that the enemy's fireball knocks the player to the right, when he should be knocked to the left. However, when the player is on the right side of the enemy, he recoils the way he's supposed to.

Also, if its not too much of a bother, can you also animate the enemy when he attacks? I've provided the "enemyshoot" sprite in the file. :) As of now, the enemy just walks as he shoots, which looks kind of silly.
 

pixeltroid

Member
Well then, don I look silly for not understanding that point all this time!

Here's what I would do.

On collision between the player and the enemy projectile I would figure out the angle that their centre's have.
Luckily that isen too hard as GML already has this function.

https://docs.yoyogames.com/source/dadiospice/002_reference/maths/vector functions/point_direction.html

So on a hit before deleting anything calculate the angle via point_direction, then use that angle as your knock-back direction and you should be golden.
I am really not a programmer and I am not sure how to do anything involving codes. :/
Whatever I've done so far I've done by copying codes I've seen other people use. My aim is to finalize the game code (player movement, AI etc) and have a decent "engine" going.

Then I can focus on art and animations, which I am more comfortable with.
 
T

TDSrock

Guest
My advice is. Get comfortable.Start simple and build up to more complex things over time. I get that it may seem daunting at first, but once you get the hang of it it becomes tons easier to A work with us and B figure mistakes out on your own.
 

pixeltroid

Member
https://drive.google.com/open?id=0Bw3ojYXOvOr3am12bFh3RzRjOWM

And that should do it.

Kind of rewrote a big bit of it. Look for hspeed in the player's step event if you want to modify how far they get pushed back.
I really really appreciate your help! Just one more thing, how do I change the sprites to a hit animation? Both for the player when he is hit and for the enemy when he is hit? I try using sprite_index = sprite_name but the charecter permanently freezes into the new sprite!
 
S

Shariku Onikage

Guest
No worries. Glad it works.

Most likely you need to tell it to go back to using the standing sprite. Try this in the step event:

Code:
  //RECOIL
  if(playerRecoil!=-1){
    playerRecoil-=1;
    if (directionOfBullet == "Right"){ //facing right
        hspeed-=4; //increase/decrease if the character doesn't recoil far enough
        sprite_index = spr_playerjump;                                    //what i presume you're using for the recoil effect
         } else if (directionOfBullet == "Left"){ //facing left
         hspeed+=4;//increase/decrease if the character doesn't recoil far enough
         sprite_index = spr_playerjump; 
        }
  // speed= recoilSpeed;
   playerStop=1;
}

if(playerRecoil=-1 && playerStop=1){
    hspeed=0;
    playerStop=-1;
    sprite_index = spr_playerstand;                                        //makes the player stand normally again
    }
 

pixeltroid

Member
No worries. Glad it works.

Most likely you need to tell it to go back to using the standing sprite. Try this in the step event:

Code:
  //RECOIL
  if(playerRecoil!=-1){
    playerRecoil-=1;
    if (directionOfBullet == "Right"){ //facing right
        hspeed-=4; //increase/decrease if the character doesn't recoil far enough
        sprite_index = spr_playerjump;                                    //what i presume you're using for the recoil effect
         } else if (directionOfBullet == "Left"){ //facing left
         hspeed+=4;//increase/decrease if the character doesn't recoil far enough
         sprite_index = spr_playerjump;
        }
  // speed= recoilSpeed;
   playerStop=1;
}

if(playerRecoil=-1 && playerStop=1){
    hspeed=0;
    playerStop=-1;
    sprite_index = spr_playerstand;                                        //makes the player stand normally again
    }
Thanks again! But I solved the sprite problem earlier today. I used an alarm to change the sprite back!
 
Top